[Swift] Optional 개념 알아 보기, nil 정의
Optional
Swift를 조금이라도 접해본 분들은 많이 들어봤을 옵셔널!! 에 대해서 알아 보기로 해요!!!
정의 : 래핑 된 값(Wrapped) 또는 값의 부재(absence)를 나타내는 타입이에요~
애플은 정의를 너무 어렵게 해서.. 공식 문서 보기 무서워요
하지만 왜 이렇게 했는지는 설명을 듣다 보면 알 거예요!
쉽게 말해 옵셔널 변수는 값이 있을 수도 없을 수도 있는 변수 라고 생각하면 돼요!
말로는 무슨 소리인지 모를 거예요 ‼️ 그래서 좀 더 설명할게요
위와 같이 let/var 변수 이름: 타입? 으로 주로 선언해요
저 String 타입 옆에? 이걸 붙이면 옵셔널 타입이에요
보통은 shortForm 형태로 많이 사용해요
옵셔널 타입은 열거형(enum)으로 이루어져 있어요
그래서 정의가 래핑 된 값, 값의 부재 라고 한 것이 그 이유에요!
하지만 열거형은 아직 다루지 않아서 이 부분은 추후 포스팅할게요!
Optional Type
자자 이제 옵셔널 타입을 예시로 설명할게요
옵셔널을 타입 어노테이션 방법으로 선언해 볼게요 !
girlFriend 를 옵셔널 String 으로 타입을 정해두고 선언했어요
이 값을 출력해 볼 거예요
엥? 그냥 "지수" 가 아니라 Optional("지수") ..?
한번 타입을 찍어볼게요
타입을 찍어보면
그냥 String 이 아니라
String이 Wrapping 되어 있죠? Optional<String> 으로 말이죠!
아까 옵셔널 정의에서 제가 뭐라 했을까요?
래핑(Wrapping) 된 값(String) 또는 값의 부재
래핑 된 값! (Wrapped Value)
래핑 된!! (Wrapped)
아.. girlFriend는 옵셔널이라는 타입으로 래핑<> 되어 있구나!!
제 여자친구가 있을 수도 있고 없을 수도 있는 거예요!!
자 이제 제가 여자친구랑 헤어져서 girlFriend에 값을 넣어주지 않을게여 .. ㅜ
이렇게 타입 어노테이션으로 선언 만 해놓고 값을 저장하지 않을게요
이제 출력을 해보고 결과를 해볼게요
nil? 엥 nil이 뭘까요?
드디어 nil 을 설명할 수 있게 되어서 기뻐요 ㅎ
설명하기 전에 진짜 마지막으로 옵셔널 타입의 정의가 뭐라고요?
ㄹㅍㄷ ㄱ ㄸㄴ ㄱㅇ ㅂㅈ~
ㅎㅎ ^^;; 죄송..
아무튼 이번엔 값의 부재(absence) !!!
nil
Optional 타입 은 열거형(enum)이라고 했어요!
case none 에 해당하는 케이스에 해당돼요
무슨 소리지? 하면 열거형 부분은 넘어가요! 열거형 몰라도 돼!!
아무튼 nil 은
"값이 없음을 나타내는 키워드"
라고 생각하면 좋아요!
Objective-C에서는 nil 이 포인터인데, Swift 에서 nil은 포인터가 아니에요!
정의에서도 봤듯이 값의 부재 = absence입니다
그래서 nil이 왜 필요할까요?
바로 Swift는 타입 안정성(type-safe)을 보장하는 언어이기 때문이에요
nil 을 통해 명시적으로 값이 없음을 처리하고, 컴파일 시점에 타입 오류를 방지하고 런타임에 안전한 코드 실행을 보장하는 특성이 있어요!
변수에 값을 접근했는데 값이 없으면 오류가 뜨거든요~
이렇게 말이에요
아무튼 옵셔널이 아닌 타입(Non-Optional Type) 은 변수와 상수는 값을 읽기 전에 반드시 초기화해야 합니다!
( 참고로 Non-Optional Type 은 Optional 타입이 아닌 모든 타입을 말해요 ⭐️
우리가 매일 사용하는 String, Int 등등.. )
여자친구가 옵셔널이 아니라면
여자친구가 필수라는 건데 ,, 헤어지는 게 말이 되나요?네네.. 필수였으면 좋겠네요 ^^
우리의 이름은 String으로 정의된다고 생각해 봐요
사람을 구분하는데 필수죠? 뭐 주민등록번호 등등..
nil 일 수가 없는 것들은 일반 자료형이라고 생각합시다!
하지만 여자친구는 String? 이다 ~
딴 얘기로 더새기 전에
자 결론
nil은 Optional로 포장(Wrapping) 된 값에만 사용이 가능하고, 값이 없다면 값의 부재로 알려준다.
더 쉽게!
값이 없으면 에러를 내는 게 아니라 값이 없음 알려준다 ~
Optional 이해하기, nil 할당
자자 이제 옵셔널 타입의 래핑 된 값, 값의 부재 nil 까지 모두 설명이 끝났어요 ~
이제 어느 정도 지식은 들어갔다 생각하고 이해하는 시간을 가져 볼게요
아까 위에서 여자친구가 헤어졌다고 한거 기억나죠? 그때 아래처럼 선언만 했어요!
참고로 아래처럼 선언만 하고 값을 입력하지 않으면 nil 로 저장이 돼요
이제 옵셔널을 이해했으니
girlFriend와 헤어졌다고 생각하고, 옵셔널 변수에 nil을 할당 시켜줄 거예요
여자친구가 있었는데(var girlFriend: String? = "지수") , 헤어졌다(girlFriend = nil)
오케이 !!?
근데 옵셔널이 아닌 Non-Optional Type 에는 nil 을 사용할 수 없어요
자 위에 처럼 String? 이 아니라 Non-Optional Type 인 String 로 선언했을 때는 에러가 뜹니다
왜냐하면 nil은
nil 은 String 타입에 할당할 수 없어요!
nil 은 아까 어디서만 사용 가능하다고 했죠??
Optional 타입에 case none 에 해당한다 !아 case 몰라도 돼
Optional 타입에~
뭐라고여 ?
ㅇㅅㄴ ㅌㅇㅇ ~
즉 옵셔널로 선언된 타입에만 가능하다!!
nil 은 오류가 발생했을 때 타입 오류를 방지하기 위해 대신 값이 없는 키워드를 발생해요
따라서 nil 은 Optional 타입에만 할당 가능해요.
Dictionary로 한 번 더 예시로 들어볼게요
참고로 딕셔너리의 키 값에 접근하는 서브스크립트 문법의 리턴 값은 옵셔널이에요 ⭐️
서브 스크립트는 또 뭐예요?
클래스, 구조체 또는 열거형 등에 원하는 인덱스 값을 사용하여 인스턴스 요소에 대괄호[] 로 접근하는 방법을 제공하는 특별한 메서드에요
iOS에서는 주로 배열이나 딕셔너리에서 많이 사용돼요
본론으로 돌아와서 딕셔너리의 key 에 접근해 볼게요
옵셔널 MJ로 잘 출력이 되는 걸 볼 수 있어요
여기서 질문 !
근데 왜 옵셔널로 리턴이 될까요??
왜냐하면 딕셔너리가 딕셔너리에 사용하는 키에 대한 값을 보유하지 않을 수 있기 때문이에요
따라서 값이 없는 값을 서브스크립트 문법으로 접근한다면요?
예상이 가시죠!?
값이 없을을 나타내는 키워드인 nil 을 리턴 합니다 ㅎㅎ
마지막으로 일반 타입(Non-Optional Type)과 옵셔널(Optional Type)의 차이를 String 타입으로 예를 들어, 범위로 그려 볼게요.
자 이제 옵셔널에 대해 많이 이해가 됐을까요?
옵셔널 값 사용
어.. 근데 여기서 Unwrapping은 뭐예요?
아까 위에서
봤을 텐데 옵셔널 타입을 출력하면 옵셔널 타입을 return을 해요
친구 : 너 여자친구 누구야?
나 : Optional(지수) 야 ~
라고 말하는 사람은 없잖아요?
이것을 방지하고 래핑 된 값을 사용하기 위해 옵셔널 값을 사용할 때
옵셔널 바인딩과 같은 기법으로
옵셔널 타입을 Non-Optional Type 으로 언래핑 해주는 과정이 필요해요!