swift 기본문법 - 옵셔널체이닝과 nil 병합 연산자(optional chaining & nil-coalescing operator)

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
인프런, 야곰의 스위프트 기본문법 강좌를 듣고 정리하였습니다.


옵셔널 체이닝(optional chaining)

구조체, 클래스등을 선언해줄때 구조체 안에 또다른 구조체 인스턴스가 들어올 수 있는데, 이렇게 연결되어 프로퍼티를 타고타고 들어가는 경우가 생긴다.
이 프로퍼티 자체가 옵셔널인 경우에는 이게 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 zehye: Person? = Person(name: "zehye")
let apart: Apartment? = Apartment(dong: 101, ho: 3)
let superman: Person? = Person(name: "superman")

세개의 인스턴스를 생성했고 이때 생성만 하고 안에있는 프로퍼티들은 모두 nil 상태이다. > 옵셔널이 초기화됐을때 nil이 할당되어있기 때문
이때 가지게 되는것은 꼭 필요했던 프로퍼티 값들만 가지고 있다 (name, dong, ho)

옵셔널 체이닝을 사용하지않고 경비원의 직업이 궁금하다면?

func guardJob(owner: Person?) {
  if let owner = owner {
    if let home = home {
      if let `guard` = home.guard {
        if let guardJob = `guard`.job {
          print("우리집 경비원의 직업은 \(guardJob)입니다")
        } else {
          print("우리집 경비원은 직업이 없어요")
        }
      }
    }
  }
}

이렇듯 엄청 복잡하다. 이때 옵셔널 체이닝을 사용해보자!

func guardJobOptionalChaining(owner: Person?) {
  if let guardJob = owner?.home?.guard?.job {
    print("우리집 경비원의 직업은 \(guardJob)입니다")
  } else {
    print("우리집 경비원은 직업이 없어요")
  }
}

guardJobOptionalChaining(owner: zehye)

zehye?.home?.guard?.job   // nil

zehye?.home = apart
zehye?.home  // Optional(Apartment)

zehye?.home?.guard  // nil
zehye?.home?.guard = superman
zehye?.home?.guard  // Optional(Person)

zehye?.home?.guard?.name  // superman
zehye?.home?.guard?.job  // nil

zehye?.home?.guard?.job = "경비원"
zehye?.home?.guard?.job  // 경비원

nil 병합 연산자 (nil-coalescing operator)

옵셔널 체이닝을 사용하면 값이 할당되지 않은 애들은 무조건 nil을 반환하게 되는데, nil이 아닌 기본값을 설정하고 싶다면 nil 병합 연산자를 사용해준다.

이는 ?? 을 사용하는 것으로 ?? 앞의 값이 nil이라면 ?? 이후 값을 반환해달라 라는 의미이다.

var guardJob: String

guardJob = zehye?.home?.guard?.job ?? "슈퍼맨"
print(guardJob)  // 경비원

zehye?.home?.guard?.job = nil
guardJob = zehye?.home?.guard?.job ?? "슈퍼맨"
print(guardJob)  // 슈퍼맨