귀염둥이의 메모

[Swift] Optional(옵셔널) 본문

iOS/Swift

[Swift] Optional(옵셔널)

겸둥이xz 2021. 2. 17. 11:04
반응형

 

Optional

  • 값이 있을 수도, 없을 수도 있음을 표현.
  • nil(없음)이 할당 될 수 있는지 없는지 표현.
  • nil은 Optional 변수 이외에서 사용불가.

 

Optional을 쓰는 이유

  • 명시적 표현
    1. nil의 가능성을 코드만으로 표현가능.
    2. 문서/주석 작성 시간 절약가능.
  • 안전한 사용
    1. 전달받은 값이 Optional이 아니라면 nil 체크를 하지 않고 사용가능.
    2. 예외 상황을 최소화한다.

 

Optional 선언

var optionalValue: Optional<Int> = nil
var optionalValue: Int? = nil // 같은 표현

optionalValue = 30

var someValue = optionalValue // someValue는 Optional타입

// var someValue: Int = optionalValue -> error
// Int타입에 nil이 들어갈 수 있는 optionalValue를 넣어주었기 때문에 오류발생

IntInt?는 다른 타입이다.

 

Optional Binding & Unwrapping

var someValue: Int? = 30

print(someValue) // Optional(30)

30이 아닌 Optional(30)이 출력된다.

 

 

if let을 통한 바인딩 (variable shadowing가능)

var someValue: Int? = 30

if let someValue = someValue {
    print(someValue)
} else {
    print("someValue == nil")
}
// 30


someValue = nil

if let someValue: Int = someValue {
    print(someValue)
} else {
    print("someValue == nil")
}
// someValue == nil

 

! 를 이용한 Forced Unwrapping

var someValue :Int? = 30

var value : Int = someValue!

print(value) // 30

someValue = nil
print(someValue!) // error

nil 여부와 관계 없이 unwrapping -> nil 값이면 error발생, 추천되지 않는 방식

 

암시적 추출 옵셔널 (Implicitly Unwrapped Optional)

var someValue: Int! = 30
print(someValue) // 30

someValue = nil
// print(someValue) // error

이렇게 정의된 Optional은 nil을 포함할 수 있지만, 접근할 때 Optional binding이나 Optional을 벗기는 과정을 거치지 않고도 바로 값에 접근할 수 있다.

nil인데 접근을 시도하면 error가 발생한다!

 

 

옵셔널 체이닝 (Optional Chaining)

매번 if let으로 nil을 확인 하지 않고 최종적으로 원하는 값이 있는지 없는지 확인 가능하다.

// 사람 클래스
class Person {
    var name: String
    var job: String?
    var home: Apartment?
    
    init(name: String) {
        self.name = name
    }
}

// 사람이 사는 집 클래스
class Apartment {
    var buildingNumber: String
    var roomNumber: String
    var `guard`: Person?	// 경비원
    var owner: Person?
    
    init(dong: String, ho: String) {
        buildingNumber = dong
        roomNumber = ho
    }
}

// 옵셔널 체이닝
let james: Person? = Person(name: "James")
let apart: Apartment? = Apartment(dong: "101", ho: "202")
let joe: Person? = Person(name: "Joe")

 

 

 1. 옵셔널 체이닝 사용 X

// 옵셔널 체이닝 사용 X
if let owner = james,
   let home = owner.home,
   let `guard` = home.guard,
   let guardJob = `guard`.job  {
    print("우리집 경비원의 직업은 \(guardJob)입니다")
} else {
    print("우리집 경비원은 무직입니다")       
}
// 우리집 경비원은 무직입니다

2. 옵셔널 체이닝 사용 O

// 옵셔널 체이닝 사용
if let guardJob = james?.home?.guard?.job {
	print("우리집 경비원의 직업은 \(guardJob)입니다")
} else {
	print("우리집 경비원은 무직입니다")
}
// 우리집 경비원은 무직입니다
print(james?.home?.guard?.job) // nil
// 집 할당
james?.home = apart
// 경비원 할당
james?.home?.guard = joe
print(james?.home?.guard) // Optional(Person)
print((james?.home?.guard?.name)!) // Joe
print(james?.home?.guard?.job) // nil

 

nil 병합 연산자

  • 중위 연산자이고 ??를 사용한다.
  • Optional 값이 nil인 경우에 우측의 값을 반환한다.
var optionalValue: Int? = nil
var someValue: Int

someValue = optionalValue ?? 100
print(someValue) // 100

 

 

 

 

<참고 자료>

BoostCourse - iOS 프로그래밍을 위한 스위프트 기초 : www.boostcourse.org/mo122/joinLectures/38564

반응형
Comments