Skip to content

模式匹配

模式表示单个值或复合值的结构。例如,元组 (1, 2) 的结构是两个元素的逗号分隔列表。由于模式表示值的结构而不是某个特定值,因此您可以将它们与各种值进行匹配。例如,模式 (x, y) 可以匹配元组 (1, 2) 以及任何其他双元素元组。除了将模式与值匹配之外,您还可以提取复合值的部分或全部,并将每个部分绑定到常量或变量名。

在 Swift 中,有两种基本类型的模式:

  1. 成功匹配任何类型的值的模式
    用于解构简单变量、常量和可选绑定中的值。包括:

    • 通配符模式
    • 标识符模式
    • 包含它们的值绑定或元组模式
  2. 运行时可能无法匹配指定值的模式
    用于完全模式匹配,包括:

    • 枚举 case 模式
    • 可选模式
    • 表达式模式
    • 类型转换模式

模式语法

模式 → 通配符模式类型注释?
模式 → 标识符模式类型注释?
模式 → 值绑定模式
模式 → 元组模式类型注释?
模式 → 枚举案例模式
模式 → 可选模式
模式 → 类型转换模式
模式 → 表达模式

通配符模式

通配符模式匹配并忽略任何值,由下划线 (_) 组成。

swift
for _ in 1...3 {
    // 执行三次
}

语法
通配符模式 → _

标识符模式

标识符模式匹配任意值,并将匹配的值绑定到变量或常量名称。

swift
let someValue = 42  // someValue 是标识符模式

语法
标识符模式 → 标识符

值绑定模式

将匹配的值绑定到变量或常量名称。

swift
let point = (3, 2)
switch point {
case let (x, y):  // 值绑定模式
    print("坐标: (\(x), \(y))")
}
// 输出: "坐标: (3, 2)"

语法
值绑定模式 → var 模式 | let 模式

元组模式

逗号分隔的零个或多个模式列表,用括号括起。

swift
let (x, y): (Int, Int) = (1, 2)  // 约束为Int类型

语法

元组模式 → (元组模式元素列表?)
元组模式元素列表 → 元组模式元素 | 元组模式元素, 元组模式元素列表
元组模式元素 → 模式 | 标识符: 模式

枚举用例模式

匹配现有枚举类型的用例。

swift
enum Direction { case north, south }
let dir = Direction.north
switch dir {
case .north: print("向北")
case .south: print("向南")
}

语法
枚举案例模式 → 类型标识符?.枚举案例名称元组模式?

可选模式

匹配 Optional 枚举的 some(Wrapped) 情况。

swift
let optionalInt: Int? = 42
if case let x? = optionalInt {  // 等价于 .some(let x)
    print(x)  // 输出42
}

语法
可选模式 → 标识符模式?

类型转换模式

有两种形式:isas

swift
let value: Any = 7
switch value {
case is String: print("是字符串")
case let num as Int: print("是数字\(num)")
default: break
}

语法

类型转换模式 → is模式 | as模式
is模式 → is类型
as模式 → 模式as类型

表达模式

表示表达式的值,仅出现在 switchcase 标签中。

swift
let point = (1, 2)
switch point {
case (0, 0): print("原点")
case (-2...2, -2...2): print("靠近原点")
default: print("坐标: \(point.0), \(point.1)")
}

语法
表达模式 → 表达式

模式匹配运算符

Swift 使用 ~= 运算符进行模式匹配。可以重载此运算符实现自定义匹配逻辑。

swift
// 重载~=运算符实现字符串与整数匹配
func ~= (pattern: String, value: Int) -> Bool {
    return pattern == "\(value)"
}

switch 42 {
case "42": print("匹配成功")
default: print("不匹配")
}
// 输出: "匹配成功"