nil
을 사용할 수 있는 타입과 그렇지 못한 타입을 구분하기 위한 수단이다.nil
을 사용할 수 있는 타입을 Optional Type이라고 한다.→ 즉, 에러가 났지만 바로 앱을 중단시키는 것이 아닌, nil
을 내 뱉을거다.(기회를 한번 더 주는 것!)
let people = ["kim": 1, "lim": 2, "hyun": 3]
let name = people["kim"] // 1
nil
을 던져 프로그램의 강제 종료를 막는 것이다!let name = people["brrr"] // nil
?
을 통하여 optional을 선언할 수 있다.var people: String?
people = nil // 에러가 생기지 않는다.
// 만약
var peopel: String
people = nil // error
let number: Int? = nil
let number2 = number
// number2도 옵셔널 타입이 된다.
let number: Int? = nil
print(type(of: number)) // Optional<Int>
number = 4
print(number) // Optional(4)
nil
이면 안된다.nil
은 어떠한 값이 아니다! 그냥 값이 없는 것이다.nil
은 unwrapping 할 수 없다. 만약 하려고 하면 에러가 난다!nil
이건 말건 그냥 강제로 옵셔널을 때어버리는 것이다.let number: Int? = nil
print(a!) // error
nil
이 아니라면 상수에 옵셔널이 해제가 된 값을 저장하고, true를 return한다.nil
이라면 false를 return 한다.if let
let optionalNum: Int? = 10
if let num = optionalNum { print("num") } else { print("optionalNum") }
// 10
nil
이 저장되어있었다면? nil
을 프린트한다.let optionalNum: Int? = nil
if let num = optionalNum { print("num") } else { print("optionalNum") }
// nil
guard let
let optionalNum: Int? = 10
guard let num = optionalNum else { print("optionalNum") }
// 10
지역 변수
의 성격let optionalNum: Int? = 10
if let num = optionalNum { print("num") } else { print("optionalNum") }
print(num) // error
전역 변수
의 성격nil
일 경우 무조건 함수의 실행을 종료시키고 싶을 때!let optionalNum: Int? = 10
guard let num = optionalNum else { return }
print(num) // 10
let name: String! // IUO
optional type을 non-optional type에 대입이 될 경우, 별도의 추출 과정이 없이 대입이 가능하다.
- 우리가 알고 있는 Optional Type은 아래와 같다. Optional unwrapping 없이 대입을 하기에 error가 난다.
var name: String? = "Miro"
var name2: String = name // error
var name: String! = "Miro" // 아직, Optional<String>이다
var name2: String = name // OK
.(점)
을 통하여 메서드나 프로퍼티에 접근을 연쇄적으로 할 때, 옵셔널 값이 하나라도 있다면, 옵셔널 체이닝이다.human.gender?.bloodType
human?.gender?.bloodType
struct Genders {
var bloodType: String
var height: Int
}
struct Human {
var name: String
var gender: Genders
init(name: String, bloodType: String, height: Int) {
self.name = name
gender = Genders(bloodType: bloodType, height: height)
}
}
var miro: Human? = Human(name: "Miro", bloodType: "A", height: 185)
miro.gender.height // error
nil
이라면 nil
이 반환이된다.miro?.gender.height // 185
miro = nil
let height = miro?.gender.height // nil이지만, height의 타입은 Optional<Int>type
?
를 생략한다!struct Genders {
var bloodType: String
var height: Int?
}
let height = miro?.gender.height? // error
let height = miro?.gender.height // OK
nil
이라면, 나머지 표현식은 평가하지도 않고 그냥 nil
을 return한다.()?
를 붙혀준다!struct Human {
var name: String
var gender: Genders
init(name: String, bloodType: String, height: Int) {
self.name = name
gender = Genders(bloodType: bloodType, height: height)
}
func getGenders() -> Genders? {
return gender
}
}
miro?.getGenders()?.height // 185
?()
를 통하여 접근을 한다. ( return 값은 옵셔널 아님!)struct Human {
var name: String
var gender: Genders
init(name: String, bloodType: String, height: Int) {
self.name = name
gender = Genders(bloodType: bloodType, height: height)
}
func getGenders() -> Genders { // return 값 옵셔널 아님
return gender
}
}
let function = miro?.getGenders()
function?().height // OK
?()?
를 통하여 접근해준다.struct Human {
var name: String
var gender: Genders
init(name: String, bloodType: String, height: Int) {
self.name = name
gender = Genders(bloodType: bloodType, height: height)
}
func getGenders() -> Genders? {
return gender
}
}
let function = miro?.getGenders()
function?()?.height // OK
Swift) Optional 부수기 (3) Optional Unwrapping - 옵셔널 바인딩(if let vs guard let)
Swift) Optional 부수기 (4) Optional Unwrapping - IUO (옵셔널 묵시적 추출)