2.4 Structures
Struct
struct Person {
// properties
var name: String
// methods
func sayHello() {
print("Hello! My name is \(name)!")
}
}
// Instances
let person = Person(name: "Joohyun")
person.sayHello() // "Hello! My name is Joohyun!"
Intializers
- 가장 일반적인 형태는 파라미터를 가지고 있지 않은
init()
이다.
var string = String.init() // ""
var integer = Int.init() // 0
var bool = Bool.init() // false
init()
은 생략이 가능하다.
var string = String() // ""
1. Memberwise Initializers
- structure를 정의할 때, custom initializer를 생성하지 않으면 Swift에서 자동으로 memberwise initializers를 생성해준다.
struct Car {
var make: String
var model: String
var year: Int
var topSpeed: Int
}
// memberwise initializer
let car = Car(make: "Honda", model: "Civic", year: 2010, topSpeed: 120)
- default value가 설정된 properties가 있다면 여러개의 memberwise initializers가 생성된다.
struct BankAccount {
var accountNumber: Int
var balance: Double = 0
}
var account1 = BankAccount(accountNumber: 123)
var account2 = BankAccount(accountNumber: 456, balance: 1200)
Default Values
- structure를 정의할 때 default value를 설정하면 해당 값 없이
init
을 호출할 때 default value로 해당 값이 설정된다.
- structure에 있는 모든 properties들이 default value를 갖고있다면,
init()
을 사용할 수 있다.
struct Odometer {
var count: Int = 0
}
let odometer = Odometer()
print(odometer.count) // 0
2. Custom Initializers
- 직접 custom initializer를 정의할 수 있다.
- 단, custom initializer를 정의하면 Swift에서 자동으로 생성해주는 memberwise initializer를 사용할 수 없다.
struct Temperature {
var celsius: Double
init(celsius: Double) {
self.celsius = celsius
}
init(fahrenheit: Double) {
celsius = (fahrenheit - 32) /1.8
}
init() {
celsius = 0
}
}
let temp1 = Temperature(celsius: 18.5)
let temp2 = Temperature(fahrenheit: 212.0) // celsius : 100.0
let temp3 = Temperature() // celsius : 0
Instance Methods, Properties
- 해당 type의 instance를 통해 호출할 수 있는 method이다.
- structure의 properties에 접근하거나 수정할 수 있다.
struct Size {
var width: Double
var height: Double
// Instance Method
func area() -> Double {
width * height
}
}
let size = Size(width: 10.0, height: 5.5)
let area = size.area() // 55.0
1. Mutating Methods
- instance method를 통해 structure의 property 값을 수정하려면
mutating
을 method앞에 붙여주어야 한다.
struct Odometer {
var count: Int = 0
// mutating methods
mutating func increment() {
count += 1
}
mutating func increment(by amount: Int) {
count += amount
}
mutating func reset() {
count = 0
}
}
var odometer = Odometer() // count : 0
odometer.increment() // count : 1
odometer.increment(by: 15) // count : 16
odometer.reset() // count : 0
2. Computed Properties
- 해당 property에 접근될 때 마다, computed property 내부 로직이 실행되어 값이 수정된다.
- 섭씨와 화씨온도를 property로 갖고 custom initializer를 포함한 Temperature structure를 가정해보자.
struct Temperature {
var celsius: Double
var fahrenheit: Double
init(celsius: Double) {
self.celsius = celsius
fahrenheit = celsius * 1.8 + 32
}
init(fahrenheit: Double) {
self.fahrenheit = fahrenheit
celsius = (fahrenheit - 32) / 1.8
}
}
var temp = Temperature(fahrenheit: 212.0) // celsius: 100, fahrenheit: 212.0
// celsius property를 변경했지만 fahrenheit property가 변경되지 않아 섭씨온도와 화씨온도가 일치하지 않는다.
temp.celsius = 18.5 // celsius: 18.5, fahrenheit: 212.0
- 이 때, custom initializer 대신 computed property를 이용하면 섭씨온도와 화씨온도 중 하나가 바뀌더라도 나머지 하나의 온도가 자동으로 계산되어 변경되도록 설정할 수 있다.
struct Temperature {
var celsius: Double
var fahrenheit: Double {
celsius * 1.8 + 32
}
}
var temp = Temperature(celsius: 0.0) // celsius: 0.0, fahrenheit: 32.0
temp.celsius = 18.5
// 이 때, computed property 내부 로직 실행하여 값 변경됨
print(temp.fahrenheit) // 65.3
3. Property Observers
- 해당 property에 값이 할당될 떄마다 property observers가 호출된다.
willSet
- 해당 property에 값이 할당되기 직전에 호출된다.
newValue
: 새롭게 할당되는 값에 접근
didSet
- 해당 property에 값이 할당된 직후에 호출된다.
oldValue
: 할당되기 전의 값에 접근
struct StepCounter {
var totalSteps: Int = 0 {
willSet {
print("\(newValue)이 totalSteps에 할당된다")
}
didSet {
if totalSteps > oldValue {
print("\(totalSteps - oldValue)이 더해진다")
}
}
}
}
var stepCounter = StepCounter() // totalStep : 0
stepCounter.totalSteps = 40
// console
40이 totalStep에 할당된다
40이 더해진다
Type Properties, Methods
- type과 관련되어 있는 properties 또는 methods
- type을 통해 접근한다.
static
키워드를 사용한다.
struct Temparature {
// type property
// temperature의 모든 instance들의 끓는 온도는 동일하다.
static var boilingPoint = 100
}
// Double structure의 type method
// 2개의 Double 타입의 parameter 중에 더 작은 값을 반환
let smallerNumber = Double.minimum(100.0, -1000.0)
Instance Properties, Methods VS Type Properties, Methods
- Instance Properties, Methods
- type의 instance를 통해 접근 가능
- 각각 instance마다 고유할 경우
- Type Properties, Methods
- type을 통해 접근 가능
- type과 관련되어 있어 instance들 모두 같은 값이나 행동을 가짐
Copying
- structure를 variable에 할당하거나 함수의 parameter로 삽입할 때, 해당 structure의 값이 복제되어 할당된다.
var size = Size(width: 250, height: 1000)
var anotherSize = size
size.width = 500
print(size.width) // 500
// anotherSize에 할당된 값은 size의 복제값이기 때문에 값이 바뀌어도 서로에게 영향을 주지 않는다.
print(anotherSize.width) // 250
Self
- 현재 type의 instance를 뜻한다.
- instance에 존재하는 instance method 또는 computed property에서 사용된다.
- 생략이 가능하지만, 동일한 property 또는 method의 이름이 존재하는 경우에는
self
키워드를 꼭 붙여주어야 한다.
struct Temperature {
var celsius: Double
init(celsius: Double) {
// instance의 property 이름과 initializer의 parameter 이름이 동일하기 때문에 self 키워드를 통해 둘을 구별해주어야 한다.
self.celsius = celsius
}
}
property를 variable로 선언하는 이유
- 일반적으로 structure의 property는 varialbe로 선언한다.
- 변경되지 않는 property도 variable로 선언하는 이유는 copy를 통해 새로운 데이터의 값을 편리하게 생성하기 위해서이다.
struct Car {
var make: String
var year: Int
var color: Color
var topSpeed: Int
}
var car1 = Car(make: "Honda", year: 2010, color: .blue, topSpeed: 120)
// make property가 constant였다면 memberwise initializer를 통해 car2를 생성했어야 할것이다.
var car2 = car1
car1.make = "Ford"
- 해당 instance의 property가 변경되지 않길 원한다면 instance 값을 constant로 설정하자.
let car = Car(make: "Honda", year: 2010, color: .blue, topSpeed: 120)
car.color = .red // Error
Author And Source
이 문제에 관하여(2.4 Structures), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@j00hyun/2.4-Structures
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
struct Person {
// properties
var name: String
// methods
func sayHello() {
print("Hello! My name is \(name)!")
}
}
// Instances
let person = Person(name: "Joohyun")
person.sayHello() // "Hello! My name is Joohyun!"
init()
이다.var string = String.init() // ""
var integer = Int.init() // 0
var bool = Bool.init() // false
init()
은 생략이 가능하다.var string = String() // ""
struct Car {
var make: String
var model: String
var year: Int
var topSpeed: Int
}
// memberwise initializer
let car = Car(make: "Honda", model: "Civic", year: 2010, topSpeed: 120)
struct BankAccount {
var accountNumber: Int
var balance: Double = 0
}
var account1 = BankAccount(accountNumber: 123)
var account2 = BankAccount(accountNumber: 456, balance: 1200)
Default Values
- structure를 정의할 때 default value를 설정하면 해당 값 없이
init
을 호출할 때 default value로 해당 값이 설정된다. - structure에 있는 모든 properties들이 default value를 갖고있다면,
init()
을 사용할 수 있다.
struct Odometer {
var count: Int = 0
}
let odometer = Odometer()
print(odometer.count) // 0
struct Temperature {
var celsius: Double
init(celsius: Double) {
self.celsius = celsius
}
init(fahrenheit: Double) {
celsius = (fahrenheit - 32) /1.8
}
init() {
celsius = 0
}
}
let temp1 = Temperature(celsius: 18.5)
let temp2 = Temperature(fahrenheit: 212.0) // celsius : 100.0
let temp3 = Temperature() // celsius : 0
struct Size {
var width: Double
var height: Double
// Instance Method
func area() -> Double {
width * height
}
}
let size = Size(width: 10.0, height: 5.5)
let area = size.area() // 55.0
mutating
을 method앞에 붙여주어야 한다.struct Odometer {
var count: Int = 0
// mutating methods
mutating func increment() {
count += 1
}
mutating func increment(by amount: Int) {
count += amount
}
mutating func reset() {
count = 0
}
}
var odometer = Odometer() // count : 0
odometer.increment() // count : 1
odometer.increment(by: 15) // count : 16
odometer.reset() // count : 0
struct Temperature {
var celsius: Double
var fahrenheit: Double
init(celsius: Double) {
self.celsius = celsius
fahrenheit = celsius * 1.8 + 32
}
init(fahrenheit: Double) {
self.fahrenheit = fahrenheit
celsius = (fahrenheit - 32) / 1.8
}
}
var temp = Temperature(fahrenheit: 212.0) // celsius: 100, fahrenheit: 212.0
// celsius property를 변경했지만 fahrenheit property가 변경되지 않아 섭씨온도와 화씨온도가 일치하지 않는다.
temp.celsius = 18.5 // celsius: 18.5, fahrenheit: 212.0
struct Temperature {
var celsius: Double
var fahrenheit: Double {
celsius * 1.8 + 32
}
}
var temp = Temperature(celsius: 0.0) // celsius: 0.0, fahrenheit: 32.0
temp.celsius = 18.5
// 이 때, computed property 내부 로직 실행하여 값 변경됨
print(temp.fahrenheit) // 65.3
newValue
: 새롭게 할당되는 값에 접근oldValue
: 할당되기 전의 값에 접근struct StepCounter {
var totalSteps: Int = 0 {
willSet {
print("\(newValue)이 totalSteps에 할당된다")
}
didSet {
if totalSteps > oldValue {
print("\(totalSteps - oldValue)이 더해진다")
}
}
}
}
var stepCounter = StepCounter() // totalStep : 0
stepCounter.totalSteps = 40
// console
40이 totalStep에 할당된다
40이 더해진다
static
키워드를 사용한다.struct Temparature {
// type property
// temperature의 모든 instance들의 끓는 온도는 동일하다.
static var boilingPoint = 100
}
// Double structure의 type method
// 2개의 Double 타입의 parameter 중에 더 작은 값을 반환
let smallerNumber = Double.minimum(100.0, -1000.0)
Instance Properties, Methods VS Type Properties, Methods
- Instance Properties, Methods
- type의 instance를 통해 접근 가능
- 각각 instance마다 고유할 경우
- Type Properties, Methods
- type을 통해 접근 가능
- type과 관련되어 있어 instance들 모두 같은 값이나 행동을 가짐
var size = Size(width: 250, height: 1000)
var anotherSize = size
size.width = 500
print(size.width) // 500
// anotherSize에 할당된 값은 size의 복제값이기 때문에 값이 바뀌어도 서로에게 영향을 주지 않는다.
print(anotherSize.width) // 250
self
키워드를 꼭 붙여주어야 한다.struct Temperature {
var celsius: Double
init(celsius: Double) {
// instance의 property 이름과 initializer의 parameter 이름이 동일하기 때문에 self 키워드를 통해 둘을 구별해주어야 한다.
self.celsius = celsius
}
}
struct Car {
var make: String
var year: Int
var color: Color
var topSpeed: Int
}
var car1 = Car(make: "Honda", year: 2010, color: .blue, topSpeed: 120)
// make property가 constant였다면 memberwise initializer를 통해 car2를 생성했어야 할것이다.
var car2 = car1
car1.make = "Ford"
let car = Car(make: "Honda", year: 2010, color: .blue, topSpeed: 120)
car.color = .red // Error
Author And Source
이 문제에 관하여(2.4 Structures), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@j00hyun/2.4-Structures저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)