iOS 개발/Swift

[Swift] Optional

도지대디 2022. 7. 4. 02:08

[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

 

Apple Developer Documentation

 

developer.apple.com

https://seolhee2750.tistory.com/10

 

[Swift] nil 정리 (feat.NULL)

스위프트를 시작하고 nil이란 단어를 처음 들어봤는데, 그냥 NULL이랑 비슷해보였다,, 근데 자세히 찾아보니 NULL과는 엄연히 다른것이라는 것이라는 것,,이라는,,,, 그래서 이번에는 NULL과의 차이

seolhee2750.tistory.com

https://velog.io/@yohanblessyou/short-%EC%97%B0%EC%82%B0%EC%9E%90operator%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%A0%95%EC%9D%98%EB%90%98%EB%8A%94%EA%B1%B8%EA%B9%8C

 

[75%] Optional과 non-Optional 타입 간 연산자(operator)를 사용할 수 있는 원리

Swift에서 Optional 타입과 non-Optional 타입 간 비교연산자(==, != 등)를 사용할 수 있음을 알았습니이전 포스팅 : Optional과 non-Optional은 별도의 Binding없이 비교할 수 있다이번 포스팅에서는 Swift에서 연

velog.io