rust的模式匹配的完整用法


一、if let 表达式

用途:简化单分支模式匹配,处理特定模式并忽略其他情况。

基本语法

if let Pattern = Expression {
    // 匹配成功时的逻辑
} else {
    // 匹配失败时的逻辑(可选)
}

示例

let opt = Some(42);

// 只处理 Some 情况
if let Some(x) = opt {
    println!("值为: {}", x); // 输出: 值为: 42
}

// 处理 Some 和 None
if let Some(50) = opt {
    println!("匹配到50");
} else {
    println!("未匹配到50"); // 输出: 未匹配到50
}

结合枚举和守卫

enum Message {
    Text(String),
    Number(i32),
}

let msg = Message::Number(7);

if let Message::Number(n) = msg && n % 2 == 0 {
    println!("偶数: {}", n);
} else {
    println!("奇数或无数字"); // 输出: 奇数或无数字
}

二、while let 表达式

用途:循环处理持续匹配某个模式的值,直到不匹配为止。

基本语法

while let Pattern = Expression {
    // 循环体逻辑
}

示例

let mut stack = vec![1, 2, 3];

// 持续弹出元素直到栈空
while let Some(top) = stack.pop() {
    println!("弹出: {}", top); // 依次输出3, 2, 1
}

处理复杂模式

let mut data = vec![Some(4), None, Some(6)];

// 仅处理 Some 值且大于5的情况
while let Some(Some(x)) = data.pop() && x > 5 {
    println!("处理 {}", x); // 输出: 处理6
}

三、嵌套模式匹配

用途:解构嵌套的数据结构(如元组、枚举、结构体等)。

示例

enum Color {
    Rgb(u8, u8, u8),
    Hsv(u8, u8, u8),
}

let color = Color::Rgb(255, 0, 128);

match color {
    Color::Rgb(r, g, b) if g == 0 => {
        println!("纯红色,蓝色分量: {}", b); // 输出: 纯红色,蓝色分量: 128
    }
    _ => println!("其他颜色"),
}

嵌套解构Option

let nested = Some(Some(10));

match nested {
    Some(Some(inner)) => println!("内部值: {}", inner), // 输出: 内部值: 10
    Some(None) => println!("内部为None"),
    None => println!("外层为None"),
}

四、@ 绑定

用途:在匹配模式的同时将值绑定到变量,便于后续使用。

基本语法

Pattern @ SubPattern

示例

范围匹配

let age = 25;

match age {
    a @ 0..=17 => println!("未成年,年龄: {}", a),
    a @ 18..=120 => println!("成年,年龄: {}", a), // 输出: 成年,年龄: 25
    _ => unreachable!(),
}

结构体字段绑定

struct Point { x: i32, y: i32 }

let p = Point { x: 5, y: 20 };

match p {
    Point { x: x_val @ 0..=10, y: y_val @ 15..=25 } => {
        println!("x在0-10: {}, y在15-25: {}", x_val, y_val); // 输出匹配
    }
    _ => (),
}

枚举值绑定

enum Result<T> {
    Ok(T),
    Err(String),
}

let result = Result::Ok(42);

match result {
    Result::Ok(num @ 0..=100) => println!("有效值: {}", num), // 输出: 有效值: 42
    Result::Ok(num) => println!("超出范围的值: {}", num),
    Result::Err(e) => println!("错误: {}", e),
}

五、组合使用技巧

  1. if let@ 绑定

    if let Some(x @ 1..=5) = Some(3) {
        println!("匹配到1-5的值: {}", x); // 输出: 3
    }
    
  2. 嵌套 if let

    let triple = Some(Some(Some(7)));
    
    if let Some(Some(Some(n))) = triple {
        println!("深度嵌套的值: {}", n); // 输出: 7
    }
    
  3. while let 与复杂模式

    let mut data = vec![Some(5), None, Some(8)];
    
    while let Some(Some(x @ 5..=10)) = data.pop() {
        println!("处理有效值: {}", x); // 输出: 8, 5
    }
    

六、注意事项

  1. 所有权问题:模式匹配可能触发移动,使用 refref mut 避免:

    let name = Some(String::from("Rust"));
    if let Some(ref s) = name {
        println!("借用的值: {}", s); // 不会移动所有权
    }
    
  2. 穷尽性检查match 必须处理所有可能分支,而 if letwhile let 仅处理指定模式。


Read more

Trait系统的细节:Sized、Dyn Trait、impl Trait、关联类型(Associated Types)

1. Sized:类型大小 底层原理 * 内存对齐:Sized 类型在栈上分配时,编译器必须知道其确切大小和对齐要求 * 类型系统守卫:Rust 默认要求泛型参数满足 T: Sized,因为编译器需要为泛型代码生成具体实现 * DST 的妥协:?Sized 放松约束,允许处理如 [T] 或 dyn Trait 等动态类型 深入示例 // 展示 Sized 的隐式约束 fn generic_fn<T>(t: T) {} // 实际等价于 fn generic_fn<T: Sized>(t: T) // 处理动态类型需要指针包装 fn unsized_types(

By amm

Rust所有权与生命周期底层机制

一、所有权系统(Ownership System) 1. 内存管理基础 * 基于栈(Stack)和堆(Heap)的差异: * 栈:自动管理,FILO结构,存储固定大小类型 * 堆:动态分配,存储不定大小类型,需要显式管理 * Rust 采用"谁创建谁负责释放"的原则,无垃圾回收机制 2. 所有权规则实现 * 每个值有且仅有一个所有者(Owner) * 当值被绑定到变量时,该变量成为值的所有者 * 当所有者离开作用域时,值会被自动释放(调用 drop trait) 3. 移动语义(Move Semantics) * 赋值操作默认执行移动而非拷贝: let s1 = String::from("hello"); let

By amm

© 2025 路不易All rights reserved.

备案号:黔ICP备2025043243号-1 | 公安备案图标 贵公网安备52052402000220号