模式匹配
> 学习 match 表达式的穷尽匹配,掌握 if let / while let 简化写法和高级匹配模式。
match 控制流
基本用法
rust
▶ Runenum Coin {
Penny,
Nickel,
Dime,
Quarter,
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
fn main() {
println!("{}", value_in_cents(Coin::Penny)); // 1
println!("{}", value_in_cents(Coin::Quarter)); // 25
}match 是表达式
rust
▶ Runfn main() {
let number = 5;
// match 可以返回值
let description = match number {
1 => "一",
2 => "二",
3 => "三",
_ => "其他",
};
println!("{}", description);
}绑定值
rust
▶ Run#[derive(Debug)]
enum UsState {
Alabama,
Alaska,
California,
}
enum Coin {
Penny,
Nickel,
Dime,
Quarter(UsState),
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => {
println!("幸运的一分钱!");
1
},
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter(state) => {
println!("州纪念币:{:?}", state);
25
}
}
}if let 和 while let
if let 简洁匹配
rust
▶ Runfn main() {
let config_max = Some(3u8);
// 使用 if let(简洁)
if let Some(max) = config_max {
println!("最大值:{}", max);
}
// 等同于 match(冗长)
match config_max {
Some(max) => println!("最大值:{}", max),
_ => {}
}
}if let else
rust
▶ Runfn main() {
let coin = Some(5u8);
if let Some(value) = coin {
println!("值是:{}", value);
} else {
println!("没有值");
}
// 链式 if let
let x = Some(5);
if let Some(n) = x {
if n > 0 {
println!("正数");
}
}
}while let 循环
rust
▶ Runfn main() {
// 弹出栈直到空
let mut stack = vec![1, 2, 3, 4, 5];
while let Some(top) = stack.pop() {
println!("弹出:{}", top);
}
// 迭代器
let mut iter = vec![1, 2, 3].into_iter();
while let Some(value) = iter.next() {
println!("值:{}", value);
}
}模式匹配高级模式
匹配字面量
rust
▶ Runfn main() {
let number = 5;
match number {
0 => println!("零"),
1 | 3 | 5 | 7 | 9 => println!("奇数"),
2 | 4 | 6 | 8 => println!("偶数"),
_ => println!("其他"),
}
}匹配范围
rust
▶ Runfn main() {
let number = 42;
match number {
0..=9 => println!("个位数"),
10..=99 => println!("十位数"),
100..=999 => println!("百位数"),
_ => println!("三位数以上"),
}
}匹配结构体
rust
▶ Runstruct Point {
x: i32,
y: i32,
}
fn main() {
let p = Point { x: 0, y: 10 };
match p {
// 解构所有字段
Point { x, y } => println!("x={}, y={}", x, y),
}
// 带条件匹配
match p {
Point { x: 0, y } => println!("在 Y 轴上,y={}", y),
Point { x, y: 0 } => println!("在 X 轴上,x={}", x),
Point { x, y } => println!("普通点,x={}, y={}", x, y),
}
// 忽略部分字段
match p {
Point { x, .. } => println!("x={}", x),
}
}匹配守卫(match guard)
rust
▶ Runfn main() {
let number = Some(4);
match number {
Some(x) if x < 5 => println!("小于 5"),
Some(x) if x >= 5 => println!("大于等于 5"),
None => println!("无值"),
_ => {}
}
// 多个条件
let (num, even) = (4, true);
match (num, even) {
(n, true) if n > 0 => println!("正偶数"),
(n, true) if n < 0 => println!("负偶数"),
(n, false) if n > 0 => println!("正奇数"),
_ => println!("其他"),
}
}匹配元组和数组
rust
▶ Runfn main() {
// 匹配元组
let tuple = (1, "hello", 3.14);
match tuple {
(0, _, _) => println!("第一个元素是 0"),
(_, "hello", _) => println!("第二个元素是 hello"),
(x, y, z) => println!("x={}, y={}, z={}", x, y, z),
}
// 匹配数组/切片
let numbers = [1, 2, 3];
match numbers {
[1, _, _] => println!("以 1 开头"),
[_, 2, _] => println!("中间是 2"),
[_, _, 3] => println!("以 3 结尾"),
_ => println!("其他"),
}
}小结
match:穷尽匹配,必须处理所有情况,是表达式可返回值if let:简化单一模式匹配,适合只关心一个分支的情况while let:循环中匹配,常用于迭代器或栈操作- 匹配模式:字面量
|、范围..=、解构、守卫if
练习题
详见:练习题