으니의 개발로그

[Swift] 옵셔널(2) - 옵셔널 추출 본문

Swift/책 정리

[Swift] 옵셔널(2) - 옵셔널 추출

아잉으니야 2021. 2. 2. 20:57

[Swift] 옵셔널(2) - 옵셔널 추출

이 글은 Swift 프로그래밍 책을 읽고 요약한 내용입니다.

 

옵셔널 추출 : 열거형의 some 케이스로 숨어있는 옵셔널의 값을 옵셔널이 아닌 값으로 추출

 

 

강제 추출

옵셔널 값의 뒤에 느낌표(!)를 붙여주면 값을 강제로 추출하여 반환한다. 옵셔널의 값이 없다면(nil 이라면) 런타임 오류가 발생한다. 이 방법은 가장 간단하지만 가장 위험한 방법이다. 런타임 오류가 일어날 가능성이 가장 높고 옵셔널의 만든 의미가 무색해지는 방법이기 때문이다.

var myName: String? = "seonho"

// 옵셔널이 아닌 변수에는 옵셔널 값이 들어갈 수 없다. 추출해서 할당해주어야 한다.
var seonho: String = myName!

myName = nil
seonho = myName!    // 런타임 오류

// if 구문 등 조건문을 이용해서 조금 더 안전하게 처리해볼 수 있다.
if myName != nil {
    print("My name is \(myName!)")
} else {
    print("myName == nil")
}
/* myName == nil */

 

 

옵셔널 바인딩

옵셔널에 값이 있는지 확인할 때 사용한다. 옵셔널에 값이 있다면 옵셔널에서 추출한 값을 일정 블록 안에서 사용할 수 있는 상수나 변수로 할당해서 옵셔널이 아닌 형태로 사용할 수 있도록 해준다. 옵셔널 바인딩은 if 또는 while 구문 등과 결합하여 사용할 수 있다.

var myName: String? = "seonho"

// 옵셔널 바인딩을 통한 임시 상수 할당
if let name = myName {
    print("My name is \(name)")
} else {
    print("myName == nil")
}
/* My name is seonho */

// 옵셔널 바인딩을 통한 임시 변수 할당
if var name = myName {
    name = "wizplan"    // 변수이므로 내부에서 변경 가능
    print("My name is \(name)")
} else {
    print("myName == nil")
}
/* My name is wizplan */

 

옵셔널 바인딩을 통해 한 번에 여러 옵셔널의 값을 추출할 수도 있다. 쉼표(,)를 사용해 바인딩 할 옵셔널을 나열하면 된다. 단, 바인딩하려는 옵셔널 중 하나라도 값이 없다면 해당 블록 내부의 명령문은 실행되지 않는다.

var myName: String? = "seonho"
var yourName: String? = nil

// friend에 바인딩이 되지 않으므로 실행되지 않는다.
if let name = myName, let friend = yourName {
    print("We are friend! \(name) & \(friend)")
}

yourName = "hero"

if let name = myName, let friend = yourName {
    print("We are friend! \(name) & \(friend)")
}
/* We are friend! seonho & hero */

 

 

암시적 추출 옵셔널

nil 을 할당해줄 수 있는 옵셔널이 아닌 변수나 상수를 암시적 추출 옵셔널이라고 한다. 옵셔널을 표시하고자 타입 뒤에 물음표(?)를 사용했지만, 암시적 추출 옵셔널을 사용하려면 타입 뒤에 느낌표(!)를 사용해주면 된다.

암시적 추출 옵셔널에는 nil 을 할당해줄 수 있는데 이 때 접근을 시도하면 런타음 오류가 발생한다.

var myName: String! = "seonho"
print(myName)
/* Optional("seonho") */

myName = nil

// 암시적 추출 옵셔널도 옵셔널이므로 바인딩을 사용할 수 있다.
if let name = myName {
    print("My name is \(name)")
} else {
    print("myName == nil")
}
/* myName == nil */

 myName.isEmpty // 오류