Rust基础

第7课:模式匹配

🎯 本课目标

深入掌握Rust模式匹配的各种语法:解构、守卫、绑定、refutable/irrefutable模式。

1. match深度用法

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(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::ChangeColor(r, g, b) => {
            println!("颜色: rgb({}, {}, {})", r, g, b);
        }
    }
}

fn main() {
    process(Message::Move { x: 10, y: 20 });
    process(Message::Write(String::from("hello")));
}

✅ 编译验证通过

2. 结构体解构

struct Point { x: i32, y: i32 }

fn main() {
    let p = Point { x: 0, y: 7 };
    let Point { x, y } = p;
    let Point { x: a, y: b } = p;  // 重命名
    let Point { x, .. } = p;      // 部分解构

    match p {
        Point { x: 0, y } => println!("在y轴: {}", y),
        Point { x, y: 0 } => println!("在x轴: {}", x),
        Point { x, y } => println!("({}, {})", x, y),
    }
}

✅ 编译验证通过

3. 匹配守卫

fn main() {
    let num = Some(4);
    match num {
        Some(x) if x % 2 == 0 => println!("偶数: {}", x),
        Some(x) => println!("奇数: {}", x),
        None => println!("无值"),
    }

    let threshold = 10;
    match 15 {
        n if n > threshold => println!("{} > {}", n, threshold),
        n => println!("{} <= {}", n, threshold),
    }
}

✅ 编译验证通过

4. @绑定

fn main() {
    let age = 25;
    match age {
        n @ 0..=12 => println!("儿童: {}岁", n),
        n @ 13..=19 => println!("青少年: {}岁", n),
        n @ 20..=59 => println!("成年人: {}岁", n),
        n @ 60.. => println!("老年人: {}岁", n),
    }
}

✅ 编译验证通过

5. Refutable vs Irrefutable

letfor只接受irrefutable;if letmatch接受refutable。

fn main() {
    // ✅ Irrefutable
    let (x, y) = (1, 2);

    // ❌ Refutable不能用在let中
    // let Some(x) = Some(5);  // 警告

    // ✅ let-else (Rust 1.65+)
    let Some(x) = Some(5) else {
        return;
    };
    println!("x = {}", x);
}

✅ 编译验证通过

6. 模式匹配的内存模型

枚举解构内存布局: Message::Write(String) ┌──────────────────────────┐ │ tag: 2 (Write变体) │ ← 1 byte + padding │ payload: │ │ ┌────────────────┐ │ │ │ ptr → "hello" │ │ │ │ len: 5 │ │ │ │ cap: 5 │ │ │ └────────────────┘ │ └──────────────────────────┘ Message::Write(text) ← text获得所有权 Message::Write(ref text) ← text只是引用

📝 练习题

练习1:表达式求值器

enum Expr {
    Lit(i32),
    Add(Box<Expr>, Box<Expr>),
    Mul(Box<Expr>, Box<Expr>),
    Neg(Box<Expr>),
}

fn eval(e: &Expr) -> i32 {
    match e {
        Expr::Lit(n) => *n,
        Expr::Add(a, b) => eval(a) + eval(b),
        Expr::Mul(a, b) => eval(a) * eval(b),
        Expr::Neg(a) => -eval(a),
    }
}

练习2:JSON枚举

设计JSON值枚举并实现打印。

练习3:命令解析器

用模式匹配解析"ADD/GET/DEL key [value]"命令。

🏆

成就解锁:模式猎人

掌握Rust模式匹配——最优雅的特性之一

🔬 深度理解:Rust的设计哲学

Rust的设计遵循几个核心原则,理解这些原则能帮助你更好地使用Rust:

1. 显式优于隐式

Rust要求你显式声明可变性(mut)、生命周期、错误处理。没有隐式类型转换、没有隐式异常传播、没有隐式GC。虽然代码更冗长,但行为更可预测。

2. 编译期检查优于运行时检查

借用检查器、生命周期分析、trait约束——所有这些都在编译期完成。这意味着运行时零开销。你付出的代价是编译时间,换来的是运行时性能和安全。

3. 零成本抽象

高层抽象(泛型、trait、迭代器、async/await)编译后与手写底层代码一样高效。你不需要在抽象和性能之间做选择。

4. 所有权是核心

所有其他特性——借用检查、生命周期、并发安全——都建立在所有权模型之上。理解所有权,就理解了Rust。

📖 Rust发展历史

年份里程碑
2006Graydon Hoare开始Rust项目
2009Mozilla开始赞助
2010首次公开
2012第一个预发布版
2015Rust 1.0发布
2016-2024连续Stack Overflow最受喜爱语言
2022Linux内核接纳Rust
2023Android、Windows开始使用Rust
2024Rust基金会成立,生态系统成熟
2026你正在学习Rust!

💡 学习路径建议

基础阶段(1-2周):完成本课程第1-7课,重点理解所有权和借用。

进阶阶段(2-3周):完成第8-14课,掌握trait、泛型、智能指针。

系统阶段(2-3周):完成第15-21课,实际写并发程序。

网络阶段(2-3周):完成第22-28课,构建真实的网络服务。

实战阶段(持续):完成第29-35课,开始自己的项目。


📚 扩展阅读

以下资源帮助你深入学习本课主题:

🔑 关键术语回顾

本课涉及的核心概念,确保你理解每一个:

术语说明
所有权Rust内存管理的核心机制,每个值有唯一所有者
借用通过引用访问数据,不获取所有权
生命周期引用有效的范围,编译期分析工具
traitRust的接口/抽象机制,类似其他语言的接口
泛型参数化类型,零成本抽象
模式匹配强大的数据解构和分支机制
零成本抽象高层抽象不引入运行时开销
fearless concurrency编译器保证线程安全

💬 学习建议

  1. 动手编码 — 每个代码示例都在本地运行一遍
  2. 修改实验 — 故意改错代码,看编译器报什么错
  3. 完成练习 — 每课的练习题是巩固知识的关键
  4. 阅读源码 — 看标准库和优秀开源项目的实现
  5. 写项目 — 真正掌握需要构建真实项目

🤔 常见问题

Q: Rust学习曲线真的很陡吗?

A: 前期确实需要适应所有权和借用检查器,但一旦理解了,这些概念会让你的代码更可靠。大多数人2-4周就能上手。

Q: Rust适合什么项目?

A: 系统编程、Web服务、CLI工具、嵌入式、WASM、网络服务、数据库等。基本上需要性能和安全的地方都适合。

Q: 遇到编译错误怎么办?

A: Rust编译器的错误信息非常友好!仔细阅读,通常会指出问题所在和修复建议。也可以用cargo clippy获取更多提示。