안녕하세요! 오늘은 Optionals 포스팅으로 돌아왔습니다.
개발할 때 가장 많이 발생하는 예외 중 하나가 NullPointerException입니다. 접근하는 변수의 값이 nil이어서 발생하는 것입니다.

var yourName: String // 선언
//yourName = "어흥" // 값을 저장하지 않는다면..
print(yourName) // (만약 저장과정이 없다면) 메모리에 저장된 값이 없는데 접근 ===> 🔸"에러"
위처럼 변수를 선언했지만 값을 저장하지 않은 변수에 접근하면 에러가 발생합니다. 앱 실행 중에 해당 에러가 발생하면 바로 앱이 중단됩니다.
이 때문에 Optional 개념을 도입한 것이라고 할 수 있습니다.
Swift는 안전한 코딩을 할 수 있게 해주는 언어라고 알려져 있습니다. 그리고 이 안전성의 기본 바탕에 있는 중요한 요소 중 하나가 바로 Optional이라는 개념입니다.

위 그림처럼 기존 non-optional type 값과 nil을 포함한 타입이 optional type이라고 생각하면 됩니다.
Optional은 nil을 사용할 수 있는 타입과 없는 타입을 구분하기 위함이며, nil을 사용할 수 있는 Type을 Optional Type이라 부릅니다. (nil - 값이 없음을 나타내는 키워드)
이처럼 에러가 나지 않도록 임시적인 타입을 담아두는 개념이라고 생각하시면 됩니다.
그럼 optional 은 어떻게 구현되어 있을까요?
옵셔널은 제네릭 Enum(열거형)으로 구현되어 있습니다.

enum Optional<Wrapped> {
case none // nil
case some(Wrapped) // optional value
}
따라서 nil은 실제 값이 없는 것이 아니라 값이 없음을 나타내는 키워드인 것을 알 수 있습니다.
var num: Int? = 3 // optional type
var noneNum: Int? = nil
위 코드를 예시로 들면 각각의 변수는 다음과 같이 표현할 수 있습니다.
모든 타입의 뒤에 '?' (물음표)를 붙이면 옵셔널 타입이 됩니다.
var num: Int? = 3
var yourAge: Int? = nil
var yourGrade: Double? = nil
var name1: String? = "Jobs"
num = nil
name1 = nil
옵셔널 타입 선언의 기본 규칙
옵셔널은 2가지로 표현할 수 있지만 주로 간편표기 방식을 많이 사용합니다.
일반 타입과는 다르게 옵셔널 타입은 타입 추론 방식을 사용할 수 없습니다. -> nil 값으로 초기화될 때 어떤 타입인지 추론하기 어렵기 때문입니다.
따라서 type annotation을 사용해서 초기화해야합니다.
let num1: Int? = 2 // 간편표기
let num2: Optional<Int> = 0 // 정식문법
//var optionalNum = nil // 불가능한 형태
그렇다면 optional type에 non-optional type 값을 담으면 어떻게 될까요?
optional 타입인 b에 non-optional 타입인 c를 할당해도 non-optional 타입이 Optional 타입으로 바꿔서 담기는 걸 확인할 수 있습니다.
var a: Int? = 7 // 옵셔널 인트
var b = a // 값을 복사해서 담는 다면 타입은?
print(b) //Optional(7)
var c: Int = 5
b = c // Int를 Int?타입에 담을 수는 있다. (어쨌든 타입이 Int? 타입으로 바뀌어서 담김)
print(b) // Optional(5)
optional 타입끼리 계산할 수 없습니다. 계산하기 위해서 unwrapping을 진행해야 합니다.
unwrapping에 대해서는 다음 포스팅에 이어 작성하도록 하겠습니다!