<aside> 💡 옵셔널 체이닝(Optional Chaining)은 Swift 언어에서 옵셔널 타입의 변수나 상수를 사용할 때, 옵셔널이 nil일 경우에도 안전하게 속성이나 메서드를 호출할 수 있는 방법을 제공합니다.

옵셔널 체이닝을 사용하면 옵셔널 값이 nil인 경우에도 코드가 크래시되지 않고 안전하게 실행됩니다. 옵셔널 체이닝을 사용하면 코드를 보다 안전하고 간결하게 작성할 수 있습니다.

옵셔널 체이닝은 ? 연산자를 사용합니다. 예를 들어, optionalValue?.property와 같은 형태로 사용할 수 있습니다. 이 코드는 optionalValue가 nil이 아닌 경우, property를 호출합니다. optionalValue가 nil인 경우에는 프로퍼티 호출을 무시하고 nil을 반환합니다.

옵셔널 체이닝을 사용하여 메서드도 호출할 수 있습니다. 예를 들어, optionalValue?.method()와 같은 형태로 사용할 수 있습니다. optionalValue가 nil인 경우 메서드 호출을 무시하고 nil을 반환합니다.

옵셔널 체이닝을 사용하면 중첩된 옵셔널 값에도 적용할 수 있습니다. 예를 들어, optionalValue?.property1?.property2?.method()와 같은 형태로 사용할 수 있습니다. 이 코드는 optionalValue가 nil이 아니고, property1이 nil이 아니고, property2가 nil이 아닌 경우, method를 호출합니다. 이렇게 중첩된 옵셔널 값에 대해서도 옵셔널 체이닝을 사용하면 코드를 더욱 간결하고 안전하게 작성할 수 있습니다.

옵셔널 체이닝을 사용할 때는 주의해야 할 점도 있습니다. 옵셔널 체이닝으로 호출한 값은 항상 옵셔널 값으로 반환됩니다. 따라서, 옵셔널 체이닝으로 값을 가져온 후에는 값이 nil인지 확인하고, 옵셔널 바인딩 등의 방법을 사용하여 옵셔널 값을 해제해주어야 합니다.

</aside>

Chaining 뜻은 “연쇄”라는 뜻으로 말 그대로 옵셔널을 연쇄적으로 사용하는 것!

person.contacts?.address
person?.contacts?.address

person.contacts.address // X 옵셔널 체이닝이 아니다.

점문법 (.)을 통해 내부 프로퍼티나 메서드에 연속적으로 접근할 때 옵셔널 값이 하나라도 있다면, 그것은 옵셔널 체이닝이다. 위 코드는 모두 옵셔널 체이닝

struct Contacts {
		var email: String
		var address: [String: String]
}

struct Person {
		var name: String
		var contacts: Contacts

		init(name: String, email: String, address: String) {
				self.name = name
				contacts = Contacts(email: email, address: ["home" : address]
		}
}

var sodeul: Person? = Person(name: "SodeulSodeul", 
														 email: "[email protected]", 
														 address: "Seoul")

옵셔널 Person타입인 sodeul 이라는 변수를 선언했다. 이제 sodeul.contacts.email 에 접근하려고 이렇게 작성할 경우 에러가 뜬다 왜냐하면 sodeul 은 옵셔널 타입이기때문이다. 만약 sodeul이 nil 일 수도 있기 때문이다. sodeul?.contacts.email 이렇게 작성을 해주면 된다. 만약 nil 인 경우에는 어떻게 될까?

sodeul = nil   // nil
sodeul?.contacts.email   // nil

sodeul, contacts, email 중 단 하나의 표현식이라도 nil이라면 결과값은 nil이 반환됨

옵셔널 강제 해제 연산을 작성한다면?

sodeul!.contacts.email

접근은 가능하다 강제해제 연산자 !는 지양하는걸로..

optional chaining의 특징

어떤 조건이든 옵셔널 체이닝의 결과값의 타입은 마지막 표현식의 옵셔널 타입이다

let **email** = sodeul?.contacts.**email
       \\ Optional(email.type) /** 

type(of: email)  // Optional<String>.Type

email 은 옵셔널이 아닌 일반 String 인데 반환깂이 Optional<String> 인 이유는?

sodeul = nil   // nil
let email = sodeul?.contacts.email   // nil