안녕하세요~~ 소들입니다 😎
휴~~ 오랜만에 다시 Swift 포스팅이네염~~~~
이번엔 옵셔널 부수기의 마!지!막!편!인 바로
옵셔널 체이닝
이란 개념입니다 ;))))
사실 마지막이 아닐 수도 있. ... 옵셔널 패턴이란 것도 있.......ㅎ
쨌든..~~~ 이 개념까지 이해 한다면 이제 스위프트 옵셔널은 거의 다 안다고 봐도 무방해여!!!
코로나니까 수다 그만 떨고
바로 본론으로 고고!
1. 옵셔널 체이닝이란?
자 먼저 옵셔널 체이닝 개념부터!
Chaining의 뜻이 "연쇄" 이듯이
옵셔널 체이닝은 말 그대로
옵셔널을 연쇄적으로 사용하는 것임
어떻게?
이런 식으루!
위와 같은 유형의 코드를 많이 봤을 것이셈!!
.(dot)을 통해 내부 프로퍼티나 메서드에 연속적으로 접근할 때
옵셔널 값이 하나라도 껴 있으면
그것은 옵셔널 체이닝임
(따라서 위 코드 두개 모두 옵셔널 체이닝임)
만약 하나라도 안 껴 있으면?
그럼 옵셔널 체이닝이 아닌 것임
오키!??????
1-1. 예제로 살펴보기
자 다음과 같은 구조체가 있음
그리고 다음과 같이
옵셔널 Person 타입인 sodeul 이란 변수를 선언 했음
그리고 이제 sodeul.contacts.email 에 접근해 보겠음
그럼 다음과 같이 쓸거잖음?!
그러면 이렇게 에러뜸.. 왜냐? sodeul은 옵셔널 타입이거든..
만약 sodeul이 nil이면 어떡할라구 그 안에 멤버에 접근한단 말임?
저렇게 컴파일 에러라도 내줬으니 다행이지 만약 안내준다면 런타임 에러로 떨어졌을 거임 ;ㅁ;
따라서 저 옆에 에러를 눌러주면
이렇게 바뀌면서 에러가 사라짐
이게 바로 옵셔널 체이닝임
옵셔널 표현식의 멤버에 접근할 때, 표현식이 nil일 수 있으니 ?를 써주는 것임
그래 만약 nil일 수 있으니 ?로 접근해야 한댔음
그럼 nil일 경우엔 어떻게 될까
nil이 반환됨 ㅎㅎㅎㅎㅎ
만약 sodeul, contacts, email 중 단 하나의 표현식이라도 nil이라면 결과값은 nil임
엥 다음과 같이 !를 써도 접근 되는데염?
이것도 옵셔널 체이닝임?
ㄴㄴㄴ
여기서 !는 옵셔널 체이닝이 아니라
옵셔널 강제 해제 연산임
따라서 다음과 같이 sodeul이 nil인 경우엔
강제해제 연산자 !는 앱 만들 땐 웬만해선
쓰지 ... ㅁ... ㅏ......
2. 옵셔널 체이닝의 특징
옵셔널 체이닝의 가장 큰 특징만 알고 가겠음
이것만 제대로 알아도 옵셔널 체이닝은 껌임
2-1. 옵셔널 체이닝의 결과값의 타입은 마지막 표현식의 옵셔널 타입이다
이해가 안갈테니 예제로 설명하겠음
먼저, 옵셔널 체이닝의 sodeul, contacts, email의 타입은 다음과 같음
표현식 |
타입 |
sodeul |
Person |
contacts |
Contacts |
|
String |
근데 반환값 email을 확인해보면
마지막 표현식 email 타입에 옵셔널을 씌운 Optional String ~~~~
뭐 그렇다는 얘기
헤에에에엑!!!!
email은 옵셔널이 아닌 일반 String인데 왜 반환값은 옵셔널 String 타입이지!!!!!!!!!!!!!!!!!
내가 원하는 email에 닿기 전에 sodeul이가 nil이면 그냥 nil을 뱉어버리기 때문이지.....
이런 가능성 때문에 옵셔널 체이닝의 반환값은 무족권 옵셔널 타입임
헤에에에에에엑!!!1
만약 sodeul이 nil이라서 nil이 반환 되어도 반환값은 맨 마지막 표현식 타입임?
ㅇㅇ..
어떤 조건이든 옵셔널 체이닝의 결과값은 무족권 마지막 표현식의 옵셔널 타입임
2-2. 옵셔널 체이닝의 마지막 표현식은 옵셔널이더라도 ?를 생략한다
자 다음과 같이 구조체를 바꿔주겠음
이거처럼 email의 변수를 옵셔널 String으로 바꿔줬음
그럼 옵셔널이니까 접근할 때 옵셔널 체이닝에 의해 ?를 써줘야 할 거 같잖음?
응 에러남~_~
왜냐???????????
옵셔널 체이닝의 마지막 표현식은 옵셔널이든 아니든 ?를 생략함
따라서 다음과 같이 지워주면
에러 안 나여~~_~~
근데 만약~~ email 이란 변수의 속성에 또 접근한다??
그럼 다시 써주면 됨 ㅎㅇㅎ
왜냐? email이 더이상 마지막 표현식이 아니기 때문 ~..~
2-3. 옵셔널 체이닝의 표현식 중 하나라도 nil이라면, 이어지는 표현식은 평가하지 않고 nil을 리턴한다
이거도 예제로 보면 간단함
자 이런 경우에 옵셔널 체이닝의 첫 표현식 sodeul이 nil이잖음?
그러면 다음과 같이
다음에 오는 contacts, email 표현식을 평가하지 않고 바로 nil을 리턴하며 종료한단 말
호홋
3. 함수가 껴있는 옵셔널 체이닝
3-1. ()?
Person 구조체에 getContacts라는 함수를 만들었음
그리고 이 함수의 리턴값으로 얻은 contacts의 email 값에 접근하려 함
그럼 다음과 같이
함수의 리턴 값이 Optional인 경우엔 함수를 호출하는 () 뒤에 ? 를 붙여주면 됨
() 뒤에 ?가 붙는 경우는 함수의 리턴 값의 속성에 접근할 때임
3-2. ?()
함수 호출 () 앞에도 ?가 붙을 수 있음돠
그 경우는 바로바로 함수 자체가 옵셔널인 경우 임
자 이렇게 getContacts의 리턴 값을 Non-Optional Type으로 지정 했음
이처럼
리턴 타입이 Non-Optional Type 이며
getContacts 함수를 담은 function이란 상수는 Optional Type인 경우
그때 이렇게 사용함
3-3. ?()?
그럼 ?()? 이건 언제 쓰느냐
이건 다음과 같이 함수 자체도 옵셔널이고, 리턴 값도 옵셔널일 때임
자 다시 원복해서, getContacts 함수의 리턴값을 Optional Type으로 지정 했음
이처럼
리턴 타입이 Optional Type 이며
getContacts 함수를 담은 function이란 상수가 옵셔널 타입인 경우
다음과 같이 ?()? 이런 모양이 나오게 됨
① ?() function이란 함수가 먼저 optional인지 아닌지 체크해주고
② ()? function 함수가 옵셔널이 아니라면 리턴값이 옵셔널인지 아닌지 체크해 주는 것임
4. 딕셔너리가 껴있는 옵셔널 체이닝
이거도 함수랑 같은 선상임
함수로 자세히 설명 했으니 딕셔너리는 간단하게 설명 하겠음
4-1. []?
자 이런 딕셔너리가 있을 때
name이라는 키 값에 접근 해서, 그 value 값을 count 할 것임
그럼 이때 []? 를 사용하는 것임
왜냐? 딕셔너리에서 key 를 통해 value를 얻을 땐
해당 key가 없을 수도 있기 때문에 무조건 Optional Type이 return 됨
따라서 딕셔너리의 key 값으로 얻은 value 값의 속성에 접근 할 때에는 []? 를 사용함
근데 이것은 Framework 자체가 무조건 옵셔널 타입을 리턴하는 지라,
이처럼 value 값의 속성에 접근할 땐 무조건 옵셔널 체이닝을 해줘야 함
4-2. ?[]?
이제 감 왔을 거라 믿어 의심치 않음
함수와 마찬가지로
딕셔너리 타입 자체가 옵셔널인 경우엔
이렇게 접근해줘야 함
① dic이 nil인지 아닌지 체크 하고
② key "name"으로 얻은 value 값이 nil인지 아닌지 체크 하고
.
.
크아ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ
드디어 길고 긴 옵셔널 포스팅이 끝났어요 짜까ㅉㄲ짜까짞!~~~~
이번엔 정말 쉽게 풀어썼다 생각했는데
혹시나 모르거나 틀린 부분 있음 댓글 꼭 주세엽 :D
좋은 하루 되시길
'iOS > Swift' 카테고리의 다른 글
Swift & Objective-C) Closure와 Block의 차이점 (9) | 2020.11.06 |
---|---|
Swift) String에 대한 고찰 (1) - Struct인데 Heap에 저장 된다고? (8) | 2020.10.07 |
Swift) 튜플(Tuple)에 대해 알아보자 (4) | 2020.09.22 |
Swift) Optional 부수기 (5) ?? 연산자 (Nil-Coalescing Operation) (4) | 2020.08.03 |
Swift) Optional 부수기 (4) Optional Unwrapping - IUO (옵셔널 묵시적 추출) (5) | 2020.08.03 |