Optional

A type that represents either a wrapped value or the absence of a value.
값 혹은 비어있는 값을 나타내는, 싸여있는(래핑된)타입

왜 Optional?

Optional이 아닌 타입은 Non-optional 타입이라고 한다.

Non-optional타입은 반드시 값을 가져야만 한다.
만약 Non-optional타입에 값이 없다면, 크래시가 일어난다.
때문에 이와 같은 위험을 줄여 언어의 안전성을 제고하기 위해, Swift는 값이 있어도 되고 없어도 되는 Optional이라는 타입을 사용한다.
Optional 타입은 싸여있기 때문에 그냥은 사용할 수 없고, 여러 가지 방법으로 이 래핑을 풀어야 한다.
다음은 Optional타입의 래핑을 푸는 몇 가지 방법들이다.

Optional Binding

  • if let 바인딩
let bindMe: Optional<Int> = Int(1)
if let bound = bindMe {
	print(bound)
} // 1

이와 같이 Optional 값의 래핑을 벗겨서 사용할 수 있으며

let bindMe: Optional<Int> = Int(1)
if let bindMe = bindMe {
		print(bindMe)
} // 1

이렇게 같은 이름을 사용해도 되고,

let bindMe: Optional<Int> = Int(1)
if let bindMe {
		print(bindMe)
} // 1

Swift 5.7부터는 이렇게 =연산자를 생략하고 사용할 수도 있다.

  • guard let 바인딩
    guard let 바인딩은 함수 내에서만 사용 가능하다. ->
    함수의 조건을 검사하는 용도인 guard의 특성상 guard let 역시 함수 내에서만 사용 가능하고, return, throw, break, continue 등의 제어문 전환 명령어가 필요기 때문이다.
let bindMe: Optional<Int> = Int(1)
func illBindYou(_ who: Optional<Int>) {
    guard let bindMe = bindMe else { return }
    print(bindMe)
}
illBindYou(bindMe) // 1
let bindMe: Optional<Int> = Int(1)
func illBindYou(_ who: Optional<Int>) {
    guard let bindMe else { return }
    print(bindMe)
}
illBindYou(bindMe) // 1

if let 바인딩과 마찬가지로 = 연산자는 생략할 수 있다.

nil-Coalescing

옵셔널 값이 nil일 경우를 대비해서 nil-coalescing 연산자(??)를 사용한다.
좌항이 nil이 아닐 경우 좌항을 할당하고, 좌항이 nil일 경우에는 우항을 할당한다.
nil-Coalescing을 사용하면 옵셔널 값이 비어있을 경우를 위한 기본값을 설정하기 좋다.

let nilCoalesceLhs: Optional<Int> = 1
let nilCoalesceRhs: Optional<Int> = nil

let coalesceLhs = nilCoalesceLhs ?? Int(2)
print(coalesceLhs) // 1

let coalesceRhs = nilCoalesceRhs ?? Int(2)
print(coalesceRhs) // 2

?? 연산자는 오른쪽에 위치한 다른 옵셔널 값과도 작동하기 때문에, 여러 개의 ?? 연산자를 함께 사용할 수도 있다.

let coalesceFirst: Optional<Int> = nil
let coalesceSecond: Optional<Int> = nil

let coalesceChain = coalesceFirst ?? coalesceSecond ?? Int(3)
// coalesceFirst값 체크->nil이므로 coalesceSecond값 체크-> 다시 nil이므로 Int(3)에 도달

print(coalesceChain) // 3

Unconditional Unwrap

일명 강제 언래핑
단순히 Optional 값의 뒤에 !를 붙임으로써 사용할 수 있다.

let soSimple: Optional<Int> = 1
print(soSimple!) // 1

하지만 만약 Optional이 값을 가지고 있지 않을 경우, 즉시 런타임 오류가 발생한다.
안전성을 위한 Optional을 간단하게 풀어버리는 만큼, 안전성을 포기하는 언래핑 방법이라고 할 수 있다.

let areYouSure: Optional<Int> = nil
print(areYouSure!) // 크래시

다만 로직상 Optional이 반드시 값을 가지고 있을 수밖에 없는 등 확신이 있다면 편리하게 사용할 수도 있다.

Implicitly Unwrapped Optional(IUO)

암시적 추출 옵셔널

타입의 선언시 타입 뒤에 !를 붙임으로써 사용할 수 있다.

IUO로 지정된 타입은 일반 값처럼 사용할 수 있으나, nil을 할당할 수도 있다. 하지만 nil이 할당되어 있을 때 접근하면 런타임 오류가 발생한다.

var bornToWrap: String! = "good"
print(bornToWrap) // good

bornToWrap = nil
print(bornToWrap) // 크래시

1개의 댓글

comment-user-thumbnail
2023년 11월 23일

Optional 개념을 확실히 알았습니다 감사합니다!! 👍

답글 달기
Powered by GraphCDN, the GraphQL CDN