1. 옵셔널 (Optional)
☝️ Swift는 기본적으로 nil(값 없음)을 허용하지 않지만 개발을 하다 보면 값이 없는 경우가 생기게 됩니다!
💡 이럴 때 사용할 수 있는 것이 Optional 입니다.
Optional을 사용하면 값이 없는 상황을 개발할 수 있습니다.
struct Person {
var name: String
var age: Int
var car: String? // ?를 붙여서 옵셔널 타입이라고 명시하여 값이 없을수도 있다고 알려줄 수 있어요
func introduce() {
print("안녕하세요. 제 이름은 \(name)이고, 나이는 \(age)살 입니다.")
}
}
Swift는 기본적으로 nil을 허용하지 않지만, Optional를 사용하면 값이 없을 수 있는 상태를 안전하게 처리할 수 있습니다.
- nil 키워드는 값이 없음을 의미합니다.
- 값이 없을 수 있는 상태를 옵셔널이라고 하며, 옵셔널 타입은 Nil 값을 저장할 수 있습니다.
- 기존 타입 뒤에 ? 키워드를 사용하여 옵셔널 타입으로 선언할 수 있습니다.
- 기본 타입 (Int, String, Float ...)
- Collection Type (Array, Dictionary, Set ...)
- Custom Type (struct, class, enum)
- 익명함수인 클로저
- 값을 할당할 때는 기존의 타입과 동일하게 사용하면 됩니다.
- 옵셔널 타입의 값에 접근하면 Optional로 감싸진 값이 나옵니다. Optional로 래핑 된 값이라고 부릅니다.
옵셔널 타입 선언 및 사용 방법
옵셔널 타입으로 선언하는 방법
// 기본 타입 옵셔널로 선언하기
var intValue: Int?
var stringValue: String?
// Collection Type 옵셔널로 선언하기
var array: [String]?
var dictionary: [String: String]?
// struct, class, enum을 타입처럼 사용하므로 Optional로 선언할 수 있습니다.
struct Person {
let name: String
}
var optionalPerson: Person?
// 클로저 옵셔널로 선언하기
var closure: (() -> Void)?
옵셔널 타입을 사용하는 방법 (할당과 접근)
// 값을 할당할 때는 기존의 타입과 동일하게 사용하면 됩니다.
var intValue: Int? = 1
var stringValue: String?
stringValue = "안녕하세요"
var nilValue: String? = nil
struct Person {
let name: String
}
var optionalPerson: Person? = Person(name: "Brody")
var closure: (() -> Void)? = {
print("Fire")
}
// 값에 접근하면 Optional로 래핑된 값으로 나옵니다.
print(intValue) // Optional(1) : 옵셔널로 래핑된 값 1이 출력됩니다.
print(stringValue) // Optional("안녕하세요") : 옵셔널로 래핑된 값 "안녕하세요"가 출력됩니다.
print(nilValue) // nil : 값이 없음을 의미하는 nil이 출력됩니다.
Optional 값은 기본 타입과 연산이 불가능합니다.
- 옵셔널 타입과 기본 타입은 다른 타입이기 때문에 연산이 불가능합니다.
- 비교 연산자 사용 가능합니다.
var intValue: Int? = 5
intValue += 5 // Error 발생
// Value of optional type 'Int?' must be unwrapped to a value of type 'Int'
// Int? 타입은 Int 타입과 다르기 때문에 컴파일 오류 발생!
- 옵셔널과 기본 타입의 차이로 인해 연산이 불가능합니다.
- 옵셔널 값에서 값만 추출하는 언래핑 작업을 통해 기본 타입으로 변환하여 사용해야 합니다.
2. 옵셔널 체이닝 (Optional Chaining)
📚 옵셔널 체이닝은 옵셔널 타입을 포함하는 폭잡한 데이터 구조에서 옵셔널 값이 nil 인지를 간결하게 체크하고 접근할 수 있는 방법입니다.
- 여러 중첩된 프로퍼티나 메소드 호출을 한줄로 처리할 수 있으며, 중간에 nil이 있는 경우 자동으로 nil을 반환합니다.
- 옵셔널 체이닝은 옵셔널 값에 대해 접근할 때마다 안전하게 처리할 수 있습니다.
- 옵셔널 값에 접근할 때 프로퍼티나 메소드 이름 뒤에 ?를 붙여서 체이닝할 수 있습니다.
struct Person {
var name: String = "Default Name"
var animal: Animal? // 사람 struct은 반려동물이 있을 수도 있고 없을수도 있어요!
}
struct Animal {
let name: String
var age: Int? // 언제 태어난지 모른다면 나이를 정할 수 없어서 Optional 타입으로 설정
}
let person: Person? = Person(name: "Brody", animal: nil)
print(person?.animal?.name) // person은 옵셔널 값이여서 ?를 붙였으며, nil이 아니에요. 다음으로 넘어갑니다.
// animal?을 확인해보니 nil이여서 nil을 반환합니다.
// 출력 값 : nil
let person2 = Person(name: "Brody", animal: Animal(name: "Dog", age: 5))
print(person2.animal?.name) // person2는 옵셔널이 아니기 때문에 ?를 붙이지 않아요
// animal?을 확인하니 값이 있군요! 다음으로 넘어갑니다.
// name은 값이 있어서 Animal의 "Dog"를 옵셔널 래핑하여 반환합니다
// 출력 값 : Optional("Dog")
let stringValue: String? = "안녕하세요"
print(stringValue?.count) // Optional(5)
// 옵셔널 체이닝으로 연결되어 있기 때문에 Optional로 래핑된 값이 출력됩니다.
// 옵셔널 값이기 때문에 언래핑하여 사용하면 됩니다!
- person?.animal?.name <- 처럼 사용됩니다.
- 옵셔널 값에 ?를 붙인 후 .을 사용하면 중첩된 프로퍼티나 메소드에 접근할 수 있습니다.
- 중첩된 값 중 하나라도 nil이면 전체값을 nil을 반환합니다.
- 중첩된 값이 모두 nil이 아니라면 Optional로 래핑된 값을 반환합니다
3. 실습하기
import UIKit
// 옵셔널 실습하기
// 1. 옵셔널 기본 실습
// 변수나 상수에 타입을 넣으면서 테스트 해보기
var stringValue: String?
print(stringValue)
stringValue = "Hello"
print(stringValue)
var intValut: Int? = 123
var floatValue: Float? = 15.1
var boolValue: Bool? = false
print(intValut)
print(floatValue)
print(boolValue)
// var intValut2 = intValut + 15 // Error 발생 (옵셔널 타입과 기본 타입은 연산 불가능)
print(intValut == 123)
// 2. struct 옵셔널 체이닝 사용하기
struct Dog {
var toy: String?
}
struct Person {
var pet: Dog?
}
let person1: Person? = nil
print(person1?.pet?.toy) // person1이 nil이어서 최종 nil 출력
let person2: Person? = Person(pet: nil)
print(person2?.pet?.toy) // pet이 nil이어서 최종 nil 출력
let person3: Person? = Person(pet: Dog(toy: "AAA"))
print(person3?.pet?.toy) // Optional("AAA") 출력
// 3. 클로저 옵셔널 체이닝 사용하기
var optionalClosure: ((Int) -> Void)? = { value in
print(value)
}
optionalClosure?(3) // 3 출력
'스파르타 코딩 클럽 - iOS 스타터 6기 > 본 캠프' 카테고리의 다른 글
16. 스파르타 코딩 클럽 - 접근제어자 (0) | 2025.03.17 |
---|---|
15. 스파르타 코딩 클럽 - 옵셔널 언래핑 (0) | 2025.03.17 |
13. 스파르타 코딩 클럽 - 프로그래밍 기초 주차 과제 Lv3 (0) | 2025.03.14 |
12. 스파르타 코딩 클럽 - 열거형 (Enum) (1) | 2025.03.13 |
11. 스파르타 코딩 클럽 - 클로저 (Closure) (0) | 2025.03.12 |