[Swift] Optional
Optional 은 해당 변수가 어떤 타입의 값을 가지고 있을 수도 있고, 혹은 nil 을 가지고 있을 수도 있다는 의미입니다.
Optional 의 구현부를 살펴보면 위와 같이 none 과 some(Wrapped) 라는 case 를 가진 열거형으로 구현되어 있습니다.
none 일 경우 nil 을 가지게 될 것이고, some(Wrapped) 는 Wrapping 된 어떠한 값을 가지고 있게 될 것입니다.
Optional 은 위처럼 두가지 방법으로 선언할 수 있지만, 대부분의 경우 타입 뒤에 ?
를 붙이는 방식을 선호하는 것 같습니다.
Optional 은 초기값을 할당해주지 않으면 nil 로 초기화됩니다. Optional 을 상수로 선언할 시 항상 nil 이 할당되며 해당 상수는 정상적으로 이용이 불가능합니다. 따라서 Optional 은 변수로 선언해주는 것이 안전합니다.
위 내용들은 다음과 같이 정리할 수 있습니다.
- case some 일땐 Wrapped Value 이거나, case none 일때 nil 인것을 나타내는 열거형
- 해당 변수는 nil 이 될수도, 아닐수도 있음
- 선언 시 타입 뒤에
?
를 붙이거나 Optional 와 같이 선언 - 초기값 할당하지 않을 시 nil 할당
nil 이란?
nil 은 타 언어의 Null 과 매우 유사하게 값이 없는 것을 표현합니다.
C 언어에서의 Null 은 포인터 값의 부재를 뜻하지만, Swift 에는 포인터가 존재하지 않습니다. 그래서 Objective-C 의 경우를 살펴보자면 nil 은
Objective-C : Objective-C 객체의 클래스 부재 , 존재하지 않는 객체에 대한 포인터를 뜻합니다.
Swift : Objective-C 객체의 부재 , 포인터가 아닌 특정 타입에 대한 값의 부재를 뜻합니다.
그렇다면 모든 타입을 뜻하는 Any 에는 nil 을 할당할 수 있을까? 라는 의문이 들 수 도 있습니다.
하지만 Any 로 선언된 배열에 nil 을 집어넣으려고 한다면 에러가 발생하는 것을 확인하실 수 있으실 겁니다.
nil 은 위에서 설명했듯이 특정 타입에 대한 값의 부재를 뜻하는데, Any 에 직접적으로 nil 을 할당하기에는 표현할 수 있는 타입이 존재하지 않기 때문에 이는 불가능 해집니다.
하지만 Optional 로 선언된 변수에 nil 이 할당되어 있는 경우는 Any 에 할당이 가능합니다.
Optional Binding
Optional 인스턴스를 이용하기 전, Unwrapping 하는 과정을 거쳐야 해당 값을 안전하게 사용할 수 있습니다.
if - let
if - let 구문을 이용하여 Optional Binding 을 진행하는 것은 다음과 같은 특징을 가집니다.
- if 이후 오는 상수/변수가 nil 인지 아닌지 체크
- nil 이 아니라면 if 내부 블럭 실행
- nil 이라면 else 내부 블럭 실행
- 선언한 상수/변수는 if 문 내부의 지역변수로만 사용 가능
guard - let
guard - let 구문을 이용하여 Optional Binding 을 진행하는 것은 다음과 같은 특징을 가집니다.
- guard 이후 조건이 false (nil) 인 경우 else 문 실행
- else 문이 실행될 때 상위 코드블럭을 종료해야함 (continue, break, return, throw 등..)
- 조건이 true 라면 guard 구문 다음 코드라인으로 이어서 실행
- 선언한 상수/변수는 guard 문 외부에서도 사용 가능
Optional Chaining
Wrapped Instance, 즉 Optional 인스턴스의 프로퍼티에 접근하려면 해당 프로퍼티 뒤에 Chaining Operator ?
를 붙여줘야 합니다.
이 때 값이 없다면 nil 을, 있다면 해당 값을 반환합니다.
또한 어떤 Optional 변수가 nil 일 때 다른 값을 할당해주고 싶다면 ??
연산자를 이용할 수 있습니다.
해당 변수 뒤에 ??
연산자를 붙이고 그 뒤에 대입하고자 하는 다른 값이나 변수를 적어서 사용이 가능합니다.
그리고 만약 어떤 Optional 변수가 현재 값을 가지고 있다고 확신할 수 있다면 해당 변수 뒤에 !
을 붙여줄 수 있습니다.
값이 제대로 들어가 있는 경우 Optional 이 아닌 해당 타입에 대한 값을 반환하지만, nil 이 들어가 있을 경우 런타임 에러가 발생하니 유의해서 사용해야 합니다.
Optional == non Optional ?
위와 같이 Optional 인 변수와 Optional 이 아닌 변수를 비교했을때 해당 비교 구문이 동작하는 걸 확인할 수 있습니다.
Optional 인 변수는 값이 있다고 할지라도 Wrapped 된 값이고, Optional 이 아닌 변수는 해당 타입에 대한 값을 그대로 가지고 있는데 이게 어떻게 가능한 것일까요?
Optional 에서 == 연산자가 정의된 곳을 찾아보면 알 수 있습니다.
간단하게 해석해보자면, Optional 과 non Optional 이 비교될때는 non Optional 인 값을 Wrapping 하여 둘 다 Optional 인 것처럼 비교한다고 합니다.
그렇기 때문에 둘이 가지고 있는 값을 이용해서 서로를 비교할 수 있는 것입니다.
참고 링크
https://developer.apple.com/documentation/swift/optional
'iOS 개발 > Swift' 카테고리의 다른 글
[Swift] Swift 언어가 가진 특징 (0) | 2022.08.17 |
---|---|
[TIL] Swift 에서 Array 를 탐색하는 방법들의 차이 (for in) (0) | 2022.07.17 |
[Swift] GCD & Dispatch Queue (2) | 2022.05.27 |
[Swift] 싱글톤 패턴 (Singleton Pattern) (0) | 2022.05.20 |
[Swift] 타입 캐스팅 (Type Casting) (0) | 2022.05.19 |