저번 시간의 내용에 이어서 이번 시간에도 옵셔널에 대한 내용을 살펴보고 마무리를 하도록 하겠습니다.
여러 옵셔널 언래핑
저번 글에서는 옵셔널 변수를 언래핑하는 방법에 대해서 공부를 했는데 여러 옵셔널 변수를 한 번에 언래핑하는 방법도 존재하기 때문에 여러 옵셔널을 한 번에 언래핑하는 방법에 대해서 살펴보겠습니다.
여러 옵셔널 변수를 한 번에 언래핑하는 방법은 간단합니다. 바로 콤마를 사용하면 되는데 소스 코드를 보면서 설명하도록 하겠습니다.
(*일반적으로 ,는 or 연산자이지만 Swift에서는 ,는 and 연산자이다.)
var pet1: String?
var pet2: String?
pet1 = "cat"
pet2 = "dog"
if let firstPet = pet1, let secondPet = pet2 {
print(firstPet, secondPet)
} else {
print("nil")
}
먼저, pet1과 pet2라는 두 개의 변수를 선언합니다. 이 변수들은 옵셔널(Optional) 타입인 String?으로 선언되었습니다. 옵셔널 타입은 값이 있을 수도 있고, 없을 수도 있는 변수를 나타냅니다.
다음으로, pet1에 "cat"을 할당하고, pet2에 "dog"을 할당합니다.
그 다음 코드에서는 옵셔널 바인딩(optional binding)을 사용하여 두 개의 변수가 모두 값을 가지고 있는지 확인합니다. 두 개의 옵셔널 변수를 한 번에 언래핑 하기 위해서 이때 콤마가 중간에 사용이 되게 됩니다.
만약 두 변수가 모두 값이 있다면(if let firstPet = pet1, let secondPet = pet2) 중괄호 안의 코드가 실행됩니다.
실행되는 코드에서는 첫 번째 반려동물 이름을 firstPet, 두 번째 반려동물 이름을 secondPet 상수로 사용하여 출력합니다.
만약 어느 하나라도 값이 없다면(else) "nil"이 출력됩니다.
따라서 이 예제에서는 "cat dog"이 출력됩니다.
만약 위 소스를 short form of if-let to the Optional Binding으로 변경하게 된다면 아래처럼 코드가 만들어지게 됩니다.
var pet1: String?
var pet2: String?
pet1 = "cat"
pet2 = "dog"
print(pet1)
print(pet2)
if let pet1, let pet2 {
print(pet1, pet2)
}
else{
print("nil")
}
두 가지 옵셔널 타입
옵셔널이 항상 유효한 값을 가질 경우 옵셔널이 암묵적인 언래핑(implicitly unwrapped)이 되도록 선언할 수도 있습니다. 이러한 방법은 클래스의 아웃렛 변수 초기화에서 많이 사용합니다.
이 방법으로 옵셔널이 선언된다면 강제 언래핑이나 옵셔널 바인딩을 하지 않아도 값에 접근할 수 있습니다. 암묵적인 언래핑으로 옵셔널을 선언하기 위해서는 선언부에 물음표(?) 대신에 느낌표(!)를 사용하면 됩니다.
var x : Int? //옵셔널 변수 선언 방법 1
var y : Int! //옵셔널 변수 선언 방법 2
Implicitly Unwrapped Optional(자동으로 언래핑 하는 옵셔널)
Implicitly Unwrapped Optional은 위에서 봤듯이 형 다음에 ?가 아닌 !를 쓰는 옵셔널 형입니다.
Int!, String! //Implicitly Unwrapped Optional
이렇게 말이죠.
암시적으로 래핑되지 않은 옵션 값을 사용할 경우 Swift는 먼저 이 값을 일반 옵션 값으로 사용하려고 합니다. 옵션으로 사용할 수 없는 경우 Swift는 값을 강제로 래핑합니다.
쉽게 말하자면 일반 옵셔널 값으로 사용하려고 하지만, Optional로 사용할 수 없는 경우 Swift는 값을 강제로 풀게 됩니다.
이 내용에서의 핵심은 Optional로 사용되지 않으면 자동으로 unwrap한다는 점입니다.
두 가지 Optional 형 : Int? vs Int!
두 옵셔널 형 예제를 살펴보겠습니다.
let x : Int? = 1
let y : Int = x!
let z = x
print(x,y,z) //Optional(1) 1 Optional(1)
print(type(of:x),type(of:y),type(of:z))
//Optional<Int> Int Optional<Int>
let a : Int! = 1 //Implicitly Unwrapped Optional
let b : Int = a //Optional로 사용되지 않으면 자동으로 unwrap함
let c : Int = a!
let d = a //Optional로 사용될 수 있으므로 Optional형임
let e = a + 1
print(a,b,c,d,e) //Optional(1) 1 1 Optional(1) 2
print(type(of:a),type(of:b),type(of:c),type(of:d), type(of:e))
//Optional<Int> Int Int Optional<Int> Int
Nil-Coalescing Operator (Nil합병 연산자) ??
Nil Coalescing Operator란, 옵셔널 변수/상수에 대해서 값이 nil인지 확인 후에 참이라면 미리 정해둔 값을 할당시키는 연산자입니다.
즉, Nil 합병 연산자는 nil일 때 할당되는 값으로 A ?? B의 형태로 사용하며, 여기서 A가 옵셔널, B는 A가 nil일 때 할당되는 값입니다.
옵셔널 변수의 값이 nil이 아니라면 언래핑된 값이 나오게 됩니다. 두 가지 예제를 살펴보겠습니다.
let defaultColor = "black"
var userDefinedColor: String? // defaults to nil
var myColor = userDefinedColor ?? defaultColor
//nil이므로 defaultColor인 black으로 할당됨
print(myColor) //black
userDefinedColor = "red"
myColor = userDefinedColor ?? defaultColor
//nil이 아니므로 언래핑된 red가 할당됨
print(myColor) //red, 주의 : optional(red)가 아님
let defaultAge = 1
var age : Int?
age = 3
print(age) //값은? : Optional(3)
var myAge = age ?? defaultAge //age가 nil이 아니므로 언래핑된 값이 나옴
print(myAge) //값은? : 3
// ?? : let defaultAge = 1
var age : Int?
age = 3
print(age) //값은? : Optional(3)
var myAge = age ?? defaultAge //age가 nil이 아니므로 언래핑된 값이 나옴
print(myAge) //값은? : 3
// ?? : Nil-Coalescing Operator
이번 시간에는 저번 시간에 이어서 옵셔널의 개념과 여러 사용 방법 그리고 nil합병연산자에 대해서 알아보았습니다.
감사합니다.
틀린 부분이 있거나 더 좋은 내용 훈수 환영합니다!
공감과 댓글 부탁드립니다.
'Apple > Swift' 카테고리의 다른 글
[Swift] 제어문과 다양한 예제 정리 (0) | 2023.09.26 |
---|---|
[Swift] 업캐스팅과 다운캐스팅, Swift와 Kotlin 옵셔널의 차이 (0) | 2023.09.25 |
[Swift] Type Safety 개념, 옵셔널의 개념과 예시 (0) | 2023.09.19 |
[Swift] 데이터 타입, 상수, 변수의 개념과 예시 (0) | 2023.09.12 |
[Swift] for문을 이용한 특정 키워드 반복 출력 (2) | 2023.09.05 |