[Swift] 옵셔널 언래핑 방법들 정리
옵셔널 언래핑 방법들 정리
Optional unwrapping : 옵셔널로 감싸진 옵셔널이 아닌 값을 추출하는 작업
주의 - 옵셔널 언래핑의 대상이 nil이어서는 안 된다.
(nil은 값이 아니다!! 값이 없음을 나타내는 개념임)
1. 강제 추출 Forced Unwrapping
옵셔널의 실제 값에 상관없이 강제로 값을 추출하는 것
옵셔널이 nil일 때 강제추출을 사용하면 에러가 발생
사용하지 않는 것이 좋다
2. 옵셔널 바인딩 Optional Binding
안전하게 옵셔널 값을 언래핑 하는 방법으로, 가장 많이 사용한다.
if let ..., guard let ... else 가 주로 사용된다.
공통적으로
- 옵셔널 표현식 작성 (
if let 임시상수 = 옵셔널값또는guard let 임시상수 = 옵셔널값)- 타입 추론이 되므로 타입 어노테이션은 대부분 생략
옵셔널값이 nil이 아니라면 :임시상수에 옵셔널 언래핑된 값이 저장되고, true 반환옵셔널값이 nil이라면 : false 반환
if let
let 옵셔널숫자: Int? = 4
if let 임시상수 = 옵셔널숫자 {
// '옵셔널숫자'가 nil이 아닐 때
print(임시상수)
} else {
// '옵셔널숫자'가 nil일 때
print(옵셔널숫자)
}
사용 시 유의점
- ❗
임시상수의 스코프는 if 구문이다. - ❗
옵셔널숫자의 값은 여전히 옵셔널이다.
if let - 여러 개의 옵셔널값 바인딩 및 조건 추가
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
guard let 임시상수 = 옵셔널숫자 else {
// "옵셔널숫자" 가 nil임
return
}
// "옵셔널숫자" 가 nil이 아님
// 이 스코프에서 "임시상수" 사용 가능
guard = 지키다 라는 뜻.
- 특성상 함수(메서드)에서만 사용됨
guard문의 조건을 만족하지 못하면else문으로 처리되며, 함수는 리턴됨- 반드시 else와 함께 사용 - 조건 불만족시 리턴시켜야 하기 때문
guard 조건을 만족하지 못하면 함수 내로 들어오지 못하도록 "막는" 역할!
유의할 점
- else 문에서는
임시상수를 사용할 수 없음
guard let - 여러 개의 옵셔널값 바인딩 및 조건 추가
func test(_ name: String?, _ age: Int?) {
guard let name = name, let age = age, age < 5 else {
return
}
}
if let 과 guard let 비교
if let- 옵셔널 값 있으면 if구문에서 처리하고, nil이면 else에서 처리해.
- 옵셔널 값의 경우에 대한 피드백을 제공할 때 사용
guard let- 옵셔널 값 있으면 계속 진행하고, 없으면 내 함수에서 나가.
- 옵셔널 값이 nil인 경우 무조건 함수를 종료시키고 싶을 때 사용
3. 옵셔널 묵시적 추출 IUO - Implicitly Unwrapped Optional
강제 추출이나 옵셔널 바인딩처럼, 별도의 추출 과정을 거치지 않아도 자동으로 옵셔널이 해제되는 방법.
주의 - 옵셔널 타입을 옵셔널이 아닌 타입에 대입할 때, 별도의 언래핑 없이 자동으로 추출해 준다. 아무 때나 자동으로 추출해 주는 것이 아님.
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인 경우에는 묵시적 추출을 하려 해도 에러가 발생한다.
왜 쓰는가?
IUO는 "프로퍼티 지연 초기화"를 하기 위해 사용한다.
실제로 개발자가 직접 IUO를 쓰기보다는
- IBOutlet
- API 에서 IUO를 리턴한 경우
외에는 옵셔널 바인딩을 사용하자.
4. ?? 연산자 - nil 병합 연산자 (Nil-Coalescing Operation)
옵셔널값 ?? 기본값
옵셔널 값이 nil이 아니면 옵셔널을 언래핑한 값을, nil이면 ?? 뒤의 기본값을 사용
옵셔널값과기본값은 옵셔널을 벗기면 동일한 타입이어야 한다.
5. 옵셔널 체이닝 Optional Chaining
체이닝 = 연쇄.
따라서 옵셔널 체이닝 = 옵셔널을 연쇄적으로 사용하는 것.
.(dot)을 통해 내부 프로퍼티나 메서드에 연속적으로 접근할 때, 옵셔널 값이 하나라도 포함되어 있다면 그것을 옵셔널 체이닝이라고 한다.- 예시1 :
person.contacts?.address - 예시2 :
person?.getContacts()?.email
- 예시1 :
- 옵셔널 표현식의 멤버에 접근할 때, 표현식이 nil일 수 있기 때문에
?를 붙여주는 것이다.- 만약 표현식이 nil이면, 전체 값도 nil 이 된다.
- 만약 표현식이 nil이 아니라면, 언래핑된 값으로 연쇄 접근한다.
- 옵셔널 표현식의 결과값은 항상 옵셔널이다.
유의사항
- 옵셔널 체이닝 결과 타입은 마지막 표현식의 옵셔널 타입이다.
- 옵셔널 체이닝의 마지막 표현식은 옵셔널이더라도
?를 생략한다. - 옵셔널 표현식의 멤버(프로퍼티/메서드) 중 메서드에 접근할 때,
- 리턴값이 옵셔널이면 괄호 뒤에
메서드명()?으로 작성 - 예시 :
person?.getContacts()?.email - 메서드 자체가 옵셔널인 경우
메서드명?()으로 작성- 예시 :
function?().email
- 예시 :
- 메서드 자체도 옵셔널이고, 리턴값도 옵셔널이면
메서드명?()?으로 작성- 예시 :
function?()?.email
- 예시 :
- 리턴값이 옵셔널이면 괄호 뒤에
- 옵셔널 표현식의 멤버 중 딕셔너리에 접근할 때
- 딕셔너리 키 값으로 얻은 값의 속성에 접근할 때
[]?로 작성- 예시 :
dic["name"]?.count
- 예시 :
- 딕셔너리 키 값으로 얻은 값의 속성에 접근할 때
struct 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: "[email protected]", address: "Seoul")
tom.contacts.email // 에러 - tom 이 옵셔널 타입이기 때문.
tom?.contacts.email // OK - 만약 tom이 nil이면 전체 값도 nil 로 처리됨.
Author And Source
이 문제에 관하여([Swift] 옵셔널 언래핑 방법들 정리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@bibi6666667/Swift-옵셔널-언래핑-방법들-정리저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)