
스위프트는 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 함수를 사용할 수 있다.