Swift

[Swift] Optional Unwrapping (4) - 옵셔널 체이닝 (Optional Chaining)

띵지니어 2024. 4. 19. 00:01

안녕하세요 띵지니어 😼 입니다.

이번 시간에는 닐 코얼레싱(Nil-Coalescing)에 이어
옵셔널 언래핑하는 방법  번째 방법을 소개하려 해요 바로바로
옵셔널 체이닝(Optional Chaining)에 대해 포스팅 해보려고합니다.

 

시작 전에

"체이닝"? 이 뭐죠?

아래와 같이 점(.) 문자로
객체, 메서드, 속성에 접근을 하는 것을
보통 체이닝(Chaining) 이라고 합니다.


본격적으로 시작해 볼게요

🍎 옵셔널 체이닝 (Optional Chaining)

요약하자면
옵셔널 값에 대한 안전한 접근을 연속적으로 수행할 때 사용 합니다.
즉 옵셔널 값이 nil일 수 있는 여러 프로퍼티, 메서드, 서브스크립트를 하나의 연속된 표현식 내에서 안전하게 호출하고,
표현식 중 하나라도 nil을 반환할 경우, 표현식의 실행이 멈추고 nil 을 반환합니다.

Optional Chaning

여기서 핵심은 체이닝 과정 중 어떤 하나의 표현식이라도 nil 을 반환하면 모든 체이닝이 중단된다는 겁니다.


예시를 들어볼게요!

 

위 예시에서
mj 의 여자친구의 이름을 구하려고 하면 어떻게 될까요?

보통은 이렇게 접근하지만 지금 mj 라는 표현식도 옵셔널 타입이고,
girlFriend 표현식 도 옵셔널 타입이니

 


이렇게 에러가 떠요!
그렇지만 에러를 눌러 Fix를 연달아해 준다면,

 

원하는 결과를 얻을 수 있어요!
위처럼 속성, 메서드, 서브스크립션 등 옆에 ?(물음표)를 붙이는걸
옵셔널 체이닝이라고 합니다.

강제 언래핑(Forced Unwrapping)! 과 비슷하죠?
근데 옵셔널 체이닝에서는 강제 언래핑을 사용하지 않아요!

오? 강제 언래핑이 되는데요?

 

근데 여기서 제가 여자친구와 헤어졌다면..?
그래서 girlFriendnil 이 된다면?

위처럼 에러가 발생합니다..

강제 언래핑 편에서 봤지만
! 연산은 옵셔널 값을 강제로 벗기는 연산인데
nil 을 벗길 순 없기 때문에
강제 언래핑은 웬만하면 지양❌❌ 해야 합니다!!

따라서 옵셔널 체이닝의 표현식은 ? 로 통일 합니다!!

그러면 아래와 같이

에러 없이 nil을 반환하게 됩니다!

저렇게 mj, girlFriend, name 하나라도 nil 이면
nil을 반환하는 아주 안전한 문법이에요

조금은 이해가 됐을까요?


 

🍎 옵셔널 체이닝의 특징을 알아보겠습니다.

 

1. 옵셔널 체이닝의 결괏값은 맨 마지막 표현식의 옵셔널을 씌운 타입이다.

⭐️⭐️ 결과는 항상 옵셔널 타입으로 리턴한다고 생각하면 됩니다.⭐️⭐️

예를 들어 아래처럼 변수에 대입했을 때 girlFriend의 타입은 아래와 같습니다.

엥? 아래 사진처럼
Girl의 name 속성은 String? 이 아닌데요?

 

왜냐하면 마지막 표현식의 앞에 나온 표현식들이 nil이라면
nil 값을 반환해줘야 하기 때문에
맨 마지막 표현식에는 옵셔널을 씌우고 반환을 하게 됩니다.

아래 그림처럼 이해하면 될 거예요

따라서 옵셔널 체이닝의 결과 타입은
마지막 표현식 타입에 옵셔널을 씌운 타입이다.

 

하나만 더 예시를 들어 보겠습니다.

 

이번엔 mj의 여자친구의 직업에 대해 접근을 해볼 거예요

엥? 옵셔널 체이닝은 ?(물음표) 로 접근한다면서요

여기서 알 수 있는 사실은 옵셔널 체이닝의 마지막 표현식은 옵셔널이든 아니든 ?를 생략해요

이유는 예를 들어 마지막 표현식 자제가 옵셔널이 아니라면 추가적인 ? 없이도 옵셔널 체이닝의 결과는 여전히 옵셔널이 되기 때문입니다.


 

2. 옵셔널 체이닝 과정에서 하나라도 nil이라면, 이어지는 표현식을 평가하지 않고 nil을 리턴한다.

이것도 무슨 소리 나면

mj 가 nil이면 이어지는 girlFriend, job의 표현식을 평가하지 않고 바로 nil을 리턴하고 종료해요

 


 

🍎 함수에서 사용하는 옵셔널 체이닝

이번에는 조금 다른 예시를 들고 올게요

1. ()?

함수 뒤에 함수()? 가 있는 경우는 뭔가요

-> 함수 리턴(결과) 값이 없을 수 있다.

즉 함수의 리턴값이 옵셔널인 경우 사용을 해요


 

2. ?()

그러면 앞에 ? 가 있는 경우는 뭔가요

-> 함수 자체가 옵셔널이다.

옵셔널 체이닝의 결과는 항상 뭐랬죠?? 옵셔널 타입!! ⭐️⭐️

뭐라고요?? ㅇㅅㄴ ㅌㅇ!!!! ⭐️⭐️

사진에서 보듯이 mj?. getJob 이라는 함수를 담은
job 상수 에는 (() -> Job)? 타입을 갖는 함수이기 때문에 
job?() 라는 모습을 볼 수 있습니다.


 

3. ?()?

위에서 본 것처럼
둘다 만족을 해야 해요!

1. 함수 자체가 옵셔널 타입
2. 함수의 리턴값이 옵셔널 타입
일 때 사용합니다.

 

따라서
job?()?.salary 이런 형태의 혼종이 등장하게 됩니다.

 


 

4. ?[]?

위 개념은 Dictionary에서도 볼 수 있습니다.
딕셔너리도 위 함수와 비슷하게 생각하면 됩니다.

참고로 딕셔너리에는 없는 값이 존재할 수 있기 때문에 
subscript 문법으로 접근하면 옵셔널로 리턴이 됩니다.

따라서 아래와 같은 dic에 접근을 하면
딕셔너리의 리턴값은 옵셔널이기 때문에 해당 값에
count라는 속성에 접근하면 옵셔널 체이닝으로 접근해야 합니다.


 

따라서 만약에 딕셔너리 자체가 옵셔널이라면
아래와 같이 ?[]? 이런 형태가 만들어질 수 있어요

 

 

참고 내용
https://babbab2.tistory.com/32

 

Swift) Optional 부수기 (6) - Optional Chaining (옵셔널 체이닝)

안녕하세요~~ 소들입니다 😎 휴~~ 오랜만에 다시 Swift 포스팅이네염~~~~ 이번엔 옵셔널 부수기의 마!지!막!편!인 바로 옵셔널 체이닝 이란 개념입니다 ;)))) 사실 마지막이 아닐 수도 있. ... 옵셔널

babbab2.tistory.com