Swift

swift: 옵셔널(Optional)

소재훈 2022. 1. 21. 17:22

옵셔널은 값이 있을 수도, 없을 수도 있음을 나타내는 표현이다. 즉 변수 또는 상수의 값이 nil(다른 언어에서의 NULL)일 수도 있다는 것을 의미한다. 

옵셔널로 선언되지 않은 변수에 nil이 할당되면 에러가 발생합니다.

nil은 옵셔널로 선언된 곳에서만 사용할 수 있고, 옵셔널 변수/상수는 데이터 타입뒤에 물음표를 붙여서 표현해주거나 Optional <타입명>처럼 옵셔널을 명확하게 써줄 수 있습니다.

var myName: String? = "Jaehoon"
//var myname: Optional<String> = "Jaehoon"과 같음.
myName = nil
print(myName) // nil

옵셔널은 값을 갖는 케이스와 그렇지 못한 케이스 두 가지로 정의되어 있다. nil일때는 none 케이스가 되고, 값이 있는 경우에는 some 케이스가 되는데, 옵셔널에 값이 있으면 some연관 값인 Wrapped에 값이 할당된다. switch문을 통해 여러 가지고 조건을 검사해 보자.

let numbers: [Int?] = [2, nil, -4, nil, 100]

for number in numbers {
    switch number {
    case .some(let value) where value < 0:
        print("Negative value!! \(value)")
    case .some(let value) where value > 10:
        print("Large value!! \(value)")
    case .some(let value) :
        print("Value \(value)")
    case .none:
        print("nil")
    }
}

//Value 2
//nil
//Negative value!! -4
//nil
//Large value!! 100

 

열거형의 some케이스로 숨어있는 옵셔널의 값을 옵셔널이 아닌 값으로 추출하는 옵셔널 추출(Optional Unwrapping)에 대해서 알아보자.

첫번째로 옵셔널 강제 추출(Forced Unwrapping) 방식이 있다. 간단한 방식이지만, 실제로 변수나 상수에 nil이 할당되어 있을 경우 런타임 오류가 발생하기 때문에 가장 위험한 방법이다. 옵셔널의 값을 강제추출하기 위해서는 옵셔널 값의 뒤에 느낌표(!)를 붙여주면 된다. 

옵셔널이 아닌 변수에는 옵셔널 값이 들어갈 수 없으므로 추출해서 할당해주어야 한다.

var myName: String? = "Jaehoon"
var Jaehoon: String = myName!

myName = nil
Jaehoon = myName! // 런타임 에러

 

두번째로 옵셔널 바인딩(Optional Binding)이 있다. if구문을 사용해 변수나 상수가 nil값인지를 먼저 확인한 후 옵셔널 값을 강제 추출하는 방법이다. 옵셔널에 값이 있는 지 확인하고, 옵셔널에 값이 있다면, 옵셔널에서 추출한 값을 일정 블록안에서 사용할 수 있는 상수나 변수로 할당해서 사용한다. if나 while구문과 결합하여 사용할 수 있다.

if let name = myName {
    print("My name is \(name)")
} else {
    print("myName == nil")
}

if구문을 실행하는 블록안쪽에서만 name이라는 임시 상수를 사용할 수 있다. 쉼표(,)를 사용해서 바인딩할 옵셔널 상수 값을 나열할 수도 있다. 

 

세번째로는 옵셔널바인딩으로 값을 매번 추출하고 귀찮거나, nil로 인한 런타임 오류가 아닐 거라는 확신이 들 때, nil을 할당해줄 수 있는 변수나 상수를 만들 수 있다. 이때 사용하는 것이 암시적 추출 옵셔널(Implicity Unwrapped Optionals)이다. 타입 뒤에 느낌표(!)를 사용해 주면 된다. 

일반 값처럼 사용할 수 있고, 옵셔널이기 때문에 nil도 할당해 줄 수 있다. 하지만 nil이 할당되어 있을 때 접근하면 런타임 에러가 발생하기 때문에 조심해야한다.

var myName: String! = "Jaehoon"
myName = nil

if let name = myName {
    print("My name is \(name)")
} else {
    print("myName == nil")
}

myName.isEmpty // 런타임 에러.

'Swift' 카테고리의 다른 글

swift: 클래스  (0) 2022.01.21
swift: 구조체  (0) 2022.01.21
swift: 함수 데이터타입  (0) 2021.12.27
swift: 함수와 매개변수  (0) 2021.12.27
swift: 함수의 정의와 호출  (0) 2021.12.27