Optional unwrapping : 옵셔널로 감싸진 옵셔널이 아닌 값을 추출하는 작업
주의 - 옵셔널 언래핑의 대상이 nil이어서는 안 된다.
(nil은 값이 아니다!! 값이 없음을 나타내는 개념임)
옵셔널의 실제 값에 상관없이 강제로 값을 추출하는 것
옵셔널이 nil일 때 강제추출을 사용하면 에러가 발생
사용하지 않는 것이 좋다
안전하게 옵셔널 값을 언래핑 하는 방법으로, 가장 많이 사용한다.
if let ..., guard let ... else 가 주로 사용된다.
공통적으로
if let 임시상수 = 옵셔널값 또는 guard let 임시상수 = 옵셔널값)옵셔널값이 nil이 아니라면 : 임시상수에 옵셔널 언래핑된 값이 저장되고, true 반환옵셔널값이 nil이라면 : false 반환let 옵셔널숫자: Int? = 4
if let 임시상수 = 옵셔널숫자 {
// '옵셔널숫자'가 nil이 아닐 때
print(임시상수)
} else {
// '옵셔널숫자'가 nil일 때
print(옵셔널숫자)
}
임시상수의 스코프는 if 구문이다.옵셔널숫자의 값은 여전히 옵셔널이다.let name: String? = nil
let age: Int? = nil
if let name = name, let age = age, age > 5 {
// name과 age 가 모두 nil이 아니고, age가 5보다 커야 if 구문이 true가 됨.
}
guard let 임시상수 = 옵셔널숫자 else {
// "옵셔널숫자" 가 nil임
return
}
// "옵셔널숫자" 가 nil이 아님
// 이 스코프에서 "임시상수" 사용 가능
guard = 지키다 라는 뜻.
guard문의 조건을 만족하지 못하면 else문으로 처리되며, 함수는 리턴됨guard 조건을 만족하지 못하면 함수 내로 들어오지 못하도록 "막는" 역할!
유의할 점
임시상수를 사용할 수 없음func test(_ name: String?, _ age: Int?) {
guard let name = name, let age = age, age < 5 else {
return
}
}
if letguard let강제 추출이나 옵셔널 바인딩처럼, 별도의 추출 과정을 거치지 않아도 자동으로 옵셔널이 해제되는 방법.
주의 - 옵셔널 타입을 옵셔널이 아닌 타입에 대입할 때, 별도의 언래핑 없이 자동으로 추출해 준다. 아무 때나 자동으로 추출해 주는 것이 아님.
var num: Int? = 4
var num2: Int = num
// 에러 발생 - 옵셔널 타입을 옵셔널이 아닌 타입에 대입하려 하기 때문
var num: Int! = 4 // IUO 사용
var num2: Int = num // num2의 값은 4이다
// 정상 작동 - IUO를 사용했기 때문
let name: String!IUO는 "프로퍼티 지연 초기화"를 하기 위해 사용한다.
실제로 개발자가 직접 IUO를 쓰기보다는
외에는 옵셔널 바인딩을 사용하자.
옵셔널값 ?? 기본값
옵셔널 값이 nil이 아니면 옵셔널을 언래핑한 값을, nil이면 ?? 뒤의 기본값을 사용
옵셔널값 과 기본값은 옵셔널을 벗기면 동일한 타입이어야 한다.체이닝 = 연쇄.
따라서 옵셔널 체이닝 = 옵셔널을 연쇄적으로 사용하는 것.
.(dot)을 통해 내부 프로퍼티나 메서드에 연속적으로 접근할 때, 옵셔널 값이 하나라도 포함되어 있다면 그것을 옵셔널 체이닝이라고 한다.person.contacts?.addressperson?.getContacts()?.email?를 붙여주는 것이다.유의사항
?를 생략한다.메서드명()?으로 작성person?.getContacts()?.email메서드명?() 으로 작성function?().email메서드명?()? 으로 작성function?()?.email[]? 로 작성dic["name"]?.countstruct Contacts {
var email: String
var address: String
}
struct Person {
var name: String
var contacts : Contacts
init(name: String, email: String, address: String) {
self.name = name
contacts = Contacts(email: email, address: address)
}
}
var tom: Person? = Person(name: "Tom", email: "tomntoms@naver.com", address: "Seoul")
tom.contacts.email // 에러 - tom 이 옵셔널 타입이기 때문.
tom?.contacts.email // OK - 만약 tom이 nil이면 전체 값도 nil 로 처리됨.