Swift/Swift 기본문법

Swift 기본 문법 - 10. 옵셔널

728x90

옵셔널

다른언어에는 없는 표현으로 스위프트의 특징 중 하나인 안정성safe을 문법으로 담보하는 기능입니다.

 

옵셔널은 단어 뜻 그대로 '선택적인', 즉 값이 '있을 수도, 없을 수도 있음'을 나타내는 표현입니다.

 

옵셔널 사용

// var myName: String = "kemi"
// myName = nil // 오류!

var myName: String? = "kemi"
print(myName)

myName = nil
print(myName)


옵셔널은 어떤 상황에 사용할까요?

1) 함수에 전달되는 전달인자의 값이 잘못된 값일 경우 제대로 처리하지 못했음을 nil을 반환하여 표현 할 수 있습니다.

2) 매개변수를 굳이 넘기지 않아도 된다는 뜻으로 매개변수의 타입을 옵셔널로 정의 할 수도 있습니다.

 

옵셔널 자체가 열거형이기 때문에 옵셔널 변수는 switch 구문을 통해 값이 있고 없음을 확인 할 수 있습니다.

func checkOptionalValue(value optionalValue: Any?) {
    switch optionalValue {
    case .none:
        print("This Optional variable is nil")
    case .some(let value):
        print("Value is \(value)")
    }
}

var myName: String? = "kemi"
checkOptionalValue(value: myName) // Value is kemi

myName = nil
checkOptionalValue(value: myName) // This Optional variable is nil

 

옵셔널 추출(Optional Unwrapping)

 

강제 추출(Forced Unwrapping)

옵셔널 강제추출방식은 옵셔널의 값을 추출하는 가장 간단한 방법이지만 가장 위험한 방법입니다.

런타임 오류가 일어날 가능성이 높기 때문입니다.

옵셔널의 값을 강제 추출하려먼 옵셔널 값의 뒤에 느낌표(!)를 붙여주면 값을 반환해줍니다.

만약 강제 추출 시 옵셔널에 값이 없다면, 즉 nil이라면 런타임 오류가 발생합니다. 그래서 이렇게 되면 옵셔널을 사용한 의미가 없어집니다

 

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

myName = nil
//kemi = myName! // error

 

옵셔널 바인딩

옵셔널 바인딩도 강제추출과 마찬가지로 옵셔널에 값을 꺼내기 위해 사용됩니다.

다만 다른점은 값이 있는지 확인 할 때 사용합니다.

만약 값이 있다면 옵셔널에서 추출한 값을 일정 블록안에서 사용할수 있는 상수나 변수로 할당해서 옵셔널에서 꺼내줍니다.

옵셔널 바인딩은 if 또는 while 구문 등과 결합하여 사용 할 수 있습니다.

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

// 옵셔널 바인딩을 통한 임시 상수 할당
// friend에 바인딩이 되지 않으므로 실행되지 않습니다.
if let name = myName, let friend = yourName {
    print("My name is \(name) & \(friend)")
} else {
    print("myName == nil")
}

yourName = "eric"
if let name = myName, let friend = yourName {
    print("My name is \(name) & \(friend)")
} else {
    print("myName == nil")
}

 

암시적 추출

로직상 nil 때문에 런타임 오류가 발생하지 않을 것 같다는 확신이 들 때 옵셔널이 아닌 변수나 상수가 있으면 좋을 겁니다.

암시적 추출 옵셔널을 사용하려먼 타입 뒤에 느낌표(!)을 사용해주시면 됩니다.

 

!을 사용해도 Optional("값") 으로 감싸 나오는데, 왜 사용해주는걸까?

var myName: String! = "kemi"
print(myName)       // Optional("kemi")
myName = nil

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

myName.isEmpty // 오류

 

옵셔널 바인딩, nil 병합 연산자(??)를 비롯해 뒤에서 배울 옵셔널 체이닝 등의 방법을 사용하는 편이 훨씬 안전합니다.

 

Swift에 왜 있는지 도무지 모르겠는 문법 중에 하나다.

type safe를 중시하는 언어라 있는게 맞긴한데...
nil이 들어가면 에러가 나기 때문에 있는게 맞긴한데... 
자바스크립의 경우엔 false로 대체되기 때문에 이런 처리를 하지 않았는데 쓰다보니 익숙하긴한데.. 뭔가 맘에 안든다.

 

항상 옵셔널 값을 사용 할 때마다 if나 guard let 구문을 사용하는게... swift UI에선 안쓰나?

반응형