본문 바로가기

DEV/Swift

[Swift] Optional (옵셔널)

옵셔널은 간단히 말해 데이터 타입의 한 종류라고 보면 된다.

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)