오늘은 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 |