-
Swift - Optional, Forced-UnwrappingProgramming/Swift 2020. 10. 1. 17:18
오늘은 Optiona(옵셔널)에 대해서 같이 공부해봐요!
처음 Optional을 접한다면 많이 생소할 수 있습니다.
하지만 천천히 공부하며 이해하면 어렵지 않을 거예요!
Optional이란 값이 있을 수도 있고 없을 수도 있는 상태를 나타내는 단어입니다.
있을수도있고 없을수도 있으니 선택적(optional)이죠? Optional이라는 이름은 여기서 왔습니다.
값이 없을 수가 있나?? 상수나 변수를 만들 때 값을 무조건 다 저장하면 되는 거 아니야?? 이런 생각이 드실 수도 있습니다.
우리가 상수나 변수를 생성할 때는 값이 없는 상황을 만들지 않을 수 있습니다.
하지만 만약 네트워크를 통해 외부에서 값을 가져와 변수에 저장하는 상황을 생각해보죠. 인터넷 연결이 끊겨 값을 가져오지 못했거나 오류로 인해 값을 가져오지 못했다면 그 변수는 값이 없을 수도 있습니다.
그리고 만약 이때 일반적으로 접근을 하려 하면 '변수와 상수는 접근하기 전에 초기화가 돼있어야 한다'라는 전제조건에 의해 오류가 발생합니다.
Optional을 사용하면 값이 없을 때 오류를 발생시키지 않고 안전하게 처리할 수 있습니다.
그럼 "값이 없다."는 어떻게 나타낼까요? 그전에 먼저 "값이 있다"부터 보겠습니다.
num이라는 상수에는 Int Type의 12라는 값이 저장돼있습니다.
그렇다면 숫자에 값이 없는 건 0을 저장하면 될까요??
0도 값이기 때문에 0을 저장하는 것도 값이 없음을 나타내는 것이 아닙니다. 0이라는 값을 저장하고 있는 거죠.
값이 없다는 것을 나타내기 위해서는 nil이라는 Keyword를 사용합니다.
nil
nil은 "값이 없다"를 나타내는 Keyword입니다.
그럼 nil을 이용해서 값이 없음을 나타내 보겠습니다.
nil은 값이 없음을 나타낸다고 했죠?
그러므로 Type Annotation을 해주지 않으면 Swift는 이 상수나 변수가 어떤 Type인지 추론할 수 없습니다.
Int로 type annotation을 해보겠습니다.
이번에는 타입을 지정했는데도 에러가 발생했습니다.
에러 메시지를 읽어보니 Int에는 nil을 저장할 수 없다고 나옵니다.
Optional Type
지금까지 우리가 공부했던 Type은 모두 Non-optional Type 이었습니다.
Non-optional type에는 nil을 저장할 수 없습니다.
값이 없음을 나타내는 nil을 저장하려면 Optional Type으로 Type을 선언해줘야 합니다.
Optional Type은 우리가 사용했던 타입 뒤에?를 붙여주면 됩니다.
Optional Int Type에 nil을 저장해보겠습니다.
지금 optionalNum에는 값이 저장돼있지 않습니다.
그리고 값이 없는 상태에서 접근을 해도 에러가 발생하지 않았습니다.
그럼 optionalNum 변수를 다른 값으로 바꿔보겠습니다.
이번엔 100이라는 값을 저장했습니다.
그리고 optionalNum을 출력했는데 100이 아닌 Optional(100)이라는 값이 출력됐습니다.
100이랑은 다른 값일까요?? 여기에 다른 수를 더해보겠습니다.
100에 2를 더했는데 오류가 발생했습니다.
100이 아니라 Optional(100)이었죠?? 옵셔널 타입에 저장된 값을 사용하려면 반드시 Unwrapping을 해야 합니다.
어렵게 생각하지 말고 옵셔널 타입의 값을 사용하려면 옵셔널 포장지를 벗기고 사용해야 한다고 생각하시면 쉽습니다.
포장을 벗기는 것을 Unwrapping(추출)이라고 합니다.
Forced Unwrapping
추출하는 방법 중 한 가지로 Forced Unwrapping(강제 추출)이 있습니다.
강제 추출은 ForcedUnwrappingOperator(강제 추출 연산자)인 !을 사용합니다.
Optional Expression이란 코드를 평가했을 때의 결과가 Optional이라면 Optional Expression입니다.
위에 코드에서 optionalNum을 평가했더니 결과로 Optioanl(100)이 나왔죠? 그럼 optionalNum은 optional expression입니다.
강제 추출 연산자 !은 optionalexpression뒤에 붙여서 사용합니다.
Optional Type을 추출했더니 Non-optioanl type이 된 것을 확인할 수 있습니다.
그리고 추출된 값에 2를 더했더니 이번에는 오류가 발생하지 않고 정상적으로 102가 출력됐습니다.
optionalNum!은 Int type이죠?
이제 더 이상 optioanl expression이 아닙니다. 그러므로 추출한 값을 또 한 번 더 추출할 수 없습니다.
주의해야 할 점
Optional type에 저장된 값을 사용하기 위해선 추출을 한 후에 사용해야 했습니다.
만약 nil을 추출하면 어떻게 될까요??
Optional Type에 nil이 저장되어 있는데 이를 강제 추출하면 Fatal error가 발생합니다.
값을 사용하기 위해 추출을 하는데 값이 없음을 추출한다.
앞뒤가 안 맞는 말이죠?? 이렇게 강제 추출을 할 때 조심해야 하는 부분은 nil을 추출하는 경우입니다.
IUO(Implicitly Unwrapping Optionals)
IUO는 자동으로 추출되는 옵셔널입니다.
옵셔널 타입은 Type?으로 생성했습니다. IUO는 Type!으로 생성합니다.
iuoNum 변수를 Int! Type으로 선언했습니다.
그리고 새로운 상수 a에 iuoNum을 할당했습니다.
IUO는 자동으로 추출된다고 했죠?
그런데 a의 타입을 확인해보니 옵셔널입니다.
자동으로 추출되지 않았습니다.
IUO는 TypeInference로는 자동 추출되지 않습니다.
자동 추출을 하기 위해서는 Type Annotation을 이용하여 명시적을 Type을 지정해줘야 합니다.
새로운 상수 b의 타입을 Int로 선언하고 iuoNum을 할당했습니다.
그리고 타입을 확인해보니 자동으로 추출되어 Int Type이 된 것을 확인할 수 있습니다.
IUO도 Forced Unwrapping입니다.
IUO를 생성할 때 Type!을 사용했죠?
어디서 많이 본 Postfix Operator입니다.
IUO도 추출을 할때 강제 추출을 사용합니다.
그렇기 때문에 nil을 저장하고 자동으로 추출하게 되면 Fatalerrorr가 발생하게 됩니다.
이제 오늘 공부한 내용 중에 가장 중요한 부분입니다!!!
Foced unwrapping과 IUO는 개념만 알아두고 사용하지 않는 것이 좋습니다.
추출을 해야 한다면 다음 포스팅에서 공부할 Optional Binding을 사용하도록 합시다.
참고자료
https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html
728x90'Programming > Swift' 카테고리의 다른 글
Swift - Function Basic (0) 2020.10.06 Swift - Optional Binding, Nil-coalescing Operator (0) 2020.10.05 Swift - Control Transfer Statements (0) 2020.10.01 Swift - Loop Statements (0) 2020.09.30 Swift - Conditional Statement (if, switch, guard) (0) 2020.09.29