[iOS / Swift] Swift 문법을 알아보자! - 6편 : 옵셔널 (Optional)

프린스송·2021년 5월 20일
1

Swift 문법

목록 보기
6/21
post-thumbnail
post-custom-banner

안녕하세요! 벌써 6번째 문법 공부입니다. 많은 것을 배운것 같지만 아직 더 배워야 할 많은 문법이 남아있더군요.. 오늘 공부하고 배워본 내용은 옵셔널이라는 것입니다. 예전에 컬렉션 타입을 공부할떄 한번 Optional이라는 단어를 언급했었는데 드디어 오늘 자세하게 알아볼 수 있겠군요! 그러면 이제부터 옵셔널에 대해 자세히 알아보겠습니다.


옵셔널 (Optional)

옵셔널은 Swift언어에서 가장 큰 특징을 가진다고 합니다. 저도 다른 프로그래밍을 그래도 적지 않게 공부했다고 생각했는데 이 옵셔널에 대한 내용은 Swift에서 처음 접했네요. 옵셔널이란 변수의 값이 있을 수도 있고 없을 수도 있다는 것을 나타냅니다. 한마디로 변수의 값이 nil(NULL)값인 아무것도 없는 상태의 값을 가질 수 있다는 것입니다.

nil?
->nil은 값이 없는 느낌이 아니라 빈 값이라는 느낌에 더 가까움.

  • 문자열 ""은 값이 없는 거지 빈 값은 아니다..!
  • 정수형 0은 0이라는 값이 있는 거지 빈 값은 아니다..!

저희가 가장 먼저 배웠던 변수에 대해 다시 한번 생각을 해봅시다.

var a : String = "abc"
var b : Int = 4

print(a)
print(b)

저희는 이런식으로 변수를 선언하고 해당 변수에 값을 넣어줬습니다. 그리고 해당변수를 출력까지 한다는 것도 알았구요! 그리고 이 변수들은 각각의 값을 가지고 있고 변수로 선언했으니 수정까지 가능할 겁니다. 하지만 만약 저 변수들에게 빈 값인 nil로 변경을 해주면 어떻게 될까요?? playground에서 한번 확인을 해보겠습니다.
이런.. 에러가 나는 군요. 에러 메세지를 잠깐 읽어보면 nil은 String과 Int에 할당되지 못한다고 합니다. 여기서 저희가 이때까지 선언했던 변수 타입형들은 다 nil을 가지지 못하는 non-Optional 변수이라는 것을 알 수 있습니다! 그렇다면 변수들이 nil값인 빈 값을 가지려면 어떻게 해야할까요?


옵셔널 변수 선언

nil값을 가질 수 있는 옵셔널 변수를 선언하기 위해서는 데이터 타입 뒤에 ?를 붙이기만 하면 됩니다. 정말 쉽죠..?ㅎㅎ 그럼 ?만 붙여서 코드를 수정해 보죠.

var a : String? = "abc"
var b : Int? = 4

a = nil
b = nil

print(a)
print(b)

이제야 오류없이 변수에 nil값이 들어갔고 출력까지 잘 되는걸 확인할 수 있습니다! 이렇게 ?만으로 nil값을 포함하는 변수를 선언을 할 수 있게 되었습니다.


String?과 String

하지만!! 여기의 String?과 String은 절대 같은 타입이 아닙니다!! 저도 처음에 nil만 포함하고 아니고 그 차이니까 같은 테이터 타입이라고 착각을 했지만 둘은 아예 다른 데이터 타입을 가지고 있더라고요. 간단한 코드를 통해 확인을 해보겠습니다.

var a : String? = "abc"
var b : String

b = a

print(b)

옵셔널 String인 a에 "abc"값을 넣어 선언하고 그냥 String인 b에 a변수를 넣어주었습니다. 하지만 에러가 뜨면서 코드가 실행이 안되었군요.. b 변수는 옵셔널이 아닌 String이기 때문에 항상 값을 가지고 있어야 합니다. 반면에, a는 옵셔널로 선언된 변수이기 때문에 실제 코드가 실행되기 전까지는 값이 있는지 없는지 알 수 없습니다.

여기서 한가지를 알 수 있었습니다. 만약 두 변수가 같은 타입이였다면 한 변수에 한 변수를 넣어주어 저장이 가능하겠지만 여기서는 에러가 났으므로 두 변수는 다른 데이터 타입이다! 그리고 에러 메시지를 잠깐 읽어보자면 "String?은 반드시 String 타입으로 unwrapped를 해 줘야 된다"라고 적혀 있네요. 그렇담 unwrapped가 무엇인지 빠르게 알아볼까요?


Force Unwrapping (강제 언래핑)

Unwrapping을 해석해보자면 무언가 쌓여있는 것을 벗겨낸다는 느낌입니다. 이 의미를 옵셔널에 대입을 시켜보면 '?라는 옵셔널에 쌓여있는 것을 벗겨내어 확인을 한다'라고 저는 이렇게 이해를 해보았습니다. 옵셔널 변수안에는 값이 있을 수도 없을 수도 있기에 알 수 없고 그것을 벗겨내어 확실하게 알 수 있게 하는 것이 Unwrapping입니다

강제로 Unwrapping을 하기 위해서는 옵셔널 변수 뒤에 !를 붙여주면 됩니다. 위의 코드를 Unwrapping해서 다시 실행해 보겠습니다.
옵셔널 변수인 a뒤에 !를 붙여 실행을 해보니 문자열 변수 b에 잘 저장이 된것을 볼 수 있습니다!!

이해를 조금 더 구체화하기 위해 코드를 쓰면서 연습을 해보겠습니다.

var c : Int?

c = 5

print(c)

옵셔널 정수형 c변수를 선언한 후 5를 대입했습니다. 그럼다음 변수를 출력하면 어떠한 결과가 나올까요?
이렇게 Optional이라는 무언가가 숫자 앞에 있는 것을 확인할 수 있습니다. 이러한 이유는 c변수는 옵셔널로 선언이 되었고 이 변수가 값을 가질지 nil을 가질지 모르기 때문입니다. 그러니 앞에 Optional이라는 수식이 붙는 거지요. 그렇다면 이러한 수식조차 없애고 온전한 정수형을 얻기 위해 서는 어떻게 해야할까요? 위의 방법을 이용하는 겁니다!
!를 이용해서 Unwrapping을 해주었더니 출력값에는 온전한 숫자가..! 정답은 여기에 있었군요!

하지만 이렇게 Unwrapping을 위해 변수 뒤에 !를 쓰는 것은 좋은 코드가 절대 아니랍니다. !를 이용해 Unwrapping해주는 과정은 우리가 옵셔널 변수에 값이 무조건 있다는 가정하에 강제로 Unwrapping을 해주는 것이기 때문에 만약 옵셔널 변수에 nil값이 들어있는 체로 !를 이용해 강제 Unwrapping을 해준다면 오류가 발생한답니다. 다음 코드를 보면서 확인을 해보죠.
위 코드에서 c변수를 다시 nil로 바꾸어보았습니다. 그리고 !로 강제 Unwrapping을 해주었더니...오류가 바로 뜨네요..ㅜㅠ

이렇게 코드가 짧을 때는 내가 선언한 변수에 어떤 값이 들어가고 nil값의 유무를 쉽게 알 수 있지만 만약 나중에 복잡한 코드를 만지게 된다면 많은 변수를 만나게 될 것이고 모든 변수의 값을 기억하지 못해 !를 사용한 강제 Unwrapping으로 오류가 날 수 있답니다.. 절대 그래서는 안되겠죠.

이런 강제 Unwrapping말고 안전한 방법은 당연히 있었습니다. 옵셔널 바인딩(Optional Binding), 옵셔널 체이닝(Optional chaining)등이 있는데 이러한 내용은 나중에 더 자세히 살펴 보도록 하겠습니다.


오늘은 옵셔널에 대해서 공부해 보았습니다. 아직도 뭔가 100% 완벽하게 이해를 못했다는 생각이 듭니다. 하지만 모든 그렇듯 많이 보고 많이 접해보면 익숙해지고 더 능숙해지지 않을까요? 요 옵셔널 파트는 조금 새롭고 어려운 부분인 만큼 더 많은 학습 시간을 투자 해야겠습니다. 오늘 하루도 수고하셨습니다.

오늘 배운 중요한 요소들

  • nil을 넣기 위해서는 옵셔널이 필요하다.
  • 그냥 데이터형과 옵셔널 데이터형은 완전히 다른 것이다.
  • 옵셔널 데이터형을 쓰기위해서는 unwrapping 과정이 필요하다.
  • unwrapping을 위해 변수 뒤에 !를 붙이는 것은 좋은 코드가 되지 못한다.
profile
[iOS / Swift] [React Native]
post-custom-banner

3개의 댓글

comment-user-thumbnail
2021년 10월 13일

옵셔널은 왜 필요한건가요?? python으로 가정하면 if문을 사용해서 그냥 null인지만 확인하면되는 것 같은데 굳이 감싸고 null인지 아닌지 확인하기 위해서 언랩핑을 하는 과정이 추가된건데 돌아가는게 아닌가요?

1개의 답글
comment-user-thumbnail
2022년 4월 23일

옵셔널에 대해서 찾아보던 중 처음 이런 플랫폼이 있다는 걸 알게되고 그 중 처음 읽게 된 글인데 너무 잘 가르쳐주시니 감사할 따름이에요😽

답글 달기