模式匹配(Pattern Matching)#
Rust 的 模式匹配 是一套強大的機制,能夠解構並檢查各種資料結構。
模式可以用在 match、if let、while let、for、let 和函數參數等地方。
1. 字面值模式#
直接比對具體的值:
1
2
3
4
5
6
7
8
9
10
| fn main() {
let x = 3;
match x {
1 => println!("一"),
2 => println!("二"),
3 => println!("三"),
_ => println!("其他"),
}
}
|
2. 綁定變數#
在 match 中將匹配到的值綁定到一個變數:
1
2
3
4
5
6
7
| fn main() {
let n = 42;
match n {
x => println!("匹配到 {x}"),
}
}
|
3. 多個模式(|)#
用 | 可以在同一個分支匹配多個模式:
1
2
3
4
5
6
7
8
9
| fn main() {
let x = 2;
match x {
1 | 2 => println!("一或二"),
3 | 4 => println!("三或四"),
_ => println!("其他"),
}
}
|
4. 範圍模式(..=)#
使用 ..= 匹配一個範圍內的值:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| fn classify(score: u32) -> &'static str {
match score {
90..=100 => "優",
80..=89 => "良",
70..=79 => "中",
60..=69 => "及格",
_ => "不及格",
}
}
fn main() {
println!("{}", classify(85)); // 良
println!("{}", classify(55)); // 不及格
}
|
5. 解構結構體#
match 可以解構結構體的欄位:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| struct Point {
x: i32,
y: i32,
}
fn main() {
let p = Point { x: 3, y: -5 };
match p {
Point { x: 0, y } => println!("在 Y 軸上,y = {y}"),
Point { x, y: 0 } => println!("在 X 軸上,x = {x}"),
Point { x, y } => println!("座標 ({x}, {y})"),
}
}
|
6. 解構枚舉#
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),
Color(u8, u8, u8),
}
fn process(msg: Message) {
match msg {
Message::Quit => println!("離開"),
Message::Move { x, y } => println!("移動到 ({x}, {y})"),
Message::Write(text) => println!("寫入:{text}"),
Message::Color(r, g, b) => println!("顏色 RGB({r}, {g}, {b})"),
}
}
|
7. 解構元組#
1
2
3
4
5
6
7
8
9
| fn main() {
let pair = (0, -1);
match pair {
(0, y) => println!("x 是零,y = {y}"),
(x, 0) => println!("y 是零,x = {x}"),
(x, y) => println!("({x}, {y})"),
}
}
|
8. 守衛條件(Match Guard)#
在 match 分支後加上 if 條件,只有條件成立時才匹配:
1
2
3
4
5
6
7
8
9
10
| fn main() {
let pair = (2, -3);
match pair {
(x, y) if x == y => println!("相等"),
(x, y) if x + y == 0 => println!("互為相反數"),
(x, _) if x % 2 == 0 => println!("x 是偶數"),
_ => println!("其他"),
}
}
|
9. @ 綁定#
@ 讓你在匹配範圍模式時,同時把匹配到的值綁定到變數:
1
2
3
4
5
6
7
8
9
| fn main() {
let n = 15;
match n {
x @ 1..=10 => println!("{x} 在 1 到 10 之間"),
x @ 11..=20 => println!("{x} 在 11 到 20 之間"),
x => println!("{x} 超出範圍"),
}
}
|
10. let 解構#
let 本身也支援模式,可以直接解構元組或結構體:
1
2
3
4
5
6
7
8
| fn main() {
let (a, b, c) = (1, 2, 3);
println!("{a}, {b}, {c}");
struct Point { x: i32, y: i32 }
let Point { x, y } = Point { x: 10, y: 20 };
println!("{x}, {y}");
}
|
11. 函數參數解構#
函數參數也可以直接解構:
1
2
3
4
5
6
7
8
| fn print_point(&(x, y): &(i32, i32)) {
println!("({x}, {y})");
}
fn main() {
let p = (3, 5);
print_point(&p);
}
|
Reference#
https://doc.rust-lang.org/book/ch18-00-patterns.html