옵셔널 (Optional)
Optional의 정의
"선택적인"이라는 뜻을 가지는 어떠한 변수에 '값이 있을 수도 없을 수도' 있는 경우에 사용하는 기호
위에서 설명했듯이 값이 없을 수 있는 상황에서 옵셔널을 사용한다. 옵셔널을 2가지의 경우를 나타낼 수 있다.
지정된 타입의 값이 있고 옵셔널을 언래핑하여 해당 값에 액세서할 수 있거나, 값이 전혀 없는 경우이다.
예를 들어 isThisNumber라는 변수에 타입을 지정하지 않은 "123"을 넣는다고 했을 때, convertedNumber에 Int로 타입캐스팅을 하여 할당한다면 convertedNumber의 타입은 무엇인가?
Int로 타입캐스팅을 했다고 Int가 나올 것이라는 대답을 틀렸다.
let isThisNumber = "123"
let convertedNumber = Int(isThisNumber)
// The type of convertedNumber is "optional Int"
위 코드의 이니셜라이저가 실패할 수 있기 때문에 Int가 아닌 optional Int 타입이 반환된다.
옵셔널 사용
옵셔널 타입을 사용하려면 옵셔널 타입에 포함된 타입 이름 뒤에 ?(물음표) 기호를 붙이면 된다. (Int의 옵셔널은 Int? 이다.)
nil
옵셔널 변수에 값이 없는 상태를 할당하기 위해서는 "nil"이라는 특수값을 사용하게 된다.
var notHaveValue: Int? = 123
// notHaveValue는 optional Int 타입으로 123이라는 값을 가지고 있다.
notHaveValue = nil
// notHaveValue에 nil을 할당해줌으로써 더이상 값을 가지고 있지 않게 된다.
매번 이런식으로 nil을 할당해야하는 것은 아니다.
옵셔널 타입으로 변수를 선언하게 되면 초기값으로 nil을 가지고 있다.
var answer: String?
// answer의 초기값은 nil이다.
옵셔널 타입의 조건문
옵셔널 타입의 값이 없는지 if문을 사용하고 싶으면 nil과 비교하면 된다.
let isThisNumber = "123"
let convertedNumber = Int(isThisNumber)
if convertedNumber != nil {
print("convertedNumber contains some integer value.")
}
// 출력 : convertedNumber contains some integer value.
옵셔널이 아닌 상수나 변수에는 nil을 사용할 수 없다. 옵셔널이 아닌 값에 nil을 할당하려고 하면 컴파일 타임 오류가 발생한다.
옵셔널은 그 자체로 열거형의 성질을 띄기 때문에 switch문도 사용할 수 있다.
func doesHaveValue(_ optValue: Any?) {
switch optValue {
case .none: // nil일 때
print("optValue is nil")
case .some: // nil이 아닐 때
print("optValue is \(optValue)")
}
}
var value: Int? = 123
doesHaveValue(value)
// optValue is 123
value = nil
doesHaveValue(value)
// optValue is nil
옵셔널 추출 (Optional Unwrapping)
옵셔널의 값을 옵셔널 타입이 아닌 해당하는 타입의 값을 추출할 수 있는 방법이다.
강제 추출 (Forced Unwrapping)
옵셔널 값 뒤에 !(느낌표)를 붙이면 사용이 가능한 간단한 방법이다. 하지만 옵셔널에 값이 존재하지 않을 때 사용하게 되면 런타임 오류가 발생하기 때문에 사용에 주의해야한다. (옵셔널의 값이 확실하게 존재한다고 생각할 때만 사용하자.)
옵셔널 바인딩 (Optional Binding)
옵셔널 바인딩은 옵셔널의 값이 존재하는 지 확인할 때 사용한다. 옵셔널이 존재한다면 해당하는 코드 내에서 사용 가능하게 할 수 있다.
var isThisNumber: Int? = 123
if let number = isThisNumber {
print("number is \(number).")
} else {
print("number is nil")
}
// 출력 : number is 123
암시적 추출 옵셔널 (Implicity Unwrapping Optionals)
nil을 할당할 수 있는 변수나 상수를 선언할 때 ?(물음표) 대신 !(느낌표)를 사용하면 암시적 추출 옵셔널을 사용할 수 있게된다.
하지만 nil이 할당된 경우 해당 변수나 상수에 접근을 하려고 하면 런타임 오류가 발생한다.