옵셔널은 간단히 말해 데이터 타입의 한 종류라고 보면 된다.
var num1: Int = 3 //3의 값을 가지는 '정수형' 변수
var num2: Int? = 5 //5의 값을 가지는 '옵셔널 정수형' 변수
단, 옵셔널 타입과 일반 타입의 차이점은 nil(값 없음)값을 사용할 수 있느냐의 차이.
var num3: Int = nil //일반 정수형 타입에서 nil은 불가능, 오류 발생!!!
var num4: Int? = nil //옵셔널 정수형 타입에서 nil 가능
그리고 옵셔널은 사용이 잘못된다면 오류가 날 소지가 있음.
때문에 언래핑(unwrapping) 작업을 따로 해줘야 안전하게 사용 가능.
/* Optional */
var optNum: Int? //optional 데이터 타입 선언된 변수
optNum = 3
print(optNum!) //optional Int 값 강제 추출은 "!"로 표시
optNum = nil //만약 optional값이 'nil(값없음)'이라면 추출 시 에러 발생
//때문에 if문으로 크래시를 피해주는 것이 좋음
if optNum != nil {print(optNum!)}
else { print("empty")}
//optional binding처리 (if let)
//if let으로(바인딩) 새로운 상수를 만들어 "!"를 써서 강제 언래핑 할 필요 없음
if let mynum = optNum {print(mynum)}
else {print("empty")}
//optional chaning: 클래스 등 컨테이너 안에 있는 프로퍼티를 효과적으로 사용하기 위함
class Person { //클래스 1
var name: String?
var job: String?
var family: Family?
}
class Family { //클래스 2
var familyName:String?
}
var john = Person()
var family = Family()
john.family = family //두 클래스를 연결함
john.name = "John"
john.family?.familyName = "Smith"
if let fName = john.family?.familyName {
print(fName)
}
else {print("Family is Empty")}
//nil 병합 연산자: "??"를 두고 앞의 값이 nil이면 뒤의 값을 사용, 그게 아니면 앞의 값을 사용
//자동으로 값이 추출되므로 optional binding보다 편리하게 사용 가능
var bindNum = optNum ?? 123 //optNum1 값이 nil이면 뒷값을 사용, 그게 아니면 optNum1값 사용
print(bindNum)