article thumbnail image
Published 2020. 9. 23. 20:25
728x90
반응형

스위프트에서의 핵심 개념이라고 하는 옵셔널에 대해서 공부해보았다.
다른 프로그래밍 언어에서는 찾아볼 수 없는 개념이기 때문에 다소 생소했다.
정확히 이해하고 다루는 데까지 시간이 좀 걸리지 않을까 생각한다.

1. Optional | 옵셔널

옵셔널, 그대로 해석해보면 '선택적인' 이라고 해석할 수 있다.
스위프트에서는 '있을 수도, 없을 수도 있다' 는 것을 뜻한다.
옵셔널이 아닌 변수에 nil 값을 할당하려고 하면 아래와 같이 컴파일 오류가 발생한다.
그리고 옵셔널 타입을 사용하라고 "?"를 추가하라고 한다.

간단하게 생각해보면 옵셔널을 사용해서 값이 있는지 없는지 알 수 있다는 것이고
옵셔널이 아니라면 값이 꼭 있어야 한다는 것이다. 옵셔널이 없다면 확인해본 것과 같이 에러가 발생한다.
nil 의 값을 가지려면 옵셔널 타입을 추가해주어야 한다는 것.
(nil 은 다른 언어에서의 Null 과 같이 값이 없다는 것을 뜻한다.)

그리고 옵셔널의 기본 값은 nil 이다.
변수에 아무것도 없다면 nil을 반환해주게 되는데 nil 이 나오는 이유는 nil 도 메모리를 차지하고 있기 때문이라고 한다.

var opVal: Int?
print(opVal)

==================== 출력 결과 ====================
nil

 

2. 옵셔널을 쓰는 이유

그럼 옵셔널은 왜 필요한걸까?

1. 명시적 표현
- 옵셔널은 nil의 가능성을 명시적으로 표현
- nil 가능성을 문서화 하지 않아도 코드만으로 충분히 표현 가능
- 문서와 주석 작성 시간을 절약

옵셔널을 사용해야만 값이 없을 수도 있다는 사실을 알 수 있기 때문에
옵셔널을 사용하는 것만으로도 충분히 nil 에 대한 표현이 가능하다. 그래서 시간을 절약할 수 있다.

2. 안전한 사용
- 전달 받은 값이 옵셔널이 아니라면 nil 체크를 하지 않더라도 안심하고 사용
- 예외 상황을 최소화 하는 안전한 코딩
- 효율적인 코딩

옵셔널을 사용해야만 nil 을 표현할 수 있기 때문에 옵셔널이 아니라면 nil 체크를 하지 않고 사용해도 된다.
기본적인 변수들은 nil 의 값을 가질 수 없기 때문에 컴파일 에러에서 nil 의 예외적인 상황들에 대해 미리 예방할 수 있고
그렇기에 안전하고 효율적인 코딩이 가능해진다.

어느정도 이해는 가지만 참고해놓은 포스팅에서 더 자세하게 그리고 더 이해하기 쉽게 설명해주셨기 때문에
참고하면 좋을 것 같다.

3. 옵셔널 문법과 선언

옵셔널은 enum + generics 라고 열거형과 제네릭의 조합이라고 하는데 나중에 알아보기로 하자.
옵셔널은 다음과 같이 선언할 수 있다고 한다.

enum Optional<Wrapped>: ExpressibleByNilLiteral {
    case none
    case some(Wrapped)
}

// 완전한 문법
let optionalValue: Optional<Int> = nil
// 물음표로 표현 가능
let optionalValue: Int? = nil

완전한 문법으로 Optional<Int> 라고 선언할 수 있지만, 물음표  "?" 를 통해서 선언해줄 수 있다고 한다.

4. 옵셔널 표현 | 물음표(?) 와 느낌표(!)

옵셔널을 어떻게 표현할 수 있을까? 물음표(?)느낌표(!) 를 통해서 표현할 수 있다고 한다.

느낌표 " ! ". 를 이용한 암시적 추출 옵셔널 | Implicitly Unwrapped Optional

var optionalValue: Int! = 100

switch optionalValue {
case .none:
    print("This Optional variable is nil")
case .some(let value):
    print("Value is \(value)")
}

==================== 출력 결과 ====================
Value is 100

느낌표를 사용한 옵셔널은 기존 변수처럼 사용이 가능하고 nil을 할당할 수 있다.

var optionalValue: Int! = 100

// 기존 변수처럼 사용 가능
optionalValue = optionalValue + 1
print(optionalValue)

// nil 할당 가능
optionalValue = nil
print(optionalValue)

// 잘못된 접근
optionalValue = optionalValue + 1
print(optionalValue)

==================== 출력 결과 ====================
Optional(101)
nil
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file study10.playground, line 46

nil 의 값에 1 을 더해줄 수 없기 때문에 런타임 오류가 발생한다.

 

물음표를 이용한 " ? " 일반적인 옵셔널 | Optional

var optionalValue: Int? = 100

switch optionalValue {
case .none:
    print("This Optional variable is nil")
case .some(let value):
    print("Value is \(value)")
}

==================== 출력 결과 ====================
Value is 100

물음표를 사용한 일반적인 옵셔널의 경우 
nil 의 값을 할당할 수 있지만, 기존 변수처럼 사용할 수 없다고 한다.

var optionalValue: Int? = 100

// 기존 변수처럼 사용 불가
optionalValue = optionalValue + 1
print(optionalValue)

==================== 출력 결과 ====================
error: study10.playground:62:17: error: value of optional type 'Int?' must be unwrapped to a value of type 'Int'
optionalValue = optionalValue + 1
                ^

 

5. 정리

이렇게만 보면 옵셔널이 무엇인지 잘 이해가 되지 않는다.
물음표와 느낌표를 통해서 사용한다고 하는데 왜 물음표와 느낌표를 나누어서 사용하지? 라고 생각할 수 있다.
아래의 참고 사이트에 있는 Zedd 님이 너무 자세하고 친절하게 정리해주신 포스팅을 통해 직접 확인해면서 정리해보았다.

우선, 물음표를 통한 옵셔널 표현
옵셔널 타입을 정해주었으니 nil 의 값을 가지게 된다.
변수에 값이 있으면 값을 출력하게 되고 없으면 nil 을 출력하게 된다.

변수인 someOptional 을 물음표를 사용한 옵셔널로 선언하고 다른 하나의 변수인 Value를 선언해서 someOptionl 을 넣어주었다.
그런데 타입을 가지지 않는 변수는 옵셔널 타입의 변수가 되어 someOptional 의 값을 가지게 되었다.
Value 는 옵셔널 타입이 되었구나 확인할 수 있었다.

그리고 Int 타입의 Value2에도 someOptional 의 값을 넣어주었더니 에러가 발생했다.
Int 와 Int? 는 다른 타입이란 걸 직접 확인할 수 있었다.

다음으로는 느낌표를 통한 옵셔널 표현
언래핑? Unwrapping , 풀어준다는 뜻을 가지는데 옵셔널 타입의 변수에 들어있는 값을 풀어 가져온다는 것 같다.
위에서 예를 들었던 Value2 에 느낌표를 사용한 someOptional 의 값을 넣어주었더니 에러가 발생하지 않았다.

에러가 발생하지 않았다. 뭐지...?
값을 가져올 수 있었던 이유? 옵셔널 타입이었던 someOptional 이란 변수를 풀어서, Unwrapping 해서 값을 가져왔다는 말이다.
다행히 someOptional 은 Int 타입을 가지고 있었기 때문에 Value2 에는 someOptional 의 값이 들어가게 된다.

Unwrapping 해서 someNil 의 값을 가져오지만 someNil 의 값은 nil 이기 때문에
Int 타입의 Value3 는 nil의 값을 가질 수 없어 에러가 발생한다.

이러한 이유에서 느낌표를 사용할 때 조심해서 사용해야 한다고 한다.
그리고 옵셔널을 사용할 때에는 초기화를 해주지 않으면 nil 의 값을 가지기 때문에
느낌표를 사용할 때 옵셔널의 값이 nil 의 값이 아니라는 것이 확실해야 한다고 한다.

생각보다 어려운 내용이라 여기저기 찾아가며 공부해보았는데
어느 정도의 옵셔널에 대한 틀이 잡혔다고 생각한다. 직접 사용해보면서 익숙해져야 할 것 같다.

 

- 참고 사이트 - 

www.edwith.org/boostcamp_ios/lecture/11240

 

[LECTURE] 11. 옵셔널 : edwith

:: 옵셔널 :: 1. 옵셔널이란?? 값이 있을 수도, 없을 수도 있음을 표현 nil이 할당 될 수 있는지 없는지 표현 // someOptionalParm에 nil이 할당 될 수 ... - 부스트코스

www.edwith.org

monibu1548.github.io/2018/05/12/swift-optional/

 

[Swift] Optional이란? 옵셔널 이해하기 - JingyuJung's Blog

Optional Swift가 갖는 Optional이라는 개념은 변수의 값이 nil일 수 있다는 것을 표현하는 건데요, 반대로 Optional이 아니라면(non-optional) 해당 값은 nil이 될 수 없음을 의미합니다. Objective-C를 사용해왔��

monibu1548.github.io

zeddios.tistory.com/16

 

swift3 ) Optional 개념 정리

안녕하세요 :) 오늘은 Optional이 뭔지에 대해 정리해볼려고해요. 이것도 yagom님이 BoostCamp강의에서 설명을 엄청 잘해주셨답니다 :) yagom님 강의를 토대로 추가할 부분은 추가해가면서 정리해볼게요

zeddios.tistory.com

 

728x90
반응형

'iOS > Swift' 카테고리의 다른 글

[Swift] 12. 구조체(struct) 기본  (0) 2020.10.18
[Swift] 11. 옵셔널 추출 (Optional Unwrapping)  (0) 2020.10.08
[Swift] 9. 반복문 (for-in, while, repeats-while)  (0) 2020.09.16
[Swift] 8. 조건문  (0) 2020.09.16
[Swift] 7. 함수 고급  (0) 2020.09.15
복사했습니다!