티스토리 뷰

Swift

[Swift] Optional(옵셔널)

희철 2022. 7. 7. 14:19

옵셔널이란?

값이 있을 수도, 없을 수도 있음을 나타내는 표현. 즉, 변수나 상수의 값이 nil일 수도 있다는 의미이다.

 

※ nil이란?

 

값이 없는 것을 의미하는데, 주의할 것은 0, ""(빈 문자열) 등의 값들도 하나의 값이므로 nil이라고 생각하면 안된다.

 

또한 nil은 옵셔널로 선언된 곳에서만 사용할 수 있다. 아래의 예시를 보자.

String과 String? 타입은 철저히 다른 타입으로 취급되며, 옵셔널타입으로 선언된 변수에만 nil이 사용되는 것을 볼 수 있다.

______________________________________________________________________________________________________

 

그렇다면 언제 옵셔널을 사용하며, 옵셔널을 사용할까.

 

가장 간단한 예시로 오류를 들 수 있다.

 

심각한 오류가 아니라는 가정하에 우리는 옵셔널을 사용해 메서드를 제대로 처리하지 못했을 경우, nil을 반환함으로써 알려줄 수 있다.

즉, 프로그래밍 언어 차원에서 안정성을 최대한 높이기 위해 사용한다.

 

옵셔널의 구성

옵셔널의 정의를 보면 열거형으로 되어있다.

 @frozen는 처음보는 것이라 찾아보았더니 나중에 새로운 case가 추가되지 않는 것을 약속하는 의미라고 한다.

 

아무튼 정의를 보면 ExpressibleByNilLiteral이란 프로토콜을 따르며 값을 갖는 케이스와 갖지 않는 케이스 두 가지로 정의되어 있는 것을 볼 수 있다.
즉, nil인 경우엔 none케이스가 될 것이고, 값이 있는 경우엔 some케이스가 될 것이다.

 

이때는 연관 값이 Wrapped에 값이 할당된다. 위 두 가지 케이스를 이용하여 switch구문으로도 some의 값을 추출할 수 있을 것이다.

옵셔널의 기본 정의가 열거형이므로 위처럼 switch구문을 이용해서 값이 있는 지 확인할 수 있다.

하지만 매번 이렇게 확인한다면 불편하므로 더욱 편리하고 옵셔널의 값을 옵셔널이 아닌 값으로 추출하는 법을 알아보자.

 

옵셔널 추출

 

옵셔널 값을 추출하는 방법에는 강제 추출, 옵셔널 바인딩, 옵셔널 체이닝, 암시적 추출 옵셔널 이렇게 네 가지로 생각해볼 수 있다.

 

마지막에도 말하겠지만 이 중에서 옵셔널 바인딩이나 옵셔널 체이닝을 사용하는 것이 상대적으로 더 안전하다.

- 강제 추출

옵셔널의 값을 추출하는 가장 간단한 방법이다. 하지만 이름에서도 느낄 수 있듯이 위험한 방법이다.

 

값을 쉽게 추출하긴 하지만 런타임 오류가 날 가능성이 가장 높기 때문이다.


방법은 옵셔널 값의 뒤에 느낌표만 붙여주면 된다. 이때 옵셔널에 값이 없다면 바로 런타임 오류가 발생한다.

최대한 지양하는 것이 좋지만, 값이 확실히 있는 경우엔 써줘도 될 것 같다.

 

- 옵셔널 바인딩

 

※ 바인딩이란?

"바인딩(binding)이란 프로그램에 사용된 구성 요소의 실제 값 또는 프로퍼티를 결정짓는 행위를 의미한다." 

강제 추출보다 조금 더 안전한 방법으로 옵셔널에 값이 있는지 확인할 때 사용한다.


만약 옵셔널에 값이 있다면 추출한 값을 일정한 블록 안에서 상수나 변수로 할당해주어 옵셔널이 아닌 형태로 사용할 수 있도록 해준다.주로 if나 while문 등과 결합하여 사용할 수 있다. 

만약 여러 옵셔널의 값을 추출하는 경우엔 쉼표를 이용하여 나열해주면된다.

 

하지만 이때 바인딩하려는 옵셔널 중 하나라도 값이 없다면 그 블록 안의 내용들이 실행되지않는다. 

 

- 옵셔널 체이닝

체이닝이란 단어에서 유추할 수 있듯이 옵셔널 체이닝은 옵셔널을 반복 사용하여 옵셔널에 값이 있는지 연속적으로 확인하는 방법이다.


다만, 체인의 한 부분이 고장나면 전체가 작동하지 않듯이 중첩된 옵셔널 중 하나라도 값을 갖고 있지 않다면 결과적으로 nil을 반환한다.

 

옵셔널 체이닝은 프로퍼티나 메서드 또는 서브스크립트를 호출하고 싶은 옵셔널 변수나 상수 뒤에 물음표를 붙여 표현한다.

 

이때 옵셔널이 nil이 아니라면 정상적으로 호출될 것이다. 하지만 결과적으로 nil이 반환될 수도 있으므로 옵셔널 체이닝의 반환값은 항상 옵셔널이다.

roomCount를 선언할 때 옵셔널 체이닝이 사용된 것을 볼 수 있다.
즉, residence가 nil을 반환할 수 있는 가능성이 있기 때문에 ?표시가 붙은 것이다.

 

직접 해보면 알 수 있겠지만 물음표를 직접 입력하지 않아도 자동으로 생기게 된다.

 

위의 코드를 보면 따로 초기화를 안했으므로 nil로 초기화가 되어있을 것이다. 따라서 위의 코드에서 else부분이 실행되는 것을 볼 수 있다. if문을 실행하고 싶다면 hee.residence = Residence()를 추가해주면 될 것이다. 

 

- 암시적 추출 옵셔널

때때로 nil을 할당하고 싶으면서, 로직 상 런타임 오류가 발생하지 않을거라는 확신이 있을 때 사용하는 방법이다.

옵셔널을 표시할 때 타입 뒤에 ?를 썼다면 암시적 추출 옵셔널은 타입 뒤에 느낌표를 사용해주면된다.
일반 값처럼 사용할 수 있으며 여전히 옵셔널이기 때문에 nil도 할당해줄 수 있다.

'Swift' 카테고리의 다른 글

[Swift] ARC에 대해서 알아보자  (0) 2022.10.18
[Swift] 접근 제어  (0) 2022.08.28
[Swift] 튜플(Tuple)  (0) 2022.06.10
[Swift] 진수 변환(radix)  (0) 2022.06.06
[Swift] 순열과 조합(Permutation / Combination) 구현해보기  (0) 2022.05.10
댓글
최근에 올라온 글
Total
Today
Yesterday