可选类型 #

一、可选类型概述 #

可选类型(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