스위프트는 C, Objective-C와 달리 어떤 타입의 값이든 옵셔널을 사용해 "값이 있거나 없는 상황"을 모두 처리할 수 있다.
?
을 타입 뒤에 붙여 옵셔널을 표시한다.var digits:String = "1234567"
var numbers = Int(digits)
// digits -> Int? or optional Int
스위프트는 옵셔널이 아닌 변수와 상수에게 널 값을 허용하지 않는다.
옵셔널 변수가 아니라면 널을 사용할 수 없다는 게 가장 큰 차이점이다. 옵셔널 변수를 사용해 타입 세이프티를 확보할 수 있다는 점에서 스위프트는 다른 선택을 내린 것 같다.
nil
과 비교 연산자 ==
또는 !=
을 통해 확인할 수 있다.!
을 옵셔널 다음에 붙여 사용할 수 있다. 즉 "값이 있다고 확인"했다는 선언이며, 이를 강제 언래핑(forced unwrapping)이라고 한다.값이 없는 옵셔널 값에 접근하면 런타임 에러가 일어난다.
!
을 사용하는 강제 언래핑은 nil
값을 가지는 위험이 있다. 바인딩을 통해 옵셔널 표현식이 값을 가지는지 crush 위험 없이 판단할 수 있다.
let a:Int? = 123
if let b = a {
print("\(b) is non-nil")
} else {
print("a is nil")
}
// "123 is non-nil"
,
로 값을 언래핑하면 된다.강제 언래핑보다 옵셔널 바인딩이 더 안전한 방식이다.
옵셔널 표현식을 사용할 때 값이 들어간 게 확실한 이후에는 언래핑할 필요 없이 옵셔널 표현식을 사용할 수 있다. 즉 "옵셔널 값을 설정했으니 여기에는 앞으로 계속해서 값이 들어 있다!"는 말이다.
!
로 선언하자.let str1:String? = "an optional string"
let fored_str:String = str1!
let str2:String! = "an implicitly unwrapped optional string"
let implicit_str:String = str2
암시적으로 언래핑한 옵셔널을 If 문을 사용한 nil
과의 비교, 옵셔널 바인딩과 함께 사용할 수 있다.
이후에
nil
이 될 수 있는 변수는 암시적으로 언래핑해서 사용하면 안 된다.
스위프트는 에러 조건에 맞추어 핸들링할 수 있다. 옵셔널과 달리 failure의 원인을 구체적으로 다룰 수 있고, 또한 에러를 다른 방향으로 throw할 수 있다.
func canThrowAnError() throws {
// this function may or may not throw an error
}
do {
try canThrowAnError()
// no error was thrown
} catch {
// an error was thrown
}
기본적으로 Java 등 타 프로그래밍 언어의 try catch 문과 같은 양식이다.
이후 코드를 실행하기 전에 필수적인 조건을 충족했는지 런타임 도중에 확인할 수 있다. assertion 또는 precondition 문 안에 존재하는 불리언 값이 참이라면 코드를 계속 이어가면 되고, 아니라면 더 이상 현재 상태가 유효하지 않다는 뜻이므로 앱 자체가 종료된다.
assert 함수를 사용해 assertion 문을 작성할 수 있다. 이 함수를 통해 특정 표현식이 참인지 거짓인지 판단할 수 있다. 다음 age
값을 기준으로 assert fail이 발생한다.
let age = 300
assert(age>=0 && age<=120, "check your age range")
조건문이 거짓일 수 있는 상황에서 precondition 함수를 사용하자. 이때 코드가 계속해서 실행되는 게 확실해야 한다. 아래 상황에서 index
값은 양수여야 한다.
// In the implementation of a subscript...
precondition(index > 0, "Index must be greater than zero.")
fatalError 함수를 통해 프로토타입 개발 또는 초기 개발 시 stub 함수를 사용할 수 있다.