Swift가 가지고 있는 가장 큰 특징 중 하나인 Optional(옵셔널)에 대해서 알아보자.
만약 문자열의 값이 있으면 "Hello" 가 될 것이다. 그렇다면, 값이 없으면 "" 인가? 그렇지 않다 "" 도 엄연히 값이 있는 문자열이다. 즉, 값이 없다가 아니라 비어있는 값이다. 이때 값이 없는 문자열을 의미하는 것이 바로 nil 이다.
만약 정수형의 값이 있으면 123 과 같은 값이 있을 것이다. 값이 없다면 0 인가? 역시나 그렇지 않다 0 도 0 이라는 값이다. 이 경우에도 nil 을 사용한다.
이렇게, 값이 없는 경우를 나타낼 때 nil 을 사용한다. 그렇다고해서 모든 변수에 nil 을 넣을 수 있는 것은 아니다.
값이 있을 수도 있고 없을 수도 있는 변수를 정의할 때 타입 어노테이션에 ? 를 붙여야한다. 즉, 옵셔널에 초기값을 지정하지 않으면 기본값은 nil 이다.
옵셔널로 정의한 변수는 옵셔널이 아닌 변수와는 다르다. 예를 들면 아래와 같은 코드는 사용할 수 없다.
let optionalEmail: String? = "devxoul@gmail.com"
let requiredEmail: String = optionalEmail // 컴파일 에러!
requiredEmail 변수는 옵셔널이 아닌 String 이기 때문에 항상 값을 가지고 있어야 한다. 반면에, optionalEmail 은 옵셔널로 선언된 변수이기 때문에 실제 코드가 실행되기 전까지는 값이 있는지 없는지 알 수 없다. 따라서 Swift 컴파일러는 안전을 위해 requiredEmail 에는 옵셔널로 선언된 변수를 대입할 수 없게 만들었다.
Optional Binding(옵셔널 바인딩)
그렇다면 옵셔널의 값을 가져오고 싶은 경우에는 어떻게 하면 될까?
이 때 Optional Binidng을 이용하면 된다.
옵셔널 바인딩은 옵셔널의 값이 존재하는지를 검사한 뒤, 존재한다면 그 값을 다른 변수에 대입시켜준다. if let 또는 if var 를 사용하는데, 옵셔널의 값을 벗겨서(unwraped) 값이 있다면, if 문 안으로 들어가고, nil 이라면 그냥 통과하게 된다.
Optional Chaining(옵셔널 체이닝)
Swift 코드를 간결하게 만들어주는 많은 요소들이 있는데, 그 중하나가 옵셔널 체이닝이다.
예를 들어 옵셔널로 선언된 어떤 배열이 있다. 이 배열이 빈 배열인지를 확인해보려면 어떻게 해야할까? nil 이 아니면서 빈 배열인지 확인해보면 된다.
let array: [String]? = []
var isEmptyArray = false
if let array = array, array.isEmpty {
isEmptyArray = true
} else {
isEmptyArray = false
}
isEmptyArray
옵셔널 체이닝을 사용하면 코드를 더 간결하게 쓸 수 있다.
let isEmptyArray = array?.isEmpty == true
Unwrapping Optional(옵셔널 벗기기)
옵셔널을 사용할 때마다 옵셔널 바인딩을 하는 것이 가장 바람직 하다. 하지만, 개발을 하다보면 분명히 값이 존재할 것임에도 불구하고 옵셔널로 사용해야하는 경우가 잆는데, 이럴때에는 옵셔널에 값이 있다고 가정하고 값에 바로 접근할 수 있도록 도와주는 ! 를 붙여서 사용하면 된다.
print(optionalEmail) // Optional("devxoul@gmail.com")
print(optionalEmail!) // devxoul@gmail.com
! 를 사용할 때는 주의할 점이 있는데, 옵셔널의 값이 nil 인 경우에는 런타임 에러가 발생한다는 것이다.
Implicitly Unwrapped Optional(암묵적으로 벗겨진 옵셔널)
만약 옵셔널을 정의할 때 ? 대신 ! 를 붙이면 ImplicitlyUnwrappedOptional 이라는 옵셔널로 정의된다.
var email: String! = "devxoul@gmail.com"
print(email) // devxoul@gmail.com
이렇게 정의된 옵셔널은 nil 을 포함할 수 있는 옵셔널이긴 하지만, 접근할 때 옵셔널 바인딩이나 옵셔널을 벗기는 과정을 거치지 않고도 바로 값에 접근할 수 있다는 점에서 일반적인 옵셔널과 조금 다르다.
옵셔널 벗기기와 마찬가지로, 값이 없는데 접근을 시도하면 런타임 에러가 발생한다.
https://devxoul.gitbooks.io/ios-with-swift-in-40-hours/content/Chapter-2/optionals.html