Skip to content

模式匹配

> 学习 match 表达式的穷尽匹配,掌握 if let / while let 简化写法和高级匹配模式。

match 控制流

基本用法

rust
enum 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
}
▶ Run

match 是表达式

rust
fn main() {
    let number = 5;

    // match 可以返回值
    let description = match number {
        1 => "一",
        2 => "二",
        3 => "三",
        _ => "其他",
    };

    println!("{}", description);
}
▶ Run

绑定值

rust
#[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
        }
    }
}
▶ Run

if let 和 while let

if let 简洁匹配

rust
fn main() {
    let config_max = Some(3u8);

    // 使用 if let(简洁)
    if let Some(max) = config_max {
        println!("最大值:{}", max);
    }

    // 等同于 match(冗长)
    match config_max {
        Some(max) => println!("最大值:{}", max),
        _ => {}
    }
}
▶ Run

if let else

rust
fn 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!("正数");
        }
    }
}
▶ Run

while let 循环

rust
fn 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);
    }
}
▶ Run

模式匹配高级模式

匹配字面量

rust
fn main() {
    let number = 5;

    match number {
        0 => println!("零"),
        1 | 3 | 5 | 7 | 9 => println!("奇数"),
        2 | 4 | 6 | 8 => println!("偶数"),
        _ => println!("其他"),
    }
}
▶ Run

匹配范围

rust
fn main() {
    let number = 42;

    match number {
        0..=9 => println!("个位数"),
        10..=99 => println!("十位数"),
        100..=999 => println!("百位数"),
        _ => println!("三位数以上"),
    }
}
▶ Run

匹配结构体

rust
struct 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),
    }
}
▶ Run

匹配守卫(match guard)

rust
fn 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!("其他"),
    }
}
▶ Run

匹配元组和数组

rust
fn 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!("其他"),
    }
}
▶ Run

小结

  • match:穷尽匹配,必须处理所有情况,是表达式可返回值
  • if let:简化单一模式匹配,适合只关心一个分支的情况
  • while let:循环中匹配,常用于迭代器或栈操作
  • 匹配模式:字面量 |、范围 ..=、解构、守卫 if

练习题

详见:练习题