옵셔널 체이닝은 옵셔널에 속해 있는 nil일지도 모르는 프로퍼티, 메서드, 서브스크립션 등을 가져오거나 호출할 때 사용할 수 있는 일련의 과정이다. 옵셔널 값을 연결된 것들을 호출하려면 상당히 긴 구문이 필요한데, 옵셔널 체이닝을 사용하면 간단하게 표현이 가능하다.
class Room {
var numver: Int
init(number: Int) {
self.number = number
}
}
class Buliding {
var name: String
var room: Room? //class Room 타입을 사용
init(name: String) {
self.name = name
}
}
struct Address {
var city: String
var street: String
var building: Building? //class building타입을 사용
}
class Person {
var name: String
var address: Address? //class Address타입을 사용
init(name: String) {
self.name = name
}
}
let KIM: Person = Person(name: "KIM") //KIM이라는 사람 인스턴스 생성.
//KIM은 현재 Address, Building, Room 타입의 정보가 없음
let KIMoptionalchaining: Int? = KIM.address?.building?.room?.number? //nil (순서대로 하나라도 입력되지 않았다면 nil로 추출됨) (암시적 추출로 하면 오류남)
옵셔널 체이닝을 사용하지 않는다면 if문안에 if눈 이런식으로 복잡한 코드가 된다.
상위 프로퍼티에 값이 할당되지 않는다면 하위 프로퍼티(여기서는 number)는 존재조차 할 수 없기에 number에 값을 부여하더라도 할당되지 않는다.
빠른 종료의 핵심 키워드는 guard이다. 이 구문은 Bool타입의 값으로 동작한다. 그렇기에 guard구문은 뒤에 else가 항상 따라와야한다.
for i in 0...3 {
if i == 2 { //if문 사용
print(i)
} else {
continue
}
}
vs
for i in 0...3 {
guard i == 2 else { //guard문 사용
continue
}
print(i)
}
위 두 구문은 같은 역할을 한다.
else안에는 코드 블록을 종료하는 지시어가 있어야한다. 특정 조건에 부합하지 않는다고 판단하면 재빠르게 코드 블록의 실행을 종료할 수 있다.
func ABC(age: Int?) {
guard let A = age, //옵셔널 바인딩 활용
A < 130,
A >= 0 else {
print("나이가 잘못되었습니다.")
return //함수를 끝낸다는 의미 블록 종료 지시어
}
print("나이는 \(A)세입니다.") // 위에 바인딩 구문에서 사용되었던 A를 사용 가능하다. (if문은 불가)
}