본문 바로가기

Swift/문법 정리

옵셔널 타입

옵셔널(optional)

 

옵셔널 데이터 타입은 대부분의 다른 프로그래밍 언어에는 없는 새로운 개념이다.

옵셔널 타입의 목적은 변수 또는 상수에 값이 할당되지 않은 상황처리하기 위해 안전하고 일관된 접근 방식을 제공하는 것이다.

 

1) 변수 선언 방법

var index: Int?

변수를 선언할 때, 데이터 타입 선언 다음에 "?" 문자를 두어 옵셔널이 되게 한다.

해당 코드는 index라는 이름의 Int타입의 변수를 옵셔널로 선언하는 코드이다.

 

이렇게 선언하고 나게 되면 index 변수는 정수값이 할당되거나 아무런 값도 할당되지 않을 수 있다는 것이다.

 

내부적으로 컴파일러와 런타임의 관점에서 볼 때 이런 옵셔널 데이터 타입의 변수는 nil의 값을 갖는다.

 

2) 래핑 & 강제 언래핑 (wrapping, unwrapping)

var index: Int?

index = 3

var treeArray = ["Oak", "Pine", "Yew", "Birch"]

if index != nil {
    print(treeArray[index!])
} else {
    print("index does not contain a value")
}

 

해당 코드처럼 옵셔널에 값이 할당되었다면 (index  = 3) 해당 값이 옵셔널 내에서 '래핑되었다'고 말한다. 

이렇게 래핑된 값을 사용하기 위해서는 강제 언래핑이라는 개념을 이용하게 된다. 

강제 언래핑은 래핑된 옵셔널 타입에서 옵셔널 이름 뒤에 느낌표(!)를 두어 추출하게 된다.

 

해당 코드는 index 옵셔널 변수에 값이 할당되면 해당 위치에 있는 나무를 출력하는 코드이다.

만약 해당 옵셔널 이름 뒤에 느낌표를 빼서 언래핑을되지 않는 다면 언래핑 에러가 나타난다.

 

3) 옵셔널 바인딩 (optional binding)

옵셔널로 할당된 값을 강제 언래핑 대신 옵셔널 바인딩을 이용해서 임시 변수나 상수에 할당할 수 있다.

var index: Int?

index = 3

var treeArray = ["Oak", "Pine", "Yew", "Birch"]

if let myValue = index {
    print(treeArray[myValue])
} else {
    print("index does not contain a value")
}

이처럼 옵셔널 변수를 임시 변수나 상수에 할당을 하게 되면 index 변수에 할당된 값이 언래핑되어 myValue라는 임시 상수에 할당된다.

이 myValue 상수는 if 구문에서만 유효한 상수이기 때문에 옵셔널로 할당된 동일한 이름을 사용해도 충돌이 발생하지 않는다.

 

if let index = index {
    print(treeArray[myValue])
} else {
    print("index does not contain a value")
}

 

4) 강제적으로 언래핑 되도록 옵셔널을 선언

만약 옵셔널을 선언할 떄 물음표대신에 느낌표를 사용하여 선언하면 강제 언래핑이나 옵셔널 바인딩을 하지 않아도 값에 접근할 수 있다.

var index: Int!

index = 3

var treeArray = ["Oak", "Pine", "Yew", "Birch"]

if index != nil {
    print(treeArray[index])
} else {
    print("index does not contain a value")
}

이렇듯 옵셔널을 선언할 때 느낌표를 사용해주게 되면 index를 사용할때 기존의 강제 언래핑처럼 뒤에 느낌표를 붙이지 않고도 언래핑이 될 수 있다는 걸 알 수 있다.

 

5) 주의할 점

스위프트에서 할당된 값이 없거나 nil을 할당 할 수 있는 것은 옵셔널 타입뿐이다.

즉, 옵셔널이 아닌 변수 또는 상수에 nil을 할당할 수 없다는 것이다. 주의하면서 사용하자.

'Swift > 문법 정리' 카테고리의 다른 글

클로저(Closure)를 알아보자  (1) 2022.07.16
Map 함수  (0) 2022.05.09
타입 캐스팅(업캐스팅 & 다운캐스팅)  (0) 2022.04.04