Swift optionals - 2
22 Feb 2017이 글을 읽기 전에 optional에 대한 기본 개념을 모르시는 분들은 아래 글을 먼저 읽어 주세요. 여기서는 기본적인 optional 개념을 안다는 전제하에 Optional Chaining에 대해서만 서술합니다.
Optional Chaining 개념
Apple에서 설명하고 있는 Optional Chaining의 정의는 다음과 같습니다.
일단은 감만 잡고, 아래에서 예제를 살펴 본 뒤 다시 한 번 의미를 생각해보시면 무슨 의미인지 이해하실 수 있습니다.
다음과 같은 2개의 클래스 Person
과 Residence
를 정의하겠습니다. 그리고 john
이라는 인스턴스를 생성하였습니다. 이 때 john.residence!.numberOfRooms
는 어떤 값을 가질까요? 표현이 다소 어색할 수 있습니다만, 이런 표현은 Swift에서 자주 쓰입니다.
john
은Person
class로 선언 되었으므로 residence 변수를 가지고, 해당 변수는Residence?
형입니다.Residence
class는numberOfRooms
property를 지니고 있으므로john
부터 시작하여numberOfRooms
까지의 쿼리 는 오류가 아닙니다.
하지만, 해당 코드의 결과는 에러입니다. 왜냐하면, residence
변수는 Residence?
형인데, 아직 값이 없기 때문입니다.
이처럼 !
를 활용하여 Optional 값을 받아오는 것을 Forced unwrapping이라고 합니다. Forced unwrapping은 쉽게 에러를 낼 수 있기 때문에 항상 값이 있다고 보장할 수 있는 경우에만 사용하는 것이 권장됩니다. 그런데 Optional Chaining은 이러한 상황에서 좀 더 안전하게(nil이 안 나오도록) 코드를 짤 수 있게 해줍니다.
위의 코드를 보시면 unwrap과 다르게 ?
(john.residence?.numberOfRooms
)를 사용하는 것을 볼 수 있습니다. 이 때, if let roomCount = john.residence?.numberOfRooms
은 해당 chain에(residence?
와 numberOfRooms
) 값이 있는지 없는지를 체크하고, 하나라도 없으면 false를 반환합니다.
정리하자면,
Optional Chaining Drill Down
Optional Chaining의 유용함은 복잡하게 얽혀 있는 여러 모델들의 값을 drill down하여 (있는 경우에만) 가져올 수 있게 해주고, 값이 없는 경우 값을 설정할 수 있도록 해주는 것에 있습니다. 값을 있는 경우에 가져오는 예제는 앞서 서술한 예시를 통해 나타납니다.
위의 예제를 조금 변형해서 numberOfRooms
의 값이 없는 경우 값을 설정할 수도 있습니다.
유의할 점은 Optional chaining에 속한 값은 항상 Optional 값만을 반환한다는 것입니다. 즉, john.residence!.numberOfRooms
은 Int
형을 반환하는 것이 아니라, Int?
형을 반환합니다. 또한, Optional 변수가 여러개 연결되어 있어도 그 값은 Optional이 중첩되는 것이 아니라, 그냥 Optional입니다. 예를 들어 john.residence?.place?
(place를 String? 타입으로 가정합니다.)는 Optional(Optional(값))
이 아니고, 항상(설령 Optional chain이 더 길어져도) Optional(값)
의 형태를 유지합니다.
좀 더 자세한 설명은 Apple Swift language 책을 참고해주세요.
더 볼만한 추가 자료
참고자료 : Apple Inc. The Swift Programming Language (Swift 3.0.1)