오늘은 옵셔널 체이닝에 대해 알아보았다.
옵셔널 체이닝은 옵셔널 요소 내부의 프로퍼티로, 또다시 옵셔널이 연속적으로 연결되는 경우 유용하게 사용할 수 있다.
연속적 사용
import Swift
class Person {
var name: String
var job: String?
var home: Apartment?
init(name: String) {
self.name = name
}
}
class Apartment {
var buildingNumber: String
var roomNumber: String
var `guard`: Person?
var owner: Person?
init(dong: String, ho: String) {
buildingNumber = dong
roomNumber = ho
}
}
let itlearning: Person? = Person(name: "ITlearning")
let apart: Apartment? = Apartment(dong: "103", ho: "102")
let superman: Person? = Person(name: "superman")
// 옵셔널 체이닝 실행 후 결과값이 nil일 수 있으므로
// 결과 타입도 옵셔널이다
각 클래스들을 보면 계속 옵셔널로 이어져있는 구조이다. 이럴때 옵셔널 체이닝이 이용된다.
그리고 인스턴스로 적어놓은걸 보면 필수적으로 적용해 주어야할 프로퍼티들만 적용해주고, 나머지는 다 nil로 설정되어있으니, 불러올 인스턴스 또한 옵셔널 타입이어야 한다.
옵셔널 체이닝을 사용하지 않는다면?
// 옵셔널 체이닝을 사용하지 않는다면
func guardJob(owner: Person?) {
if let owner = owner {
if let home = owner.home {
if let `guard` = home.guard {
if let guardJob = `guard`.job {
print("우리집 경비원의 직업은 \(guardJob)입니다")
} else {
print("우리집 경비원은 직업이 없어요")
}
}
}
}
}
guardJob(owner: itlearning)
위 코드는 아까 만들어놓은 클래스를 기반으로 우리집 경비원의 직업을 출력하는 코드이다.
그런데 옵셔널 체이닝을 이용하지 않고 그냥 구현하려고 하면, 이렇게 if let 구문이 여러겹 쌓이면서 코드가 보기가 싫어진다.
옵셔널 체이닝을 사용하면?
// 옵셔널 체이닝을 사용하면
func guardJobWithOptionalChaining(owner: Person?) {
if let guardJob = owner?.home?.guard?.job {
print("우리집 경비원의 직업은 \(guardJob)입니다")
} else {
print("우리집 경비원은 직업이 없어요")
}
}
guardJobWithOptionalChaining(owner: itlearning)
옵셔널 체이닝을 사용하면, 한줄로 if let 구문을 정의할 수 있다. 물음표를 이용해 계속 하나하나 이어주고 난 뒤에 적합하면 출력되고 아니면 else 구문이 출력된다. 이 코드의 결과값은 else 출력문이다. 현재 직업이 nil로 되어있기 때문이다.
이외의 옵셔널 체이닝
itlearning?.home?.guard?.job // nil
itlearning?.home = apart
itlearning?.home // Optional(Apartment)
itlearning?.home?.guard // nil
itlearning?.home?.guard = superman
itlearning?.home?.guard // Optional(Person)
itlearning?.home?.guard?.name // superman
itlearning?.home?.guard?.job // nil
itlearning?.home?.guard?.job = "경비원"
여러 옵셔널 체이닝을 보자.
첫줄은 경비원의 직업이다. 설정을 안해줬으니 nil이다.
다음, 집을 정의해줬다.
그리고 집을 불러오면 옵셔널로 집이 정의가 되었으니 Apartment가 나온다.
그렇지만 집이 정의 됐을 뿐 그 집 경비원의 이름이 정의가 되어있지 않다. 그래서 superman 인스턴스로 이름을 정의해줬다.
그러자 이름은 나온다. 그러나 직업은 정의가 되어있지 않아 nil이다. 마지막으로 직업을 정의해 줬다.
이렇게 보면, 다 정의, 입력이 되어있어야 nil이 안뜬다 라는 것을 알 수있다. 중요하다.
nil 병합 연산자
var guardJob: String
guardJob = itlearning?.home?.guard?.job ?? "슈펴맨"
print(guardJob) // 경비원
itlearning?.home?.guard?.job = nil
guardJob = itlearning?.home?.guard?.job ?? "슈퍼맨"
print(guardJob) // 슈퍼맨
nil 병합 연산자란, 옵셔널 체이닝으로 땡겨온 값이 nil일 경우 ?? 키워드 뒤에 있는 값으로 nil 값을 대체 하는 연산자이다.
코드를 보면, 처음 코드에서는 값이 변경이 되어있지 않았다. 이유는 방금 위에서 "경비원"으로 값을 설정해놨었기 때문이다.
그래서 값을 nil로 다시 설정해주고 난뒤에 다시 입력을 하면 "슈퍼맨"으로 값이 변경되었다.
'etc > Swift' 카테고리의 다른 글
assert와 guard (0) | 2021.05.28 |
---|---|
타입 캐스팅(Type Casting) (0) | 2021.05.28 |
인스턴스 생성과 소멸 (0) | 2021.05.28 |
상속 (0) | 2021.05.28 |
프로퍼티 감시자 (0) | 2021.05.27 |
댓글