[Swift] Optional

qkr7627·2022년 12월 2일
1

Swift

목록 보기
2/2
post-thumbnail


Optional 기본 개념

옵셔널을 살펴보기 앞서 Swift 언어의 특성 중 안전하게 코드를 작성할 수 있다는 점이 있습니다.(safe - 안정성)
이 중심에 Optional 이 있으며 스위프트에서 매우 중요한 개념입니다. 해당 포스팅에서는 Optional의 기본적인 개념을 살펴보도록 하겠습니다.

What is Optinal?

옵셔널이 의미하는 것은 값이 있을 수도 없을 수도 있음을 뜻합니다.

처음 이 개념을 저의 것으로 이해하는데 어려움이 있었습니다. 도움이 되었던 몇 가지 예시를 공유하고자 합니다.

  • 두루마리 휴지를 모두 사용하면 휴지심이 남습니다. 아직 휴지심이 남아있기 때문에 아무것도 없는 상태가 아닙니다.
  • 차량 구매 및 판매와 관련된 앱을 만든다고 했을때 사용자가 차가 있는지 없는지 값을 받아오려고 합니다. 이때 Boolean 타입 true, false로 값을 검사할 수 있지만 swift에서 제공하는 optional을 통해 안전하고 신속하게 데이터를 처리할 수 있습니다.

var userAge: Int?

다음과 같이 변수 타입 뒤에 ? 를 붙여주면 userAge는 옵셔널이 되고, 이를 Int형 Optional 타입이라고 합니다.
값을 초기화 하지 않으면 userAge에 nil이 담겨있다는 것을 뜻합니다.

 var userAge: Int? = nil // good
 var userAge: Int = nil // 컴파일 에러

따라서 다음과 같은 코드는 사용할 수 없습니다.

지금까지 옵셔널 기본 개념을 살펴보았습니다. 다음은 옵셔널을 어떻게 사용하는지 살펴보도록 하겠습니다.


wrapping

옵셔널을 사용하다보면 wrap 이라는 키워드 없이는 얘기하기가 어렵습니다. 왜냐하면 Optional 에 값이 감싸져 있기 때문입니다. 즉 옵셔널로 선언되어 있는 변수는 값이 있는지, nil인 것인지 wrap 되어 있어서 알 수 없습니다.
(즉 언박싱을 해보기 전까지 박스에 무엇이 있는지 명확히 알지 못하는 것과 같습니다)

그래서 다음과 같이 wrap되어 있는 상태에서는 변수에 값이 있더라도 그 값이 바로 출력되지 않습니다.

var userAge: Int? = 5
print(userAge)

// 결과 : Optional(5)

이 경우 userAge가 Optional이고 nil인지 값이 5가 들어있는지 알 수 없기 때문에 Optional(5)라고 출력이 됩니다.

Forced Unwrapping

앞선 예제에서의 출력 결과는 대부분의 원하는 출력 값이 아닐 것이라고 생각합니다. 원하는 값으로 추출하기 위해 Swift 에서는 ! 를 사용합니다. 이를 강제 언래핑이라고 합니다.

var userAge: Int? = 5
print(userAge!)

// 결과 : 5

다음과 같이 변수명 뒤 ! 를 붙이면 감싸져 있던 포장지를 강제로 뜯어서 값을 꺼내는 작업을 해줍니다.

그럼 항상 ! 로 포장지를 뜯어서 값을 꺼내면 될까요?

아닙니다. 강제 언래핑은 위험한 방법이고 안전한 코딩을 지향하는 Swift 에서도 권장하는 방법은 아닙니다.

상단과 같은 예시는 컴파일 시점에 userAge에 값이 있는지 개발자가 알고 있는 상황입니다. 코드가 길어지면 이를 모두 확인하기가 어렵고, 만약 다음과 같이 값이 없는 상황에 강제 언래핑을 해보면 어떻게 될까요?

var userAge: Int? 
print(userAge!)

추출 할 수 있는 값이 없기 때문에 컴파일 시점에서 에러가 발생합니다.

이렇게 값을 위험하게 꺼내지 않고 안전하게 꺼낼 수 있는 방법을 사용할 수 있도록 제공하는 방법 또한 존재합니다.


Optional Binding

안전하게 꺼내는 방법이 옵셔널 바인딩 입니다. 옵셔널 타입으로 선언된 변수에 값이 있는지 없는지 확인할 수 있도록 해주는 기능입니다. 이를 사용하면 느낌표 없이(!) 옵셔널 타입의 변수 값을 추출 할 수 있어 좀 더 안전하게 값을 추출합니다.

다음과 같은 코드를 통해 값을 꺼내올 수 있습니다.

var userAge: Int? = 10

// Swift 5.7 if let 개선된 버전
if let userAge {
    print("당신의 나이 : \(userAge)")
} else {
    print("값이 없습니다.")
}


// 이전 버전
if let testData = userAge {
    print("당신의 나이 : \(testData)")
} else {
    print("값이 없습니다.")
}

다음과 같이 값이 있는 경우 임시 변수(testData)를 통해 값을 꺼내올 수 있으며 Swift 5.7 이후 개선된 버전은 임시 변수 없이 바로 값을 받아올 수 있습니다.

만약 해당 코드에서 변수값을 초기화 하지 않았다면 else 구문이 실행되어 "값이 없습니다" 라는 String 값을 출력할 것 입니다.

optional binding을 통해 짧은 코드로 nil을 체크하고, 값이 있다면 값을 추출해내는 코드로 사용하여 Objective-C 언어와 비교했을때 코드가 매우 심플해진 것을 확인할 수 있습니다.

profile
만드는 사람이 수고하면 쓰는 사람이 편하고 만드는 사람이 편하면 쓰는 사람이 수고롭다.

0개의 댓글