기본 이니셜라이저와 멤버와이즈 이니셜라이저
저번 게시글에서는 사용자 정의 이니셜라이저에 대해 알아봤는데, 이번에는 기본 이니셜라이저와 멤버와이즈 이니셜라이저에대해 알아볼까 한다.
만약 사용자 정의 이니셜라이저를 정의해주지 않으면 클래스나 구조체는 모든 프로퍼티에 기본값이 지정되어있다는 전제로 기본 이니셜라이저를 사용하게 된다. 기본 이니셜라이저는 프로퍼티 기본값으로 초기화해서 인스턴스를 생성한다.
- 저장 프로퍼티에 기본값이 있고, 사용자 정의 이니셜라이저가 지정되어 있지 않으면 ➜ 기본 이니셜라이저 제공
저장 프로피티를 선언할 때 기본값을 정해주지 않았다면 이니셜라이저에서 초깃값을 설정해야 하는데, 이 때문에 매번 이니셜라이저를 추기/변경 하는 일은 귀찮기 때문에 구조체는 사용자 정의 이니셜라이저를 구현하지 않았다면 프로퍼티의 이름으로 매개변수를 갖는 이니셜라이저인 멤버와이즈 이니셜라이저를 기본으로 제공한다.
하지만, 클래스 멤버와이즈 이니셜라이저는 지원하지 않으니 주의!
모든 Swift 구조체는 기본적으로 합성된 Memberwise initializer
를 얻는다.
struct Employee {
var name: String = "anonymous"
var height: Int = 200
}
let Seogun: Employee = Employee(name: "서근", height: 100)
let Mijin: Employee = Employee(name: "미진", height: 150)
//구조체의 저장 프로퍼티에 기본값이 있는 경우
//필요한 매개변수만 사용하여 초기화할 수도 있다.
let Someone: Employee = Employee()
let Someone2: Employee = Employee(height: 120)
print(Someone2) //Employee(name: "anonymous", height: 120)
let Someone3: Employee = Employee(name: "익명")
print(Someone3) //Employee(name: "익명", height: 200)
이 이니셜라이저를 사용하면 구조체를 쉽게 사용할 수 있지만, Swift는 이것을 만드는 두 가지 추가 작업을 수행한다.
첫 번째, 프로퍼티에 기본값이 있는 경우 이니셜라이저에 기본 매개변수 값으로 통합된다.
struct User {
var name: String
var yearsActive = 0
}
그런 다음 두 가지 방법 중에 하나로 만들 수 있다.
struct Employee {
var name: String
var yearsActive = 0
}
let Seogun = Employee(name: "서근")
let Mijin = Employee(name: "미진", yearsActive: 19)
print("제 이름은 \(Seogun.name)입니다.")
print("\(Mijin.name)은 \(Mijin.yearsActive)살 입니다.")
이렇게 하면 필요한 부분만 채울 수 있기 때문에 더 쉽게 만들 수 있다.
두 번째, custom initializer
를 생성하는 경우 Memberwise initializer
를 제거하는 것이다.
예를 들어 익명의 직원을 만든 custom initializer
의 경우 다음과 같다.
struct Employee {
var name: String
var yearsActive: Int?
init(name: String) {
self.name = "익명"
print("익명의 직원을 생성합니다..")
}
}
let Seogun = Employee(name: "서근")
init
을 작성하여 구조체의 기본값을 정해줬는데, 이래 코드를 보면 오류가 났다!
let Seogun = Employee(name: "서근")
let Mijin = Employee(name: "미진", yearsActive: 19)
"더 이상 Memberwise 이니셜라이저
에 의존할 수 없습니다. 이 작업을 수행할 수 없습니다."
위에서 사용자 정의 이니셜라이저를 만들었고, Swift가 멤버와이즈 이니셜라이저를 그대로 두면 이니셜라이저에 작성한 중요한 작업이 누락될 수도 있다.
따라서 Struct
에 대한 custom initializer
를 추가하는 즉시 기본 custom initializer
가 사라진다.
이 상태를 유지하려면 다음과 같이 custom initializer
를 extentsion
으로 이동해야 한다.
struct Employee {
var name: String
var yearsActive = 0
}
extension Employee {
init() {
self.name = "익명"
print("익명의 직원을 생성합니다..")
}
}
let Seogun = Employee(name: "서근")
let Mijin = Employee(name: "미진", yearsActive: 19)
let anonymous = Employee()
print("제 이름은 \(Seogun.name)입니다.")
print("\(Mijin.name)은 \(Mijin.yearsActive)살 입니다.")
/*
익명의 직원을 생성합니다..
제 이름은 서근입니다.
미진은 19살 입니다.
*/
struct Employee {
var name: String
var height: Int?
}
extension Employee {
init() {
self.name = "익명"
print("익명의 누군가를 생성합니다.")
}
}
var Seogun: Employee = Employee(name: "서근", height: 100)
print(Seogun)
//Employee(name: "서근", height: Optional(100))
var Mijin: Employee = Employee(name: "미진")
Mijin.height = 200
//Employee(name: "미진", height: Optional(150))
print(Mijin)
let Someone3: Employee = Employee()
print(Someone3)
//익명의 누군가를 생성합니다.
//Employee(name: "익명", height: nil)
예시
struct Country {
var name: String
var usesImperialMeasurements: Bool
init(countryName: String) {
name = countryName
let imperialCountries = ["서울", "도쿄", "뉴욕"]
if imperialCountries.contains(name) {
usesImperialMeasurements = true
print("정답")
} else {
usesImperialMeasurements = false
print("실패")
}
}
}
Country.init(countryName: "서울")
//정답
struct Message {
var from: String
var to: String
var content: String
init() {
from = "서근"
to = "미진"
content = "Yo"
}
}
let message = Message()
struct Cabinet {
var height: Double
var width: Double
var area: Double
init (itemHeight: Double, itemWidth: Double) {
height = itemHeight
width = itemWidth
area = height * width
}
}
let drawers = Cabinet(itemHeight: 1.4, itemWidth: 1.0)
print("height(\(drawers.height)) 곱하기 width(\(drawers.width))는 \(drawers.area) 입니다.")
struct PowerTool {
var name: String
var price: Int
}
let drill = PowerTool(name: "전동드릴", price: 32_000)
print("\(drill.name)의 가격은 \(drill.price)원 입니다.")
//전동드릴의 가격은 32000원 입니다.
클래스에서 멤버와이즈 이니셜라이저
클래스에서는 멤버와이즈 이니셜라이저를 지원하지 않는다. 멤버와이즈 이니셜라이저는 오직 구조체에서 만의 특권이다.
읽어주셔서 감사합니다🤟
'SWIFT > Grammar' 카테고리의 다른 글
Swift : 기초문법 [인스턴스 #4 클로저 사용 프로퍼티 기본값, 디이니셜라이저] (2) | 2022.01.15 |
---|---|
Swift : 기초문법 [인스턴스 #3 초기화 위임, 실패가능한 이니셜라이저] (0) | 2022.01.15 |
Swift : 기초문법 [인스턴스 #1 이니셜라이저, 매개변수) (0) | 2022.01.15 |
Swift : 기초문법 [메서드 #3 타입 메서드] (0) | 2022.01.14 |
Swift : 기초문법 [메서드 #2 mutating] (0) | 2022.01.14 |