可选类型 #
一、可选类型概述 #
可选类型(Optional)是Swift的核心特性之一,用于处理值可能缺失的情况。可选类型表示一个值可能存在,也可能为nil。
1.1 为什么需要可选类型 #
在其他语言中,null/nil可能导致运行时错误:
swift
var middleName: String? = nil
if let name = middleName {
print("中间名是: \(name)")
} else {
print("没有中间名")
}
1.2 可选类型的本质 #
可选类型是一个枚举:
swift
enum Optional<Wrapped> {
case none
case some(Wrapped)
}
二、声明可选类型 #
2.1 基本声明 #
swift
var name: String? = "Swift"
var age: Int? = 25
var score: Double? = nil
print(name)
print(age)
print(score)
2.2 隐式解包可选类型 #
swift
var name: String! = "Swift"
print(name)
name = nil
2.3 可选类型的默认值 #
swift
var name: String?
var age: Int? = nil
var score: Double? = 0.0
三、解包可选类型 #
3.1 强制解包 #
使用 ! 强制解包:
swift
var name: String? = "Swift"
print(name!)
name = nil
3.2 可选绑定(if let) #
swift
var name: String? = "Swift"
if let unwrappedName = name {
print("名字是: \(unwrappedName)")
} else {
print("没有名字")
}
3.3 可选绑定(guard let) #
swift
func greet(name: String?) {
guard let unwrappedName = name else {
print("没有名字")
return
}
print("你好, \(unwrappedName)!")
}
greet(name: "Swift")
greet(name: nil)
3.4 多个可选绑定 #
swift
let firstName: String? = "张"
let lastName: String? = "三"
if let first = firstName, let last = lastName {
print("全名: \(first)\(last)")
}
3.5 可选绑定附加条件 #
swift
let age: Int? = 25
if let unwrappedAge = age, unwrappedAge >= 18 {
print("成年人,年龄: \(unwrappedAge)")
}
四、空合并运算符 #
4.1 基本用法 #
swift
let name: String? = nil
let displayName = name ?? "匿名"
print(displayName)
4.2 链式使用 #
swift
let nickname: String? = nil
let username: String? = nil
let defaultName = "匿名"
let displayName = nickname ?? username ?? defaultName
print(displayName)
4.3 实际应用 #
swift
func getUserName() -> String? {
return nil
}
let userName = getUserName() ?? "默认用户"
print(userName)
五、可选链 #
5.1 基本概念 #
可选链允许在可选值上调用方法、属性和下标:
swift
class Person {
var name: String
var address: Address?
init(name: String) {
self.name = name
}
}
class Address {
var city: String
var street: String?
init(city: String) {
self.city = city
}
}
let person = Person(name: "张三")
let city = person.address?.city
print(city ?? "未知城市")
5.2 多层可选链 #
swift
let street = person.address?.street?.uppercased()
print(street ?? "未知街道")
5.3 方法调用 #
swift
class Calculator {
func add(_ a: Int, _ b: Int) -> Int {
return a + b
}
}
var calc: Calculator? = Calculator()
let result = calc?.add(1, 2)
print(result ?? 0)
calc = nil
let nilResult = calc?.add(1, 2)
print(nilResult ?? 0)
5.4 下标访问 #
swift
var numbers: [Int]? = [1, 2, 3, 4, 5]
let first = numbers?[0]
print(first ?? 0)
numbers = nil
let nilFirst = numbers?[0]
print(nilFirst ?? 0)
六、可选类型的高级用法 #
6.1 map和flatMap #
swift
let number: Int? = 5
let doubled = number.map { $0 * 2 }
print(doubled ?? 0)
let stringNumber: String? = "42"
let parsed = stringNumber.flatMap { Int($0) }
print(parsed ?? 0)
6.2 compactMap #
swift
let strings = ["1", "2", "three", "4", "five"]
let numbers = strings.compactMap { Int($0) }
print(numbers)
6.3 filter可选值 #
swift
let values: [Int?] = [1, nil, 3, nil, 5]
let nonNil = values.compactMap { $0 }
print(nonNil)
七、处理可选类型的模式 #
7.1 提前返回 #
swift
func process(name: String?) {
guard let name = name, !name.isEmpty else {
print("名字无效")
return
}
print("处理名字: \(name)")
}
7.2 默认值模式 #
swift
func getConfiguration() -> [String: String] {
return ["timeout": "30"]
}
let config = getConfiguration()
let timeout = Int(config["timeout"] ?? "10") ?? 10
print(timeout)
7.3 条件绑定链 #
swift
func validateUser(name: String?, age: Int?) -> Bool {
guard let name = name,
let age = age,
!name.isEmpty,
age >= 18 else {
return false
}
return true
}
八、隐式解包可选类型 #
8.1 使用场景 #
swift
class ViewController {
var label: UILabel!
func viewDidLoad() {
label = UILabel()
label.text = "Hello"
}
}
8.2 风险 #
swift
var name: String! = "Swift"
print(name)
name = nil
print(name)
8.3 最佳实践 #
swift
class MyClass {
private(set) var optionalValue: String?
func configure() {
optionalValue = "Configured"
}
func useValue() {
guard let value = optionalValue else {
return
}
print(value)
}
}
九、常见错误 #
9.1 强制解包nil #
swift
var name: String? = nil
print(name!)
9.2 忽略可选值 #
swift
func process(_ value: Int?) {
let doubled = value! * 2
print(doubled)
}
process(nil)
9.3 过度使用隐式解包 #
swift
var name: String! = "Swift"
var greeting = "Hello, \(name)"
name = nil
十、总结 #
本章学习了Swift的可选类型:
- 声明:使用
?声明可选类型 - 解包:强制解包、可选绑定
- 空合并:使用
??提供默认值 - 可选链:安全访问可选值的成员
最佳实践:
- 优先使用可选绑定而非强制解包
- 使用guard let进行提前返回
- 合理使用空合并运算符
- 避免过度使用隐式解包
下一章,我们将学习类型转换!
最后更新:2026-03-26