본문 바로가기

Swift_Grammar

[Swift_Grammar] Optional

 

 

오늘은 Optional에 대해서 포스팅 하겠다.

 

Optional은 값이 있을 수도, 없을 수도 있음을 

나타내는 표현이다. ( 없는건 nil로 표현한다. )

 

변수나 상수 등에 꼭 값이 있다는 것을 보장할 수 없으며

그 값이 nil 일 수도 있다는걸 의미한다.

 

Int 타입 변수에 값이 0,

혹은 String 타입 변수에 값이 "" (빈 문자열) 이라고 가정할때

이 상황에서 해당 변수들의 값은 없는게 아니다.

단지 0이라는 값이 들어간,

빈 문자열 이라는 값이 들어간 변수 또는 상수인것이다.

 

그러니 nil 이라는 값과 혼동을 해서는 안된다.

let value1 = 0

let value2 = ""

 

 

nil은 Optional 타입에만 할당을 할 수 있다.

일반 타입에 nil을 할당 하고자 한다면 컴파일 에러가 발생한다.

var notOptionalValue = 1

notOptionalValue = nil // 컴파일 에러


var optionalValue: Int? = 1

notOptionalValue = nil 

 

 

그렇다면 Optional 변수에 왜 굳이 nil이 있음을 가정해야 하나

 

그에 대한 첫번째 대답은

어떠한 프로세스 안에서

잘못된 값으로 인한 접근으로 

앱이나 서버에 치명적인 손상을 일으킬수 있는 여지가 있다고 가정할때

nil이라는 값을 할당해줌으로써

Optional Binding 과정에서 더이상 진행되지 않고

return 하도록 유도하는데 있어

nil의 존재감이 많이 두드러질수 있다.

func someFunc(someValue: Int?) {
    if let value = someValue {
        print(value)
    } else {
        print("ERROR - someValue is nil")
    }
}

 

혹은

해당 Optional 값이 함수 내에서 사용될수도 있고 

그러지 않을 수도 있을때

 

한가지 예를 들자면

매개변수를 굳이 넘기지 않아도 될때

요런식으로 사용할 수도 있고 

이렇게 사용한다면 두번째 매게변수는 사용 안하는 매개변수로

다른 사람이 코드를 읽을때 쉽게 이해할수 있다.

func someFunc(notOptionalValue: Int, optionalValue: Int?) {
   ...
}

someFunc(notOptionValue: 1, optionalValue: nil)

 

 

또는 아예 매개변수의 기본값을 nil로 설정하여 

호출할때 생략을 해주는 방법도 좋은거 같다.

func someFunc(notOptionalValue: Int, optionalValue: Int? = nil) {
   ...
}

someFunc(notOptionValue: 1)

 

 

Optional의 정의를 살펴보자면

Enum으로 정의되어 있다.

간단하게 표현 하자면

두가지의 case가 있고

하나는 값이 없는,

다른 하나는 값이 있는 경우로 나눠진다.

그리고 타입이 제네릭으로 받고 있는걸 볼 수 있다.

즉 어떤 타입이든 받을 수 있으며

값이 있을 경우에는 some case의 associateValue로 값을 가지고 있는다.

enum Optional<T> {
    case none
    case some(T)
}

 

그리고 associateValue로 가지고 있는 값( Optional로 감싸저 있는 상태 )을 

우리는 Optional Unwrapping 으로 값을 추출하여 사용한다.

 

그에 대한 첫번째 방법은

강제추출이다.

이 방법은 가장 간단하면서도

런타임 오류가 일어날 가능성이 높기 때문에

가장 위험한 방법이다.

사용법은 Optional 값 옆에 !를 붙이면 끝이다.

 

Optional 값이 있는 상태였다면 

Optional을 벗긴상태로 사용할 수 있다.

하지만 nil일 경우 런타임 오류가 발생한다.

var somValue: String? = "hello"

print(someValue) // optional("hello")
print(someValue!) // "hello"

 

또 다른 방법은 Nil Coalescing 이라는 방법이다.

이방법도 간단하다.

만약 nil일 경우를 대비해

 ?? 를 붙히고 그 옆에 

nil일때 대체할 값을 넣어주면 된다.

var somValue: String? = nil

print(someValue ?? "nil임") // "nil임"

 

 

다음 방법은 if 와 guard를 사용하여 

해당 Optional 값이 nill인지 체크한 후 사용하는 방법이다.

var someValue: String? = "hello"

if let value = someValue {
    print(value)
} else {
    print("someValue is nil")
}
var someValue: String? = "hello"

func someFunc() {
    guard let value = someValue else { 
    print("someValue is nil")
    return 
    }
}

 

 

이렇게 Optional 과 Unwrapping 방법에 대해 알아봤는데

다수의 개발자들이 강제 Unwrapping 사용을 많이 지양한다고 한다.

아무래도 가장 무식한 Unwrapping이라는 이유 때문에 아닐까

 

그래도 많이는 아니지만

개인적으로 

개발 단계에서의 강제 Unwrapping을 조금씩 사용해보는건 괜찮다고 생각한다.

이유는 바로 runtime error 가 나오고 해당 error 코드를 알려주는데에 있어

디버깅 시간을 단축할 수 있다고 생각하기 때문이다. ( 지극히 개인적인 생각.. )

 

 

 

'Swift_Grammar' 카테고리의 다른 글

[Swift_Grammar] Property  (0) 2020.12.31
[Swift_Grammar] 구조체와 클래스  (0) 2020.12.30
[Swift_Grammar] 함수  (0) 2020.12.27
[Swift_Grammar] 흐름 제어 (2)  (0) 2020.12.25
[Swift_Grammar] 흐름 제어 (1)  (0) 2020.12.23