Optional
은 아래와 같이 enum
으로 구현되어 있습니다.
enum Optional<T> {
case none
case some(<T>)
}
optional
의 타입은 generic
이라 Int, String
등 어떤 타입도 들어갈 수 있습니다.
optional
에는 두가지 경우가 있는데, none
은 아직 설정되지 않은 경우이고 some
은 그 타입의 값을 가지고 있다는 의미입니다.
optional
은 enum
이지만 enum
으로 사용하지 않는 이유는 optional
을 사용할 때마다 switch
문을 사용하여 값을 얻어야 합니다. 그러면 코드도 길어지고 복잡해 질 것입니다. 그래서 ?, !, ??, if
등으로 쉽게 표기하게 만들고 내부적으로는 enum
으로 작성된 optional
코드가 실행되는 것입니다.
var hello: String? // var hello: Optional<String> = .none
var hello: String? = "hello" // var hello: Optional<String> = some("hello")
var hello: String? = nil // var hello: Optional<String> = .none
optional
은 항상 nil
로 시작합니다.
아래는 optional
을 unwrapping
하는 방법을 보여주는 예제입니다.
enum Optional<T> {
case none
case some(<T>)
}
let hello: String? = "hello"
print(hello!)
switch hello {
case .none: // error 발생
case .some(let data): print(data)
}
enum Optional<T> {
case none
case some(<T>)
}
if let greeting = hello {
print(greeting)
} else {
// do someting...
}
switch hello {
case .none: // do something...
case .some(let data): print(data)
}
enum Optional<T> {
case none
case some(<T>)
}
let hello: String? = "hello"
let greeting = hello ?? "bye"
switch hello {
case .none: greeting = "bye"
case .some(let data): greeting = data
}
nil 병합 연산자는 ??
로 표현되고 optional
의 값이 있으면 some
의 경우인 ??
의 왼쪽 값을 사용하고, 값이 없으면 none
의 경우인 ??
의 오른쪽 값을 사용하는 것이다.
아래는 옵셔널 체인을 보여주는 예제입니다.
enum Optional<T> {
case none
case some(<T>)
}
let x: String? = ...
let y = x?.foo()?.bar?.z
switch x {
case .none: y = nil
case .some(let data1):
switch data1.foo() {
case .none: y = nil
case .some(let data2):
switch data2.bar {
case .none: y = nil
case .some(let data3): y = data3.z
}
}
}