옵셔널이란 무엇인가?

Swift를 쓰다보면 우리는 꽤 잦은 비율로 '?' 형태로 구현된 옵셔널을 마주하거나 사용하게 된다. 값이 있을 수도 없을 수도 있음을 표현해주는 이 문법은 자주 사용하지만 어떻게 구현되어 있는 지까지 학습하지는 않게 된다.
그래서 오늘은 간단하게나마 옵셔널이 어떻게 구현된 문법인지를 정리해보고자 한다.

옵셔널은 어떻게 구현되어 있을까?

let girlFriend: Person? = nil

보통 우리가 옵셔널을 사용할 때는 선언 타입 뒤에 '?'를 붙여주는 형태로 사용한다. 하지만 이런 형태는 축약 형태로서 실제로는 아래의 문법 체계를 가지고 있다.

let girlFriend: Optional<Person> = nil

@frozen public enum Optional<Wrapped> : ExpressibleByNilLiteral {
    case none
    case some(Wrapped)

    public init(_ some: Wrapped)
    
    @inlinable public func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U?
    @inlinable public func flatMap<U>(_ transform: (Wrapped) throws -> U?) rethrows -> U?

    public init(nilLiteral: ())

    @inlinable public var unsafelyUnwrapped: Wrapped { get }

    public static func ~= (lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool
    public static func == (lhs: Wrapped?, rhs: _OptionalNilComparisonType) -> Bool
    public static func != (lhs: Wrapped?, rhs: _OptionalNilComparisonType) -> Bool
    public static func == (lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool
    public static func != (lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool
}

뭐 대충 이러한 형태로 구현되어 있다. 물론 아래에 extension으로 더 많은 구문들이 구현되어 있지만 너무 길어질 듯 하여 제외하였다.

일단 제일 중요한 것은 Optional은 enum으로 선언되어 있어 값이 없다(.none)와 값이 있다(.some(Wrappend))로 나눠져 있으며 제네릭이기에 어떤 타입이든 받을 수 있게 된다.

if girlFriend == .none{
	...
} else if == .some("Who?"){
	...
}

따라서 위와 같은 형태로 사용도 가능하니 참고해서 적절한 때에 활용하면 좋을 것 같다.

옵셔널은 왜 사용할까?

그렇다면 이러한 옵셔널 문법을 왜 사용하는 것일까? 프로젝트를 진행하다보면 ViewController에서 View나 하위의 VC를 관리 또는 delegate 등을 활용하게 되는데, 이러한 것들은 VC가 생성되는 시기까지 생성이 되지 않아 프로퍼티에 할당되지 않을 수도 있다.
그럴 때, 해당 프로퍼티들이 옵셔널로 지정되어 있지 않다면 당연히 런타임 오류가 날 수 밖에 없다. 이러한 상황에서 요긴하게 사용될 수 있는 게 옵셔널이라는 문법이다.

물론 서버와 데이터를 주고받을 때 등 다양한 상황에서 유용하기 때문에 옵셔널을 잘 활용하는 것이 중요하지 않을까 생각된다.

좋은 웹페이지 즐겨찾기