[오늘의 Swift 지식] Optional이란? 🤔
📌 Swift

[오늘의 Swift 지식] Optional이란? 🤔

Optional.. iOS 앱 개발을 위해 swift 언어를 시작한 저에게
'?'나 '!'가 변수명에 들어가는 걸 보는 건 처음이라서 많이 당황했었습니다.. 😅
그래서 이번 기회에 블로그를 처음 시작하면서
optional부터 공부하면서 정리하게 되었네요 :)

 

 

 

📃 Optional이 뭘까?

optional은 Type casting이나 nil value 체크 등에 있어서 중요한 역할을 합니다.

 

optional은 '?' 키워드로 사용되며, "이 변수에는 값이 들어갈 수도 있고, 아닐 수도 있어"라는 뜻입니다.

 

우선 아래의 예시를 봅시다.

var name: String = "Jack"   // OK
name = nil                  // Error ('nil' cannot be assigned to type 'String')

 

자, 우리는 name 변수에 'Jack'이라는 값을 할당해주고, 그 값에 다시 nil을 할당해주었습니다. 어라.. 근데 오류가 났네요..? 🤬

 

오류가 난 원인은 optional 변수가 아닌데 nil을 할당해주었기 때문입니다.

 

기본적으로 swift에서 변수를 선언할 경우에는 optional이 아닌 값(non-optional)을 지정해주어야 합니다. 즉, 변수를 선언할 경우 nil이 아닌 값(non-nil)을 할당해주어야 한다는 뜻이죠

 

만약 옵셔널이 아닌 변수에 nil을 설정해주면, 위와 같이 컴파일러는 nil 값을 할당할 수 없다며 오류를 발생시키는 것입니다.

여기서 잠깐, nil은 무엇일까? 🧐

  1. swift에서 nil은 optional 변수 이외에 사용할 수 없습니다.
  2. nil은 value가 없는 것이라고 생각하면 됩니다.
  3. nil은 optional 변수에서 따로 초기화하지 않아도 기본 디폴트 값입니다.

 

자 그러면 오류를 해결해보자! 😤

var name: String? = "Jack"   // OK
name = nil                   // OK

 

String 타입의 뒤에 '?'을 붙여주니 오류가 사라졌네요! 이유는 optional의 '?'키워드를 사용하여 optional 변수로 만들어주었기 때문입니다.

 

변수에 '?'키워드가 붙으면 그 안에 값이 있는지 물어보게 되고 값이 있으면 값을 얻게 되지만, 아무것도 없으면 nil값을 얻게 되는 것입니다.

 

'?'를 붙여서 오류가 사라졌지만, 그 위치에 '!'를 넣어주어도 오류가 사라지게 됩니다.

 

이유는 바로 밑에서 설명할게요 😃

 

! (Forced Unwrapping)

자 이제 '?'는 optional의 기호라는 건 다들 아실 겁니다.  '!'를 써도 오류가 사라지는데요.

 

'!'는 swift에서 강제 언래핑(Forced Unwrapping)을 할 때 사용됩니다.

 

'?'가 친절하게 값이 있는지 없는지 물어보는 것이라고 한다면, '!'는 값이 있든 말든 확인도 하지 않고, 강제로 값을 가져온다고 생각하시면 될 거 같네요.

 

또한, '!'사용은 조심해야 합니다. 스위프트 가이드를 보시면 "느낌표(!)를 사용하여 값이 존재하지 않는 optional 값에 접근하려고 시도하면 런타임 에러가 발생합니다.

 

그래서 느낌표(!)를 사용하여 강제 언래핑을 하기 전에는 항상 "optional 값이 nil이 아니라는 것을 확실히 해야 합니다."라고 작성되어 있습니다.

그러니 가능하면 '!'사용은 자제하는 게 좋겠네요. 😅

 

Forced Unwrapping을 하고 안하고의 차이는?

이번에도 코드를 참고하면서 봅시다.

var num: Int? = 300
print(num)              // Optional(300)

print(num!)             // 300

 

위의 코드가 '!'을 쓰고 안 쓰고의 차이입니다.

 

우리가 코드를 작성할 때 일반적으로 원하는 값은 'Optional(300)' 아닌, 그냥 '300'입니다. 하지만, print(num) 작성했을 경우 'Optional(300)'이 출력되며 우리가 원하는 '300'값은 나오지 않는 게 보이죠?

 

이런 경우, 우리가 원하는 값인 '300'을 출력하도록 하기 위해 사용하는 것이 '!(exclamation mark)'입니다.

 

변수명 뒤에 느낌표를 사용해서 optional을 Forced unwrapping 해주는 것이며, optional은 Forced unwrapping를 한 상태에서만 위와 같이 제대로 된 값만을 출력할 수 있습니다.

 

즉, 우리가 optional로 값이 있을 수도 있고, 없을 수도 있다.라고 선언했지만, 무조건 변수에 값이 있는 게 보장된 경우, '!'를 사용하면 우리가 원하는 값 만을 출력할 수 있게 됩니다.

 

하지만 위에서 설명했듯이,  '!'의 사용은 자제하는 게 좋겠다.라고 말했습니다.

 

여기서 "그러면 원하는 값만 가져올 수 없는데 어떻게 하라는 거야?"라는 생각을 하시는 분들이 있을 것 같은데요. (실제로 제가 그랬거든요 ㅎㅎ..)

 

이에 대한 대처방법으로 'Optional Binding'이라는 게 있는데, 이건 좀 더 공부해서 다음 포스팅에 올리겠습니다!

 

 

 

 

Optional에 대한 건 여기까지입니다.
이 글을 읽으신 분들이 있다면 조금이나마 도움이 되길 바라며,
오타나 틀린 점이 있으면 지적해주시면 감사하겠습니다!

 

References

Swift Optional (1)