Struct
struct Person {
var name: String
func sayHello() {
print("Hello! My name is \(name)!")
}
}
let person = Person(name: "Joohyun")
person.sayHello()
Intializers
- 가장 일반적인 형태는 파라미터를 가지고 있지 않은
init()
이다.
var string = String.init()
var integer = Int.init()
var bool = Bool.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
}
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)
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)
let temp3 = Temperature()
Instance Methods, Properties
- 해당 type의 instance를 통해 호출할 수 있는 method이다.
- structure의 properties에 접근하거나 수정할 수 있다.
struct Size {
var width: Double
var height: Double
func area() -> Double {
width * height
}
}
let size = Size(width: 10.0, height: 5.5)
let area = size.area()
1. Mutating Methods
- instance method를 통해 structure의 property 값을 수정하려면
mutating
을 method앞에 붙여주어야 한다.
struct Odometer {
var count: Int = 0
mutating func increment() {
count += 1
}
mutating func increment(by amount: Int) {
count += amount
}
mutating func reset() {
count = 0
}
}
var odometer = Odometer()
odometer.increment()
odometer.increment(by: 15)
odometer.reset()
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)
temp.celsius = 18.5
- 이 때, custom initializer 대신 computed property를 이용하면 섭씨온도와 화씨온도 중 하나가 바뀌더라도 나머지 하나의 온도가 자동으로 계산되어 변경되도록 설정할 수 있다.
struct Temperature {
var celsius: Double
var fahrenheit: Double {
celsius * 1.8 + 32
}
}
var temp = Temperature(celsius: 0.0)
temp.celsius = 18.5
print(temp.fahrenheit)
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()
stepCounter.totalSteps = 40
40이 totalStep에 할당된다
40이 더해진다
Type Properties, Methods
- type과 관련되어 있는 properties 또는 methods
- type을 통해 접근한다.
static
키워드를 사용한다.
struct Temparature {
static var boilingPoint = 100
}
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)
print(anotherSize.width)
Self
- 현재 type의 instance를 뜻한다.
- instance에 존재하는 instance method 또는 computed property에서 사용된다.
- 생략이 가능하지만, 동일한 property 또는 method의 이름이 존재하는 경우에는
self
키워드를 꼭 붙여주어야 한다.
struct Temperature {
var celsius: Double
init(celsius: Double) {
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)
var car2 = car1
car1.make = "Ford"
- 해당 instance의 property가 변경되지 않길 원한다면 instance 값을 constant로 설정하자.
let car = Car(make: "Honda", year: 2010, color: .blue, topSpeed: 120)
car.color = .red