🔥 강제 언래핑의 대안, 옵셔널 체이닝
Swift에서 옵셔널 체이닝(Optional Chaining)을 강제 언래핑(Forced Unwrapping)의 대안으로 사용하는 방법에 대해 알아보도록 하겠습니다.
옵셔널 체이닝은 옵셔널 값에 속성, 메서드 또는 서브스크립트를 호출하고 싶을 때 옵셔널 값 뒤에 물음표(?
)를 붙여 지정합니다. 이는 옵셔널 값을 강제로 언래핑하기 위해 느낌표(!
)를 붙이는 것과 매우 유사하죠. 주요 차이점은 옵셔널 체이닝은 옵셔널이 nil
일 때 우아하게 실패하는 반면, 강제 언래핑은 옵셔널이 nil
일 때 런타임 오류를 발생시킨다는 것입니다.
옵셔널 체이닝은 nil
값에서 호출될 수 있다는 사실을 반영하기 위해, 옵셔널 체이닝 호출의 결과는 항상 옵셔널 값입니다. 이는 쿼리하는 속성, 메서드 또는 서브스크립트가 비옵셔널 값을 반환하더라도 마찬가지입니다. 이 옵셔널 반환 값을 사용하여 옵셔널 체이닝 호출이 성공했는지(반환된 옵셔널에 값이 포함됨) 또는 체인 내의 nil
값으로 인해 성공하지 못했는지(반환된 옵셔널 값이 nil
임) 확인할 수 있습니다.
구체적으로, 옵셔널 체이닝 호출의 결과는 예상되는 반환 값과 동일한 타입이지만 옵셔널로 래핑됩니다. 보통 Int
를 반환하는 속성은 옵셔널 체이닝을 통해 접근할 때 Int?
를 반환하게 됩니다.
다음 몇 가지 코드 예제를 통해 옵셔널 체이닝이 강제 언래핑과 어떻게 다른지, 그리고 성공 여부를 확인할 수 있는 방법에 대해 살펴보겠습니다.
먼저, Person
과 Residence
라는 두 개의 클래스를 정의해 보겠습니다:
class Person { var residence: Residence? } class Residence { var numberOfRooms = 1 }
swift
Residence
인스턴스에는 기본값이 1
인 numberOfRooms
라는 단일 Int
속성이 있습니다. Person
인스턴스에는 Residence?
타입의 옵셔널 residence
속성이 있습니다.
새로운 Person
인스턴스를 생성하면 옵셔널이기 때문에 residence
속성은 기본적으로 nil
로 초기화됩니다. 아래 코드에서 john
은 nil
인 residence
속성 값을 가지고 있습니다:
let john = Person()
swift
이 사람의 residence
에서 numberOfRooms
속성에 접근하려고 할 때, residence
뒤에 느낌표를 붙여 그 값을 강제로 언래핑하면 언래핑할 residence
값이 없기 때문에 런타임 오류가 발생합니다:
let roomCount = john.residence!.numberOfRooms // 이는 런타임 오류를 발생시킵니다.
swift
위의 코드는 john.residence
가 nil
이 아닌 값을 가질 때 성공하며, roomCount
를 적절한 수의 방이 포함된 Int
값으로 설정할 것입니다. 그러나 위에서 설명한 것처럼 residence
가 nil
일 때는 항상 런타임 오류를 발생시킵니다.
옵셔널 체이닝은 numberOfRooms
의 값에 접근하는 대체 방법을 제공합니다. 옵셔널 체이닝을 사용하려면 느낌표 대신 물음표를 사용하세요:
if let roomCount = john.residence?.numberOfRooms { print("John's residence has \(roomCount) room(s).") } else { print("Unable to retrieve the number of rooms.") } // "Unable to retrieve the number of rooms."를 출력합니다.
swift
이는 Swift에게 옵셔널 residence
속성에 "체이닝"하고, residence
가 존재하면 numberOfRooms
의 값을 가져오라고 지시합니다.
numberOfRooms
에 접근하려는 시도는 실패할 가능성이 있기 때문에, 옵셔널 체이닝 시도는 Int?
또는 "옵셔널 Int
" 타입의 값을 반환합니다. 위의 예시처럼 residence
가 nil
일 때, 이 옵셔널 Int
도 numberOfRooms
에 접근할 수 없었다는 사실을 반영하여 nil
이 됩니다. 옵셔널 Int
는 정수를 언래핑하고 비옵셔널 값을 roomCount
상수에 할당하기 위해 옵셔널 바인딩을 통해 접근됩니다.
numberOfRooms
가 비옵셔널 Int
임에도 불구하고 이것이 사실이라는 점에 주목하세요. 옵셔널 체인을 통해 쿼리된다는 사실은 numberOfRooms
에 대한 호출이 Int
대신 항상 Int?
를 반환한다는 것을 의미합니다.
john.residence
에 Residence
인스턴스를 할당하여 더 이상 nil
값을 갖지 않도록 할 수 있습니다:
john.residence = Residence()
swift
이제 john.residence
는 nil
이 아니라 실제 Residence
인스턴스를 포함합니다. 이전과 동일한 옵셔널 체이닝으로 numberOfRooms
에 접근하려고 하면, 이제 기본 numberOfRooms
값인 1
을 포함하는 Int?
를 반환할 것입니다:
if let roomCount = john.residence?.numberOfRooms { print("John's residence has \(roomCount) room(s).") } else { print("Unable to retrieve the number of rooms.") } // "John's residence has 1 room(s)."를 출력합니다.
swift
이렇게 옵셔널 체이닝을 사용하면 nil
값을 안전하게 처리할 수 있으며, 코드의 가독성과 안정성을 높일 수 있습니다. 옵셔널 체이닝은 Swift에서 매우 강력하고 유용한 기능 중 하나이니, 꼭 익혀두시는 것이 좋겠네요!
이번 글에서는 옵셔널 체이닝의 기본 개념과 사용 방법에 대해 살펴보았습니다. 코드 예제와 함께 옵셔널 체이닝이 강제 언래핑과 어떻게 다른지, 그리고 nil
값을 우아하게 처리하는 방법에 대해 알아보았습니다.