5.3 模式匹配(match 和 if let)
模式匹配是 Rust 的一个强大特性,允许开发者根据数据的形态来执行不同的操作。Rust 提供了 match 和 if let 两种方式来处理模式匹配。
5.3.1 match 表达式
match 是 Rust 中最常用的模式匹配工具,类似于其他语言中的 switch 语句,但更加强大和灵活。match 语句可以匹配多种模式,支持各种复杂的匹配方式,包括常量匹配、范围匹配、枚举匹配、元组匹配等。
基本语法
1
2
3
4
5
6
7
8
9
10
|
fn main() {
let number = 13;
match number {
1 => println!("One"),
2 => println!("Two"),
3 => println!("Three"),
_ => println!("Other"), // _ 表示匹配所有其他值
}
}
|
match 后面跟一个待匹配的值。
- 每个分支后面跟一个模式,如果匹配成功,执行相应的代码块。
_ 是通配符,用于匹配所有其他未明确列出的值。
5.3.2 匹配多个模式
match 可以使用竖线 | 来匹配多个值。
示例
1
2
3
4
5
6
7
8
9
|
fn main() {
let number = 7;
match number {
1 | 2 | 3 => println!("Small number"),
4..=6 => println!("Medium number"), // 范围匹配
_ => println!("Other"),
}
}
|
1 | 2 | 3 使得匹配多个值,4..=6 匹配数字范围。
5.3.3 匹配枚举类型
Rust 中的枚举类型在 match 表达式中非常有用,match 可以匹配枚举的每一个变体,并且可以绑定相关的数据。
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
enum Direction {
Up,
Down,
Left,
Right,
}
fn main() {
let direction = Direction::Up;
match direction {
Direction::Up => println!("Going up!"),
Direction::Down => println!("Going down!"),
Direction::Left => println!("Going left!"),
Direction::Right => println!("Going right!"),
}
}
|
绑定枚举中的数据
枚举可以包含数据,match 也可以直接绑定这些数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
}
fn main() {
let msg = Message::Move { x: 10, y: 20 };
match msg {
Message::Quit => println!("Quit"),
Message::Move { x, y } => println!("Move to x: {}, y: {}", x, y),
Message::Write(text) => println!("Write: {}", text),
}
}
|
Message::Move { x, y } 会解构 Move 枚举并将 x 和 y 的值绑定到相应的变量。
5.3.4 匹配元组
match 还支持对元组进行解构,并将元组中的每个元素绑定到不同的变量上。
示例
1
2
3
4
5
6
7
8
9
10
|
fn main() {
let coordinates = (3, 5);
match coordinates {
(0, 0) => println!("Origin"),
(x, 0) => println!("On the X axis at {}", x),
(0, y) => println!("On the Y axis at {}", y),
(x, y) => println!("Point at ({}, {})", x, y),
}
}
|
5.3.5 match 的强大功能
匹配范围
Rust 的 match 支持对范围进行匹配,例如匹配整数范围。
1
2
3
4
5
6
7
8
9
|
fn main() {
let number = 5;
match number {
1..=5 => println!("Between 1 and 5"),
6..=10 => println!("Between 6 and 10"),
_ => println!("Other"),
}
}
|
匹配 Option 和 Result
Rust 标准库中的 Option 和 Result 类型常常使用 match 来解构和处理。
Option 类型示例
1
2
3
4
5
6
7
8
|
fn main() {
let some_number = Some(10);
match some_number {
Some(x) => println!("Got a number: {}", x),
None => println!("No number"),
}
}
|
Result 类型示例
1
2
3
4
5
6
7
8
|
fn main() {
let result: Result<i32, &str> = Ok(200);
match result {
Ok(value) => println!("Success: {}", value),
Err(error) => println!("Error: {}", error),
}
}
|
5.3.6 if let 表达式
if let 是一种简化的模式匹配方式,通常用于只关心一种情况的场景。它允许在条件语句中进行模式匹配,同时将匹配的值绑定到变量上。
基本用法
1
2
3
4
5
6
7
8
9
|
fn main() {
let some_number = Some(10);
if let Some(x) = some_number {
println!("Got a number: {}", x);
} else {
println!("No number");
}
}
|
if let 简化了只关心某个特定匹配的场景,不需要写完整的 match 语句。
与 match 的比较
if let 用于匹配某一种情况并执行代码,若不匹配则进入 else 分支。
match 用于处理多个情况,并且能够精确控制每一种匹配的行为。
5.3.7 总结
match 是 Rust 的强大工具,能够匹配各种复杂的数据结构,广泛应用于枚举类型、元组、范围和 Option/Result 等。
if let 提供了一种简化模式匹配的方式,适用于只关心一种匹配情况的场景。
- 在使用
match 时,Rust 强制开发者覆盖所有可能的匹配分支,这有助于避免遗漏某些情况。
通过合理使用 match 和 if let,可以让代码更加简洁且富有表达力。下一节我们将介绍 Rust 中常见的错误处理方式。