19-模式与模式匹配

模式出现位置、可反驳性、解构与匹配守卫等模式语法精要

精要笔记 · 基于 TRPL 简体中文 第19章

模式与模式匹配

模式(pattern)描述数据形状,与值匹配后可用其中的命名部分。组成:字面值、解构、变量、通配符、占位符。

所有可以使用模式的位置

match 分支

1
2
3
match VALUE {
    PATTERN => EXPRESSION,
}
  • 必须穷尽(exhaustive);最后一支常用 _ 捕获剩余情况。
  • _ 匹配任意值但不绑定变量。

let 语句

1
let PATTERN = EXPRESSION;
  • let x = 5; 中 x 就是模式;可解构元组:let (x, y, z) = (1, 2, 3);
  • 元素数量须与模式一致,否则编译错误;可用 _ / .. 忽略多余项。

条件 if let 表达式

  • 简写只匹配一种情况的 match;可有 else / else if / else if let。
  • 模式可引入新变量并遮蔽外部同名变量。
  • 不检查穷尽性——漏分支编译器不报错。

while let 条件循环

  • 模式持续匹配时循环;如 while let Ok(value) = rx.recv() 处理信道消息。

for 循环

  • for x in y 中 x 是模式;enumerate 配合 (index, value) 解构常见。

函数参数

  • 参数列表即模式;可解构元组:fn print_coords(&(x, y): &(i32, i32))。
  • 闭包参数同理。

可反驳性:模式是否可能匹配失败

类型含义示例
不可反驳对任意值都能匹配let x = 5; 中的 x
可反驳某些值匹配失败Some(x) 对 None 失败

只能不可反驳:let、for、函数参数。

可两种:if let、while let、let...else(不可反驳会警告)。

  • let Some(x) = opt; ❌ → 改用 let...else 处理失败分支。
  • match 分支须可反驳,最后一支除外(应用不可反驳模式兜底)。

模式语法

匹配字面值

直接匹配具体值:1、'a'、true。

匹配命名变量

  • match / if let / while let 内声明的变量遮蔽外部同名变量。
  • 需比较外部变量时用匹配守卫(见下)。

匹配多个模式

| 表示或:1 | 2 匹配 1 或 2。

通过 ..= 匹配值范围

  • 闭区间:1..=5;仅 数字 和 char 可用(编译期可判空)。
  • 比 1 | 2 | 3 | 4 | 5 简洁。

解构并分解值

结构体

1
2
3
let Point { x, y } = p;           // 字段简写
let Point { x: a, y: b } = p;     // 重命名
let Point { x: 0, y } = p;        // 部分字段匹配字面值

枚举

  • 无数据变体:Message::Quit 仅匹配字面值。
  • 类结构体变体:Message::Move { x, y }。
  • 类元组变体:Message::Write(i)、ChangeColor(r, g, b)——变量数须与元素数一致。

嵌套的结构体和枚举

可嵌套匹配,如 Message::ChangeColor(Color::Rgb(r, g, b))。

结构体和元组

可混合嵌套解构。

忽略模式中的值

方式作用
_匹配但不绑定;函数参数忽略、match 兜底
嵌套 _Some(_) 只检测变体不关心内部值
_x以 _ 开头抑制未使用警告,仍会绑定/移动
单独 _不绑定,不获取所有权
..忽略剩余字段/元组元素;须无歧义

使用匹配守卫添加额外条件

  • 分支模式后加 if 条件:Some(x) if x % 2 == 0 => ...
  • 仅 match 可用;可比较外部变量避免遮蔽。
  • 4 | 5 | 6 if y => 中守卫作用于整个或模式:(4 | 5 | 6) if y。
  • 含守卫时编译器不检查穷尽性。

使用 @ 绑定

id @ 3..=7:测试范围的同时把匹配值绑定到 id。

总结

模式是 Rust 控制流核心;match 须穷尽。结合 let、函数参数可解构赋值。掌握可反驳性与各语法即可清晰表达分支逻辑。

最后修改 July 30, 2026: 更新 (33710aaae)