Rust 语言教程 - 完整指南(增强版)

IT 技术 76 阅读 更新于 2026-09-04 06:29

1. Rust 简介与环境搭建

什么是 Rust

Rust 是由 Mozilla 研究院的 Graydon Hoare 设计的系统级编程语言,首次发布于 2010 年,2015 年发布 1.0 稳定版。它专注于安全性、速度和并发性,解决了 C/C++ 中常见的内存安全问题,同时提供了零成本抽象。

  • 内存安全:无垃圾回收机制,通过所有权系统保证内存安全
  • 零成本抽象:高级抽象不牺牲运行时性能
  • 并发无畏:编译期防止数据竞争
  • 跨平台:支持编译到几乎所有主流操作系统
  • 类型系统:强大的静态类型系统 + 类型推断
  • 模式匹配:强大的控制流和数据结构分解能力
  • 宏系统:元编程能力,可定义领域特定语言(DSL)

Rust 的应用场景

  • 系统编程:操作系统、驱动、内核模块(Linux 内核已支持 Rust)
  • Web 后端:Actix-web、Axum、Rocket、Warp 等高性能框架
  • WebAssembly:编译为 WASM 在浏览器运行
  • 命令行工具:ripgrep、bat、fd、exa 等替代传统工具
  • 嵌入式系统:no_std 环境下的嵌入式开发
  • 游戏开发:Bevy 引擎、游戏后端服务
  • 区块链:Solana、Polkadot、Near 等项目大量使用 Rust
  • DevOps 工具:Docker、Kubernetes 周边工具
  • 桌面应用:Tauri 框架(比 Electron 更轻量)

安装 Rust

推荐使用官方工具 rustup 安装 Rust:

# Linux / macOS
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 验证安装
rustc --version
cargo --version
rustup --version

# 更新 Rust
rustup update

# 安装特定版本
rustup install 1.75.0
rustup install stable
rustup install beta
rustup install nightly

# 切换默认版本
rustup default 1.75.0
rustup default stable

# 添加目标平台(交叉编译)
rustup target add wasm32-unknown-unknown
rustup target add x86_64-pc-windows-gnu

# 安装附加组件
rustup component add rust-src
rustup component add rustfmt
rustup component add clippy
rustup component add rust-analyzer

Windows 用户可从

https://rustup.rs

下载安装程序(需要 Microsoft C++ Build Tools),或使用 WSL2 安装 Linux 版本以获得最佳体验。

Hello World

创建你的第一个 Rust 程序:

// 手动编译运行
// 创建 main.rs
fn main() {
    println!("Hello, World!");
}

// 编译运行:
// rustc main.rs
// ./main (或 main.exe)

// 使用 Cargo(推荐):
// cargo new hello_world
// cd hello_world
// cargo run

Cargo 项目结构

my_project/
├── Cargo.toml          # 项目配置文件(类似 package.json)
├── Cargo.lock          # 依赖锁定文件
├── src/
│   ├── main.rs         # 二进制入口
│   ├── lib.rs          # 库入口
│   └── bin/            # 多个二进制程序
│       └── other_main.rs
├── tests/              # 集成测试
│   └── integration.rs
├── benches/            # 性能基准测试
│   └── my_benchmark.rs
├── examples/           # 示例代码
│   └── example.rs
├── build.rs            # 构建脚本
├── README.md
└── .gitignore

IDE 配置

推荐使用 VSCode + rust-analyzer 插件:

  • rust-analyzer:官方推荐的 LSP 服务器,提供代码补全、跳转、类型提示
  • Even Better TOML:TOML 语法高亮
  • crates:显示依赖版本信息
  • CodeLLDB:调试 Rust 程序

JetBrains CLion 也内置了强大的 Rust 支持(IntelliJ Rust 插件)。

Rust 版本(Edition)

Rust 每隔几年会发布一个新的 Edition,带来语法变化但不破坏兼容性:

  • 2015 Edition:初始版本
  • 2018 Edition:引入模块系统改进、async/await、? 运算符
  • 2021 Edition:数组 IntoIterator、闭包捕获改进
  • 2024 Edition:进一步简化语法和特性
# 在 Cargo.toml 中指定版本
[package]
edition = "2021"  # 或 "2024"

# 使用 rustup 迁移
cargo fix --edition
cargo fix --edition-idioms

2. 变量与数据类型

变量绑定

Rust 中变量默认是不可变的,使用 let 声明:

fn main() {
    // 不可变变量
    let x = 5;
    // x = 6;  // 编译错误!

    // 可变变量
    let mut y = 5;
    y = 6;  // OK

    // 常量(必须标注类型,必须大写)
    const MAX_POINTS: u32 = 100_000;
    const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;

    // Shadowing(变量遮蔽)
    let x = 5;
    let x = x + 1;       // x 现在是 6
    let x = x * 2;       // x 现在是 12
    let x = "hello";     // 可以改变类型
    
    // 静态变量(有固定内存地址,可以是 mut)
    static COUNTER: i32 = 0;
    static mut MUTABLE_GLOBAL: i32 = 0;  // 需要 unsafe 访问
}

const

vs

static

const

:编译时常量,可内联,无固定地址

static

:运行时静态变量,有固定地址,可用于 FFI

基本数据类型

Rust 是静态类型语言,主要标量类型:

整数类型

长度有符号无符号范围
8-biti8u8-128 ~ 127 / 0 ~ 255
16-biti16u16-32768 ~ 32767 / 0 ~ 65535
32-biti32u32-2^31 ~ 2^31-1
64-biti64u64-2^63 ~ 2^63-1
128-biti128u128-2^127 ~ 2^127-1
架构isizeusize随指针大小变化
// 整数类型
let a: i8 = -128;
let b: u8 = 255;
let c: i32 = 1_000_000;  // 默认 i32
let d: u64 = 42;
let e: isize = 10;

// 数字字面量
let decimal = 98_222;        // 十进制
let hex = 0xff;              // 十六进制
let octal = 0o77;            // 八进制
let binary = 0b1111_0000;    // 二进制
let byte = b'A';             // 字节 (u8)

// 整数方法
let x: i32 = -5;
let abs = x.abs();               // 5
let signum = x.signum();         // -1
let is_positive = x.is_positive();
let is_negative = x.is_negative();
let pow = 2i32.pow(10);        // 1024
let sqrt = 16.0f64.sqrt();       // 4.0
let checked = 10u8.checked_add(20); // Some(30)
let overflow = 255u8.checked_add(1); // None

// 溢出检查
// debug 模式下整数溢出会 panic
// release 模式下会绕回
let (result, overflow) = 255u8.overflowing_add(1);  // (0, true)
let wrapped = 255u8.wrapping_add(1);                // 0
let saturated = 255u8.saturating_add(1);            // 255

浮点类型

// 浮点类型
let f: f32 = 3.14;
let g: f64 = 3.1415926;  // 默认 f64

// 特殊值
let inf = f64::INFINITY;
let neg_inf = f64::NEG_INFINITY;
let nan = f64::NAN;
let max = f64::MAX;
let min = f64::MIN;
let epsilon = f64::EPSILON;

// 判断特殊值
let is_nan = nan.is_nan();
let is_finite = 1.0.is_finite();
let is_infinite = inf.is_infinite();

// 浮点方法
let x: f64 = -3.7;
x.abs();       // 3.7
x.floor();     // -4.0
x.ceil();      // -3.0
x.round();     // -4.0
x.trunc();     // -3.0
x.fract();     // -0.7
x.sin();       // 正弦
x.cos();       // 余弦
x.ln();        // 自然对数
x.log2();      // 以 2 为底
x.log10();     // 以 10 为底
x.powi(2);     // x^2
x.powf(2.5);   // x^2.5
x.sqrt();      // 平方根
x.cbrt();      // 立方根

布尔与字符类型

// 布尔类型
let is_true: bool = true;
let is_false = 1 > 2;

// 字符类型(4 字节 Unicode 标量值)
let letter: char = 'A';
let emoji: char = '🦀';
let chinese: char = '中';
let accented: char = 'é';

// 字符方法
let c = 'A';
c.is_alphabetic();     // true
c.is_numeric();        // false
c.is_alphanumeric();   // true
c.is_whitespace();     // false
c.is_uppercase();      // true
c.is_lowercase();      // false
c.to_lowercase();      // 'a'
c.to_uppercase();      // 'A'
c.to_digit(16);        // 转为数字
c.len_utf8();          // UTF-8 编码长度
c.len_utf16();         // UTF-16 编码长度
c.escape_unicode();    // Unicode 转义

复合类型

// 元组 (Tuple)
let tuple: (i32, f64, u8) = (500, 6.4, 1);
let (x, y, z) = tuple;    // 解构
let first = tuple.0;       // 索引访问
let second = tuple.1;

// 单元类型 (unit) - 空元组
let unit: () = ();

// 数组(固定长度,栈上分配)
let arr: [i32; 5] = [1, 2, 3, 4, 5];
let zeros = [0; 10];     // [0,0,0,0,0,0,0,0,0,0]
let first = arr[0];
let slice = &arr[1..3];   // &[2, 3]

// 数组方法
let arr = [1, 2, 3, 4, 5];
arr.len();                  // 5
arr.contains(&3);           // true
arr.iter().sum::<i32>();     // 15
arr.windows(2);            // 滑动窗口 [1,2], [2,3]...
arr.chunks(2);             // 分块
arr.sort();                 // 排序 (需要 mut)

类型转换

use std::convert::TryInto;

fn main() {
    let x: u32 = 10;
    let y: i64 = x as i64;       // as 关键字显式转换
    let z: f64 = y as f64;
    
    // 安全的类型转换
    let big: u64 = 1000;
    let small: u8 = big.try_into().unwrap();
    
    // 字符串与数字互转
    let num_str = "42";
    let num: i32 = num_str.parse().unwrap();
    let num: i32 = num_str.parse().unwrap_or(0);
    let back = num.to_string();
    
    // From / Into trait
    let s: String = "hello".into();
    let v: Vec<u8> = "hello".as_bytes().into();
}

使用

as

进行数值类型转换时,如果值超出目标类型范围,会发生截断而非报错。对于可能失败的场景,推荐使用

TryInto

TryFrom

checked_* / saturating_* / wrapping_*

方法。

3. 函数与控制流

函数定义

// 基本函数
fn greet(name: &str) {
    println!("Hello, {}!", name);
}

// 带返回值
fn add(a: i32, b: i32) -> i32 {
    a + b  // 最后一个表达式即为返回值(无分号)
}

// 多返回值
fn swap(a: i32, b: i32) -> (i32, i32) {
    (b, a)
}

// 发散函数(永不返回)
fn crash() -> ! {
    panic!("Boom!");
}

// 默认参数(Rust 不支持,使用 Option 或 builder 模式)
fn create_user(name: &str, age: Option<u32>) -> User {
    User {
        name: name.to_string(),
        age: age.unwrap_or(18),
    }
}

// 函数指针
fn apply(f: fn(i32) -> i32, x: i32) -> i32 {
    f(x)
}
fn double(x: i32) -> i32 { x * 2 }
let result = apply(double, 5);  // 10

// 外部函数(FFI)
extern "C" {
    fn abs(input: i32) -> i32;
}

// const fn(编译期可计算)
const fn square(n: i32) -> i32 {
    n * n
}
const SQUARE_FIVE: i32 = square(5);

// 内联函数
#[inline]
fn fast_add(a: i32, b: i32) -> i32 {
    a + b
}
#[inline(always)]  // 强制内联
fn always_inline() { }
#[inline(never)]   // 禁止内联
fn never_inline() { }

表达式与语句

fn main() {
    // 语句不返回值
    let x = 5;
    
    // 表达式有返回值
    let y = {
        let a = 3;
        let b = 4;
        a + b  // 无分号,作为返回值
    };
    
    // 注意:加分号变为语句,返回 ()
    let z = {
        let val = 10;
        val;   // 有分号,z 是 ()
    };
    
    // return 关键字
    fn early_return(x: i32) -> i32 {
        if x < 0 {
            return -1;
        }
        x
    }
}

条件语句

fn main() {
    let number = 7;
    
    // if 表达式
    if number < 5 {
        println!("小于 5");
    } else if number < 10 {
        println!("小于 10");
    } else {
        println!("大于等于 10");
    }
    
    // if 作为表达式赋值
    let result = if number % 2 == 0 {
        "偶数"
    } else {
        "奇数"
    };
    
    // 条件链 (let else - Rust 1.65+)
    let opt: Option<i32> = Some(42);
    let Some(val) = opt else {
        println!("不是 Some");
        return;
    };
    println!("值是: {}", val);
    
    // if let(简化单分支匹配)
    if let Some(val) = opt {
        println!("值是: {}", val);
    }
    
    // matches! 宏(判断是否符合模式)
    let msg = Message::Quit;
    if matches!(msg, Message::Quit) {
        println!("Quit 消息");
    }
}

循环

fn main() {
    // loop(无限循环)
    let mut counter = 0;
    let result = loop {
        counter += 1;
        if counter == 10 {
            break counter * 2;  // break 可返回值
        }
    };
    
    // 循环标签
    let mut count = 0;
    'outer: loop {
        let mut inner = 0;
        loop {
            if inner == 5 {
                break 'outer;  // 跳出外层循环
            }
            inner += 1;
        }
        count += 1;
    }
    
    // while 循环
    let mut n = 3;
    while n != 0 {
        println!("{}!", n);
        n -= 1;
    }
    
    // while let
    let mut stack = vec![1, 2, 3];
    while let Some(top) = stack.pop() {
        println!("{}", top);  // 3, 2, 1
    }
    
    // for 循环
    for i in 0..5 {
        println!("{}", i);  // 0,1,2,3,4
    }
    
    for i in 0..=5 {
        println!("{}", i);  // 0,1,2,3,4,5
    }
    
    let arr = [10, 20, 30];
    for (index, val) in arr.iter().enumerate() {
        println!("[{}]: {}", index, val);
    }
    
    // 反向迭代
    for i in (0..5).rev() {
        println!("{}", i);  // 4,3,2,1,0
    }
    
    // 步进
    for i in (0..10).step_by(2) {
        println!("{}", i);  // 0,2,4,6,8
    }
    
    // break 和 continue
    for i in 0..10 {
        if i == 3 { continue; }
        if i == 7 { break; }
        println!("{}", i);
    }
}

Match 表达式

fn describe_number(n: i32) -> &'static str {
    match n {
        1 => "一",
        2 | 3 => "二或三",
        4..=10 => "四到十",
        x if x < 0 => "负数",
        _ => "其他",
    }
}

// 匹配守卫(match guard)
let pair = (2, -2);
match pair {
    (x, y) if x + y == 0 => println!("互为相反数"),
    _ => println!("不是"),
}

// @ 绑定
enum Message { Hello { id: i32 } }
let msg = Message::Hello { id: 5 };
match msg {
    Message::Hello { id: id_variable @ 3..=7 } => {
        println!("Found id in range: {}", id_variable);
    }
    Message::Hello { id } => println!("Found other id: {}", id),
}

4. 所有权与借用

所有权规则

Rust 的核心特性,在编译时管理内存,无需垃圾回收:

  1. 每个值有且只有一个所有者(Owner)
  2. 同一时刻只能有一个所有者
  3. 当所有者离开作用域,值被丢弃(Drop)
  4. fn main() {
        // 栈上类型(Copy 语义)
        let x = 5;
        let y = x;  // 复制,x 仍可用
        println!("x={}, y={}", x, y);
        
        // 堆上类型(Move 语义)
        let s1 = String::from("hello");
        let s2 = s1;  // 移动所有权,s1 不再有效
        // println!("{}", s1);  // 编译错误!
        println!("{}", s2);
        
        // 克隆(深拷贝)
        let s3 = s2.clone();
        println!("s2={}, s3={}", s2, s3);
    }

    Copy vs Clone

    // Copy trait:按位复制,隐式发生
    // 实现了 Copy 的类型:所有整数、浮点、布尔、字符、仅含 Copy 类型的元组
    // String、Vec 等堆上类型不实现 Copy
    
    // Clone trait:显式调用 clone() 方法,深拷贝
    let s1 = String::from("hello");
    let s2 = s1.clone();
    
    // 自定义类型实现 Copy
    #[derive(Copy, Clone)]
    struct Point {
        x: i32,
        y: i32,
    }
    
    // 注意:如果类型包含非 Copy 字段(如 String),则不能 derive Copy
    // 但可以 derive Clone

    函数与所有权

    fn takes_ownership(s: String) {
        println!("{}", s);
    }  // s 被 drop
    
    fn makes_copy(n: i32) {
        println!("{}", n);
    }
    
    fn gives_back(s: String) -> String {
        s  // 返回所有权
    }
    
    // 同时返回值和原值
    fn calculate_length(s: String) -> (String, usize) {
        let length = s.len();
        (s, length)
    }
    
    fn main() {
        let s = String::from("hello");
        takes_ownership(s);
        // s 不再有效
        
        let n = 5;
        makes_copy(n);
        println!("{}", n);  // OK,i32 是 Copy
        
        let s2 = String::from("world");
        let s3 = gives_back(s2);
        println!("{}", s3);
    }

    引用与借用

    // 不可变引用 &T
    fn calculate_length(s: &String) -> usize {
        s.len()
    }  // s 离开作用域,但不会 drop 因为不拥有
    
    // 可变引用 &mut T
    fn change(s: &mut String) {
        s.push_str(", world");
    }
    
    fn main() {
        let s = String::from("hello");
        let len = calculate_length(&s);
        println!("长度: {}", len);
        
        let mut s = String::from("hello");
        change(&mut s);
        println!("{}", s);
        
        // 借用规则
        let mut s = String::from("hello");
        let r1 = &s;       // OK
        let r2 = &s;       // OK,多个不可变引用
        // let r3 = &mut s; // 错误!存在不可变引用时不能有可变引用
        println!("{} {}", r1, r2);
        // r1, r2 不再使用
        
        let r3 = &mut s;  // OK,r1/r2 已不再使用
        println!("{}", r3);
        
        // Non-Lexical Lifetimes (NLL) - 2018 edition+
        // 引用的生命周期在使用结束后立即结束,而非作用域结束
        let mut s = String::from("hello");
        let r1 = &s;
        let r2 = &s;
        println!("{} {}", r1, r2);
        // r1, r2 在此之后不再使用
        let r3 = &mut s;  // OK!
        println!("{}", r3);
    }

    借用检查规则:

    • 任意时刻,要么只有一个可变引用,要么有多个不可变引用(不能同时存在)
    • 引用必须始终有效(不能悬垂引用)
    • 引用不能比其指向的数据活得更久

    切片(Slice)

    fn first_word(s: &str) -> &str {
        let bytes = s.as_bytes();
        for (i, &item) in bytes.iter().enumerate() {
            if item == b' ' {
                return &s[0..i];
            }
        }
        s
    }
    
    fn main() {
        let mut s = String::from("hello world");
        let word = first_word(&s);
        println!("{}", word);  // "hello"
        
        // 字符串切片
        let s = String::from("hello world");
        let hello = &s[0..5];    // "hello"
        let world = &s[6..11];   // "world"
        let all = &s[..];          // "hello world"
        
        // 数组切片
        let arr = [1, 2, 3, 4, 5];
        let slice: &[i32] = &arr[1..3];
        
        // 切片方法
        let s = &arr[1..4];
        s.len();                   // 3
        s.is_empty();              // false
        s.first();                 // Some(&2)
        s.last();                  // Some(&4)
        s.get(1);                  // Some(&3)
        s.contains(&3);            // true
        s.starts_with(&[2]);      // true
        s.ends_with(&[4]);        // true
        s.split_at(1);             // (&[2], &[3,4])
        s.chunks(2);               // 分块迭代
        s.windows(2);              // 滑动窗口
    }

    所有权与堆内存

    理解堆和栈对于理解 Rust 的所有权至关重要:

    • 栈(Stack):固定大小的数据,LIFO 访问,速度快
    • 堆(Heap):动态大小的数据,需要分配器管理,速度较慢

    String 由三部分组成(都在栈上):

    • 指向堆上数据的指针
    • 长度(length)- 当前使用的字节数
    • 容量(capacity)- 已分配的总字节数
    let mut s = String::with_capacity(10);
    s.push_str("hi");
    println!("len: {}, cap: {}", s.len(), s.capacity()); // 2, 10
    s.shrink_to_fit();   // 收缩容量到实际长度
    s.reserve(20);         // 预留额外空间

    5. Deref 与 Drop Trait

    Deref Trait

    Deref trait 允许智能指针像引用一样被使用,支持 Deref 强制转换

    use std::ops::Deref;
    
    struct MyBox<T>(T);
    
    impl<T> MyBox<T> {
        fn new(x: T) -> MyBox<T> {
            MyBox(x)
        }
    }
    
    impl<T> Deref for MyBox<T> {
        type Target = T;
        
        fn deref(&self) -> &T {
            &self.0
        }
    }
    
    fn main() {
        let x = 5;
        let y = MyBox::new(x);
        
        assert_eq!(5, x);
        assert_eq!(5, *y);  // * 操作符调用 deref()
        // 实际上 *y 等价于 *(y.deref())
    }

    Deref 强制转换

    编译器会自动在不同类型的引用之间进行转换:

    fn hello(name: &str) {
        println!("Hello, {}!", name);
    }
    
    fn main() {
        let m = MyBox::new(String::from("Rust"));
        
        // MyBox<String> --deref--> String --deref--> str
        // &MyBox<String> --&--> &String --&--> &str
        hello(&m);  // 自动转换:&MyBox<String> -> &String -> &str
        
        // 显式转换
        let s: String = String::from("hello");
        let slice: &str = &s;  // String implements Deref<Target=str>
        
        // Box<T> 同样支持
        let b = Box::new(String::from("world"));
        hello(&b);  // 自动转换
    }

    DerefMut Trait

    use std::ops::{Deref, DerefMut};
    
    impl<T> DerefMut for MyBox<T> {
        fn deref_mut(&mut self) -> &mut T {
            &mut self.0
        }
    }

    Deref 强制转换规则:

    &T

    ->

    &U

    T: Deref<Target=U>

    &mut T

    ->

    &mut U

    T: DerefMut<Target=U>

    &mut T

    ->

    &U

    T: Deref<Target=U>

    (可变转不可变 OK)

    • 反之不行(不可变不能转可变)

    Drop Trait

    Drop trait 允许在值离开作用域时执行自定义清理代码:

    struct CustomSmartPointer {
        name: String,
    }
    
    impl Drop for CustomSmartPointer {
        fn drop(&mut self) {
            println!("Dropping CustomSmartPointer with data `{}`!", self.name);
        }
    }
    
    fn main() {
        let c = CustomSmartPointer {
            name: String::from("my stuff"),
        };
        let d = CustomSmartPointer {
            name: String::from("other stuff"),
        };
        println!("CustomSmartPointers created.");
        // 离开作用域时自动调用 drop,顺序与创建相反:d 先,c 后
    }

    提前释放 - std::mem::drop

    fn main() {
        let c = CustomSmartPointer {
            name: String::from("some data"),
        };
        
        // 不能显式调用 drop() 方法(会 double drop)
        // c.drop();  // 编译错误
        
        // 使用 std::mem::drop 函数提前释放
        drop(c);  // 等价于 C++ 的析构函数提前调用
        
        println!("CustomSmartPointer dropped before end of main.");
        // c 不再可用
    }
    
    // std::mem::drop 的实现非常简单:
    fn drop<T>(_x: T) {}  // 通过所有权转移让编译器自动 drop

    注意:

    不能手动实现

    Drop

    的同时手动调用

    drop

    方法,这会导致 double-free。Rust 不允许显式调用

    Drop::drop

    方法,必须使用

    std::mem::drop

    常用 Drop 类型

    • Box<T> - 释放堆内存
    • Vec<T> - 释放堆内存 + 递归 drop 元素
    • String - 释放堆内存
    • File - 关闭文件句柄
    • Mutex<T> - 释放锁
    • TcpStream - 关闭网络连接

    6. 结构体与枚举

    结构体

    // 经典结构体
    struct User {
        username: String,
        email: String,
        age: u32,
        active: bool,
    }
    
    // 元组结构体
    struct Color(u8, u8, u8);
    struct Point(f64, f64, f64);
    
    // 单元结构体
    struct Marker;
    
    // 带泛型的结构体
    struct Wrapper<T> {
        value: T,
    }
    
    // 带生命周期的结构体
    struct Excerpt<'a> {
        part: &'a str,
    }
    
    // 使用结构体
    fn main() {
        let mut user = User {
            username: String::from("alice"),
            email: String::from("alice@example.com"),
            age: 30,
            active: true,
        };
        user.age = 31;
        
        // 字段初始化简写
        let username = String::from("bob");
        let email = String::from("bob@example.com");
        let user2 = User { username, email, age: 25, active: true };
        
        // 结构体更新语法
        let user3 = User {
            email: String::from("bob2@example.com"),
            ..user2  // 从 user2 拷贝其余字段(会移动所有权)
        };
        
        // 元组结构体
        let red = Color(255, 0, 0);
        println!("R={}, G={}, B={}", red.0, red.1, red.2);
        
        // Newtype 模式(见设计模式章节)
        struct Meters(f64);
        struct Millimeters(f64);
    }

    方法(impl)

    struct Rectangle {
        width: f64,
        height: f64,
    }
    
    impl Rectangle {
        // 关联函数(类似静态方法,用 :: 调用)
        fn new(width: f64, height: f64) -> Self {
            Self { width, height }
        }
        
        fn square(size: f64) -> Self {
            Self::new(size, size)
        }
        
        // 方法(取 &self)- 只读
        fn area(&self) -> f64 {
            self.width * self.height
        }
        
        fn is_square(&self) -> bool {
            self.width == self.height
        }
        
        // 可变方法(取 &mut self)- 修改
        fn resize(&mut self, width: f64, height: f64) {
            self.width = width;
            self.height = height;
        }
        
        // 消费方法(取 self)- 转移所有权
        fn into_description(self) -> String {
            format!("{}x{}", self.width, self.height)
        }
        
        fn can_hold(&self, other: &Rectangle) -> bool {
            self.width > other.width && self.height > other.height
        }
    }
    
    // 可以有多个 impl 块
    impl Rectangle {
        fn perimeter(&self) -> f64 {
            2.0 * (self.width + self.height)
        }
    }
    
    fn main() {
        let mut rect = Rectangle::new(5.0, 3.0);
        println!("面积: {}", rect.area());
        println!("周长: {}", rect.perimeter());
        rect.resize(10.0, 4.0);
        let desc = rect.into_description();
        // rect 已被消费,不能再使用
    }

    自动引用与解引用:

    调用方法时,Rust 会自动添加

    &

    &mut

    *

    ,使得

    rect.area()

    (&rect).area()

    等价。

    枚举

    // 基本枚举
    enum Direction {
        Up,
        Down,
        Left,
        Right,
    }
    
    // 带数据的枚举
    enum Message {
        Quit,                          // 无数据
        Move { x: i32, y: i32 },     // 结构体变体
        Write(String),                 // 元组变体
        ChangeColor(u8, u8, u8),     // 多个值
        Error { code: i32, msg: String },
    }
    
    // Option 和 Result 是标准库中最常用的枚举
    enum Option<T> {
        Some(T),
        None,
    }
    
    enum Result<T, E> {
        Ok(T),
        Err(E),
    }
    
    impl Message {
        fn call(&self) {
            match self {
                Message::Quit => println!("退出"),
                Message::Move { x, y } => println!("移动到 ({}, {})", x, y),
                Message::Write(text) => println!("消息: {}", text),
                Message::ChangeColor(r, g, b) => {
                    println!("颜色: ({}, {}, {})", r, g, b);
                }
                Message::Error { code, msg } => {
                    println!("错误 {}: {}", code, msg);
                }
            }
        }
    }
    
    fn main() {
        let m = Message::Write(String::from("hello"));
        m.call();
        
        // Option 常用方法
        let x: Option<i32> = Some(5);
        x.is_some();                  // true
        x.is_none();                  // false
        x.unwrap();                   // 5 (None 则 panic)
        x.unwrap_or(0);              // 5
        x.unwrap_or_default();        // 5
        x.unwrap_or_else(|| 0);      // 5
        x.map(|v| v * 2);            // Some(10)
        x.and_then(|v| Some(v * 2)); // Some(10)
        x.filter(|v| *v > 3);        // Some(5)
        x.ok_or("empty");            // Ok(5)
        
        // Option 组合
        let opt1 = Some(2);
        let opt2 = Some(3);
        let sum = opt1.zip(opt2).map(|(a, b)| a + b);  // Some(5)
    }

    7. 模式匹配

    Match 表达式

    match 是 Rust 中最强大的控制流工具,要求穷举所有可能的值:

    enum Coin {
        Penny,
        Nickel,
        Dime,
        Quarter(String),
    }
    
    fn value_in_cents(coin: Coin) -> u8 {
        match coin {
            Coin::Penny => {
                println!("Lucky penny!");
                1
            }
            Coin::Nickel => 5,
            Coin::Dime => 10,
            Coin::Quarter(state) => {
                println!("来自 {} 的 Quarter", state);
                25
            }
        }
    }

    各种模式

    fn match_examples() {
        // 字面量匹配
        let x = 3;
        match x {
            1 => println!("one"),
            2 | 3 => println!("two or three"),
            4..=10 => println!("four to ten"),
            _ => println!("other"),
        }
        
        // 守卫(Guard)
        let pair = (2, -2);
        match pair {
            (x, y) if x + y == 0 => println!("互为相反数"),
            (x, y) => println!("不是相反数: {}, {}", x, y),
        }
        
        // 结构体匹配
        struct Point { x: i32, y: i32, z: i32 }
        let p = Point { x: 0, y: 7, z: 0 };
        match p {
            Point { x, y: 0, z: 0 } => println!("x 轴上: {}", x),
            Point { x: 0, y, z: 0 } => println!("y 轴上: {}", y),
            Point { x: 0, y: 0, z } => println!("z 轴上: {}", z),
            Point { x, y, z } => println!("({}, {}, {})", x, y, z),
        }
        
        // 嵌套模式
        enum Color { Rgb(u8, u8, u8), Hsv(u8, u8, u8) }
        enum Message { Quit, Move { x: i32 }, ChangeColor(Color) }
        let msg = Message::ChangeColor(Color::Rgb(255, 0, 0));
        match msg {
            Message::ChangeColor(Color::Rgb(r, g, b)) => {
                println!("RGB: {}, {}, {}", r, g, b);
            }
            Message::ChangeColor(Color::Hsv(h, s, v)) => {
                println!("HSV: {}, {}, {}", h, s, v);
            }
            _ => (),
        }
        
        // @ 绑定 - 匹配并同时绑定
        enum Message { Hello { id: i32 } }
        let msg = Message::Hello { id: 5 };
        match msg {
            Message::Hello { id: id_var @ 3..=7 } => {
                println!("id 在范围内: {}", id_var);
            }
            Message::Hello { id } => println!("其他 id: {}", id),
        }
        
        // 忽略模式
        let numbers = (2, 4, 8, 16, 32);
        match numbers {
            (first, _, third, _, fifth) => {
                println!("{}, {}, {}", first, third, fifth);
            }
        }
        
        // .. 忽略剩余部分
        let p = Point { x: 1, y: 2, z: 3 };
        match p {
            Point { x, .. } => println!("x = {}", x),
        }
        
        // 解构结构体和元组
        let Point { x, y, z } = p;
        let (a, b, c, d, e) = numbers;
    }

    if let 和 while let

    fn main() {
        let config_max = Some(3u8);
        
        // 只关心 Some 的情况(match 的简化)
        if let Some(max) = config_max {
            println!("最大值: {}", max);
        } else {
            println!("没有最大值");
        }
        
        // while let
        let mut stack = vec![1, 2, 3];
        while let Some(top) = stack.pop() {
            println!("{}", top);  // 3, 2, 1
        }
        
        // let else (Rust 1.65+) - 用于提前返回
        fn get_first_char(s: &str) -> char {
            let Some(c) = s.chars().next() else {
                return '?';  // else 分支必须 diverge(返回/panic)
            };
            c
        }
        
        // matches! 宏 - 判断是否符合模式
        let x = Some(5);
        let is_some = matches!(x, Some(_));
        let is_five = matches!(x, Some(5));
        let is_even = matches!(x, Some(n) if n % 2 == 0);
        
        // 在 filter 中使用
        let v = vec![Some(1), None, Some(2), Some(3)];
        let filtered: Vec<_> = v.iter().filter(|x| matches!(x, Some(_))).collect();
    }

    模式语法总结

    模式示例说明
    字面量1, 'a', "hello"匹配具体值
    范围'a'..='z', 1..=10匹配范围内
    变量x, mut y绑定到变量
    通配符_忽略值
    剩余..忽略剩余字段
    1 | 2 | 3匹配任一值
    守卫x if x > 0附加条件
    绑定x @ 1..=5匹配并绑定
    元组(a, b, c)解构元组
    结构体Point { x, y }解构结构体
    枚举Some(x), Ok(v)解构枚举
    引用&x, &mut x匹配引用

    8. 集合类型

    Vec<T> - 动态数组

    fn main() {
        // 创建
        let v1: Vec<i32> = Vec::new();
        let v2 = vec![1, 2, 3, 4, 5];
        let v3 = vec![0; 5];  // [0,0,0,0,0]
        let v4 = Vec::with_capacity(100);  // 预分配容量
        
        // 修改
        let mut v = Vec::new();
        v.push(1);
        v.push(2);
        v.push(3);
        v.extend([4, 5, 6]);     // 扩展
        v.insert(0, 0);          // 插入到索引
        
        // 访问元素
        let first = &v[0];           // 越界会 panic
        let second = v.get(1);       // 返回 Option
        match v.get(10) {
            Some(val) => println!("{}", val),
            None => println!("索引越界"),
        }
        
        // 遍历
        for val in &v {
            println!("{}", val);
        }
        for val in &mut v {
            *val += 10;
        }
        
        // 删除
        let popped = v.pop();       // Option<T>
        v.remove(0);               // 按索引删除(O(n))
        v.swap_remove(0);          // 交换后删除(O(1))
        v.retain(|&x| x > 1);      // 条件保留
        v.clear();                  // 清空
        v.truncate(3);              // 截断到指定长度
        v.drain(1..3);             // 删除范围并返回迭代器
        
        // 常用操作
        let mut v = vec![3, 1, 4, 1, 5];
        v.sort();                   // [1,1,3,4,5]
        v.sort_unstable();          // 快速排序,不稳定
        v.sort_by(|a, b| b.cmp(a)); // 自定义排序
        v.dedup();                  // [1,3,4,5] 去除相邻重复
        v.reverse();
        v.contains(&3);            // true
        v.binary_search(&3);       // 二分查找(需已排序)
        let sum: i32 = v.iter().sum();
        let first = v.first();       // Option<&T>
        let last = v.last();         // Option<&T>
        v.is_empty();
        v.len();
        v.capacity();
        v.as_slice();               // 转为切片
        v.into_boxed_slice();       // 转为 Box<[T]>
    }

    String - 字符串

    fn main() {
        // 创建
        let s1 = String::new();
        let s2 = String::from("hello");
        let s3 = "world".to_string();
        let s4: String = "中文".into();
        let s5 = String::with_capacity(100);
        
        // 修改
        let mut s = String::from("hello");
        s.push_str(" world");
        s.push('!');
        s.insert(0, 'H');          // 插入字符
        s.insert_str(5, " there");  // 插入字符串
        s.remove(0);                // 删除字符
        s.pop();                     // Option<char>
        s.clear();
        s.truncate(5);
        s.replace_range(0..5, "Hi");
        
        // 拼接
        let s1 = String::from("hello");
        let s2 = String::from(" world");
        let s3 = s1 + &s2;  // s1 被移动,+ 实际是 add(self, &str)
        let s4 = format!("{}-{}", s2, "rust");  // 不移动,推荐
        
        // 不能索引(UTF-8 可变长度)
        // let c = s[0];  // 编译错误
        
        // 遍历
        for c in "你好世界".chars() {
            println!("{}", c);
        }
        for b in "abc".bytes() {
            println!("{}", b);
        }
        // char_indices 返回 (字节索引, 字符)
        for (i, c) in "你好".char_indices() {
            println!("{}: {}", i, c);  // 0:你, 3:好
        }
        
        // 字符串方法
        let s = String::from("  Hello, World!  ");
        s.len();                   // 字节长度
        s.chars().count();          // 字符数
        s.is_empty();
        s.contains("World");       // true
        s.starts_with("Hello");    // false (有前导空格)
        s.ends_with("!");
        s.find("World");            // Option<usize> 字节索引
        s.trim();                   // "Hello, World!"
        s.trim_start();
        s.trim_end();
        s.to_lowercase();
        s.to_uppercase();
        s.replace("World", "Rust");
        s.split(",");               // 迭代器
        s.split_whitespace();
        s.lines();
        s.matches("l");             // 匹配迭代器
        s.parse::<i32>();           // 转为数字
    }

    HashMap<K, V>

    use std::collections::HashMap;
    
    fn main() {
        // 创建
        let mut scores: HashMap<String, i32> = HashMap::new();
        scores.insert(String::from("Alice"), 95);
        scores.insert(String::from("Bob"), 87);
        
        // 从 Vec 构建
        let teams = vec![String::from("Blue"), String::from("Red")];
        let scores = vec![10, 50];
        let map: HashMap<_, _> = teams.into_iter().zip(scores.into_iter()).collect();
        
        // 访问
        let alice_score = scores.get("Alice");  // Option<&i32>
        if let Some(score) = scores.get("Alice") {
            println!("Alice: {}", score);
        }
        
        // entry API(最常用)
        scores.entry(String::from("Alice")).or_insert(50);  // 不存在则插入
        scores.entry(String::from("Charlie")).or_insert(80);
        
        // 基于旧值更新
        let text = "hello world hello";
        let mut map = HashMap::new();
        for word in text.split_whitespace() {
            let count = map.entry(word).or_insert(0);
            *count += 1;
        }
        println!("{:?}", map);
        
        // and_modify (Rust 1.50+)
        scores.entry(String::from("Alice"))
            .and_modify(|v| *v += 5)
            .or_insert(50);
        
        // 遍历
        for (key, val) in &scores {
            println!("{}: {}", key, val);
        }
        
        // 删除
        scores.remove("Bob");
        scores.retain(|k, v| *v > 80);
        scores.clear();
        
        // 其他方法
        scores.len();
        scores.is_empty();
        scores.contains_key("Alice");
        scores.keys();           // 迭代器
        scores.values();        // 迭代器
        scores.values_mut();
    }

    HashSet<T>

    use std::collections::HashSet;
    
    fn main() {
        let mut set: HashSet<i32> = HashSet::new();
        set.insert(1);
        set.insert(2);
        set.insert(3);
        set.insert(2);  // 重复,不会添加
        
        set.contains(&1);       // true
        set.len();                // 3
        
        // 集合操作
        let a: HashSet<_> = [1, 2, 3].iter().collect();
        let b: HashSet<_> = [2, 3, 4].iter().collect();
        
        // 交集
        let intersection: HashSet<_> = a.intersection(&b).collect(); // {2, 3}
        
        // 并集
        let union: HashSet<_> = a.union(&b).collect(); // {1, 2, 3, 4}
        
        // 差集
        let diff: HashSet<_> = a.difference(&b).collect(); // {1}
        
        // 对称差
        let sym_diff: HashSet<_> = a.symmetric_difference(&b).collect(); // {1, 4}
        
        // 子集/超集判断
        let small: HashSet<_> = [1, 2].iter().collect();
        small.is_subset(&a);       // true
        a.is_superset(&small);    // true
    }

    VecDeque<T> - 双端队列

    use std::collections::VecDeque;
    
    fn main() {
        let mut deque = VecDeque::new();
        deque.push_front(1);  // 前端添加
        deque.push_back(2);   // 后端添加
        deque.push_front(0);  // [0, 1, 2]
        
        deque.pop_front();     // Some(0)
        deque.pop_back();      // Some(2)
        
        // 作为队列使用(FIFO)
        let mut queue = VecDeque::new();
        queue.push_back(1);
        queue.push_back(2);
        let first = queue.pop_front();  // Some(1)
        
        // 作为栈使用(LIFO)
        let mut stack = VecDeque::new();
        stack.push_back(1);
        stack.push_back(2);
        let last = stack.pop_back();    // Some(2)
    }

    BTreeMap 和 BTreeSet

    use std::collections::{BTreeMap, BTreeSet};
    
    fn main() {
        // BTreeMap - 按键排序的 Map(红黑树实现)
        let mut map = BTreeMap::new();
        map.insert("c", 3);
        map.insert("a", 1);
        map.insert("b", 2);
        // 遍历时按键排序:a, b, c
        
        // 范围查询(HashMap 不支持)
        for (k, v) in map.range("a".."c") {
            println!("{}: {}", k, v);
        }
        
        // BTreeSet - 排序的集合
        let mut set = BTreeSet::new();
        set.insert(3);
        set.insert(1);
        set.insert(2);
        // 遍历时按值排序:1, 2, 3
    }
    
    // HashMap vs BTreeMap 选择:
    // HashMap: O(1) 平均查找,无序,更快(大多数场景)
    // BTreeMap: O(log n) 查找,有序,支持范围查询

    BinaryHeap<T> - 优先队列

    use std::collections::BinaryHeap;
    
    fn main() {
        let mut heap = BinaryHeap::new();
        heap.push(3);
        heap.push(1);
        heap.push(5);
        heap.push(2);
        
        // 默认是大顶堆
        heap.peek();     // Some(&5)
        heap.pop();      // Some(5)
        heap.pop();      // Some(3)
        
        // 转为小顶堆(使用 Reverse)
        use std::cmp::Reverse;
        let mut min_heap = BinaryHeap::new();
        min_heap.push(Reverse(3));
        min_heap.push(Reverse(1));
        min_heap.push(Reverse(5));
        min_heap.pop();  // Some(Reverse(1))
    }

    9. 字符串深入

    字符串类型区别

    类型说明所有权可变
    StringUTF-8 字符串,堆分配拥有可变
    &str字符串切片,UTF-8借用不可变
    &mut str可变字符串切片(很少用)借用可变
    OsString操作系统原生字符串拥有可变
    &OsStr操作系统字符串切片借用不可变
    PathBuf路径,堆分配拥有可变
    &Path路径切片借用不可变
    CStringC 兼容的字符串(\0 结尾)拥有可变
    &CStrC 字符串切片借用不可变

    UTF-8 编码细节

    fn main() {
        let hello = "नमस्ते";  // 印地语 "你好"
        
        // 字节长度(每个字符 3 字节)
        println!("字节: {}", hello.len());       // 18
        println!("字符: {}", hello.chars().count()); // 6
        
        // 不能按字节索引(可能切在多字节字符中间)
        // &hello[0..3]; // 可能 panic(如果不是字符边界)
        
        // 安全按字节切片(需检查边界)
        let safe_slice = if hello.is_char_boundary(3) {
            &hello[0..3]  // OK,如果是字符边界
        } else {
            ""
        };
        
        // Unicode 组合字符
        let hello = "Hello";
        let mut hello2 = String::from(hello);
        hello2.push('\u{0301}');  // 组合锐音符
        println!("{}", hello2);       // Héllo
        println!("字符数: {}", hello2.chars().count()); // 6
        
        // Grapheme clusters(字形簇,人类视角的"字符")
        // 需要 unicode-segmentation crate
        use unicode_segmentation::UnicodeSegmentation;
        let s = "é";  // e + 组合符
        println!("graphemes: {}", s.graphemes(true).count()); // 1
        println!("chars: {}", s.chars().count()); // 2
    }

    字符串性能优化

    fn main() {
        // 1. 预分配容量
        let mut s = String::with_capacity(1000);
        for i in 0..1000 {
            s.push_str("abc");  // 不会重新分配
        }
        
        // 2. 使用 Cow(Clone on Write)
        use std::borrow::Cow;
        fn remove_spaces(s: &str) -> Cow<str> {
            if s.contains(' ') {
                Cow::Owned(s.replace(" ", ""))
            } else {
                Cow::Borrowed(s)  // 无需拷贝
            }
        }
        let r1 = remove_spaces("hello");       // 借用
        let r2 = remove_spaces("hello world"); // 拥有
        
        // 3. 使用 format! 宏
        let s = format!("{} + {} = {}", 1, 2, 3);
        
        // 4. 使用 write! 宏
        use std::fmt::Write;
        let mut s = String::new();
        write!(s, "{} {}", "hello", "world").unwrap();
        
        // 5. String::from_utf8 转换字节
        let bytes = vec![72, 101, 108, 108, 111];
        let s = String::from_utf8(bytes).unwrap();  // "Hello"
        
        // 6. String::from_utf8_lossy(容错转换)
        let invalid = vec![0xff, 0xfe];
        let s = String::from_utf8_lossy(&invalid);  // 无效字节替换为 U+FFFD
    }

    字符串格式化

    fn main() {
        // 基础格式化
        println!("{}", "hello");       // Display
        println!("{:?}", (1, 2));      // Debug
        println!("{:#?}", (1, 2));     // Pretty Debug
        println!("{:x}", 255);          // ff (小写十六进制)
        println!("{:X}", 255);          // FF (大写十六进制)
        println!("{:b}", 255);          // 11111111 (二进制)
        println!("{:o}", 255);          // 377 (八进制)
        println!("{:e}", 1000.0);       // 1e3 (科学计数法)
        
        // 位置参数
        println!("{0} {1} {0}", "hello", "world");
        
        // 命名参数
        println!("{name} is {age}", name="Alice", age=30);
        
        // 宽度与对齐
        println!("{:10}", "x");          // "x         " (左对齐)
        println!("{:>10}", "x");         // "         x" (右对齐)
        println!("{:^10}", "x");         // "    x     " (居中)
        println!("{:*^10}", "x");        // "****x*****" (填充 *)
        
        // 精度
        println!("{:.2}", 3.14159);     // 3.14
        println!("{:.5}", "hello world"); // hello (截断)
        
        // 捕获变量 (Rust 1.58+)
        let name = "Rust";
        let version = "1.75";
        println!("{name} {version}");  // 直接捕获
        
        // 数字格式
        println!("{:#06x}", 255);       // 0x00ff
        println!("{:08}", 42);          // 00000042
        println!("{:08.3}", 3.1415);    // 0003.142
    }

    10. 错误处理

    panic! - 不可恢复错误

    fn main() {
        // 主动 panic
        // panic!("crash!");
        
        // 隐式 panic(数组越界、unwrap 失败等)
        let v = vec![1, 2, 3];
        // v[99];  // 越界 panic
        
        // 设置 panic 行为(Cargo.toml)
        # [profile.release]
        # panic = 'abort'  # 直接终止,无回溯
        
        # [profile.dev]
        # panic = 'unwind'  # 默认,允许捕获
        
        // 捕获 panic(谨慎使用)
        let result = std::panic::catch_unwind(|| {
            panic!("oh no!");
        });
        assert!(result.is_err());
    }

    Result<T, E> - 可恢复错误

    use std::fs::File;
    use std::io::{self, Read};
    
    fn read_file(path: &str) -> Result<String, io::Error> {
        let file_result = File::open(path);
        
        let mut file = match file_result {
            Ok(f) => f,
            Err(e) => return Err(e),
        };
        
        let mut content = String::new();
        match file.read_to_string(&mut content) {
            Ok(_) => Ok(content),
            Err(e) => Err(e),
        }
    }
    
    // 使用 ? 运算符简化(只能用在返回 Result 的函数中)
    fn read_file_v2(path: &str) -> Result<String, io::Error> {
        let mut file = File::open(path)?;
        let mut content = String::new();
        file.read_to_string(&mut content)?;
        Ok(content)
    }
    
    // 链式调用
    fn read_file_v3(path: &str) -> Result<String, io::Error> {
        File::open(path)
            .and_then(|mut file| {
                let mut s = String::new();
                file.read_to_string(&mut s).map(|_| s)
            })
    }
    
    // 链式写法 2
    fn read_file_v4(path: &str) -> Result<String, io::Error> {
        let mut s = String::new();
        File::open(path)?.read_to_string(&mut s)?;
        Ok(s)
    }
    
    // 使用 std::fs::read_to_string 最简洁
    fn read_file_v5(path: &str) -> Result<String, io::Error> {
        std::fs::read_to_string(path)
    }

    Result 常用方法

    fn main() {
        let r: Result<i32, &str> = Ok(5);
        let e: Result<i32, &str> = Err("error");
        
        // 解包
        r.unwrap();                 // 5
        r.unwrap_or(0);            // 5
        e.unwrap_or(0);            // 0
        e.unwrap_or_default();     // 0
        e.unwrap_or_else(|_| 0);   // 0
        // e.unwrap();  // panic
        r.expect("Failed");        // 5,失败显示信息
        
        // 判断
        r.is_ok();                  // true
        r.is_err();                 // false
        
        // 转换
        r.ok();                     // Some(5)
        e.ok();                     // None
        r.err();                    // None
        e.err();                    // Some("error")
        
        // 链式
        r.map(|v| v * 2);          // Ok(10)
        r.map_err(|e| e.to_string());
        r.and_then(|v| Ok(v * 2)); // Ok(10)
        r.or_else(|_| Ok(0));      // Ok(5)
        e.or_else(|_| Ok(0));      // Ok(0)
        
        // 扁平化
        let nested: Result<Result<i32, &str>, &str> = Ok(Ok(5));
        nested.flatten();           // Ok(5)
    }

    自定义错误类型

    use std::fmt;
    use std::error::Error;
    
    #[derive(Debug)]
    enum AppError {
        NotFound(String),
        Unauthorized,
        ParseError(std::num::ParseIntError),
        Io(std::io::Error),
    }
    
    impl fmt::Display for AppError {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            match self {
                AppError::NotFound(msg) => write!(f, "未找到: {}", msg),
                AppError::Unauthorized => write!(f, "未授权"),
                AppError::ParseError(e) => write!(f, "解析错误: {}", e),
                AppError::Io(e) => write!(f, "IO 错误: {}", e),
            }
        }
    }
    
    impl Error for AppError {
        fn source(&self) -> Option<&(dyn Error + 'static)> {
            match self {
                AppError::ParseError(e) => Some(e),
                AppError::Io(e) => Some(e),
                _ => None,
            }
        }
    }
    
    // 从其他错误类型转换
    impl From<std::num::ParseIntError> for AppError {
        fn from(err: std::num::ParseIntError) -> Self {
            AppError::ParseError(err)
        }
    }
    
    impl From<std::io::Error> for AppError {
        fn from(err: std::io::Error) -> Self {
            AppError::Io(err)
        }
    }
    
    // 使用 thiserror crate 简化
    use thiserror::Error;
    
    #[derive(Error, Debug)]
    enum AppError {
        #[error("未找到: {0}")]
        NotFound(String),
        
        #[error("未授权")]
        Unauthorized,
        
        #[error("解析错误")]
        ParseError(#[from] std::num::ParseIntError),
        
        #[error("IO 错误")]
        Io(#[from] std::io::Error),
        
        #[error("自定义错误: {code} - {msg}")]
        Custom { code: i32, msg: String },
    }

    推荐在库代码中使用

    Result

    +

    thiserror

    返回错误,在应用顶层(main)使用

    anyhow

    处理错误。

    anyhow::Result<T>

    Result<T, anyhow::Error>

    的别名,支持任意错误类型和

    .context()

    方法添加上下文。

    使用 anyhow 简化错误处理

    use anyhow::{Result, Context, anyhow};
    
    fn read_config() -> Result<Config> {
        let content = std::fs::read_to_string("config.toml")
            .context("无法读取配置文件")?;
        
        let config: Config = toml::from_str(&content)
            .context("配置文件格式错误")?;
        
        Ok(config)
    }
    
    fn main() -> Result<()> {
        let config = read_config()?;
        println!("{:?}", config);
        
        // 创建自定义错误
        if config.is_invalid() {
            return Err(anyhow!("Invalid config"));
        }
        
        Ok(())
    }

    11. 泛型

    泛型函数

    // 单类型参数
    fn largest<T: PartialOrd>(list: &[T]) -> &T {
        let mut largest = &list[0];
        for item in &list[1..] {
            if item > largest {
                largest = item;
            }
        }
        largest
    }
    
    // 多类型参数
    fn print_pair<T, U>(t: T, u: U)
    where
        T: std::fmt::Display,
        U: std::fmt::Display,
    {
        println!("({}, {})", t, u);
    }
    
    // 带返回值的泛型
    fn wrap<T>(x: T) -> Option<T> {
        Some(x)
    }
    
    // turbofish 语法(显式指定类型参数)
    let v = Vec::<i32>::new();
    let s = "42".parse::<i32>().unwrap();
    let v = vec![1, 2, 3].into_iter().collect::<Vec<_>>();

    泛型结构体

    struct Point<T> {
        x: T,
        y: T,
    }
    
    struct Pair<T, U> {
        first: T,
        second: U,
    }
    
    // 带默认类型参数
    struct Array<T, const N: usize> {
        data: [T; N],
    }
    
    // 为泛型结构体实现方法
    impl<T> Point<T> {
        fn x(&self) -> &T {
            &self.x
        }
    }
    
    // 为特定类型实现方法
    impl Point<f64> {
        fn distance_from_origin(&self) -> f64 {
            (self.x.powi(2) + self.y.powi(2)).sqrt()
        }
    }
    
    // 常量泛型参数
    fn create_zero_array<T: Default + Copy, const N: usize>() -> [T; N] {
        [T::default(); N]
    }
    let zeros: [i32; 5] = create_zero_array();
    
    fn main() {
        let integer_point = Point { x: 5, y: 10 };
        let float_point = Point { x: 1.5, y: 4.2 };
        
        println!("x = {}", integer_point.x());
        println!("距离: {}", float_point.distance_from_origin());
    }

    泛型枚举

    // 标准库中的 Option 和 Result
    enum Option<T> {
        Some(T),
        None,
    }
    
    enum Result<T, E> {
        Ok(T),
        Err(E),
    }
    
    // 自定义泛型枚举
    enum List<T> {
        Cons(T, Box<List<T>>),
        Nil,
    }
    
    // Either 类型(两个结果之一)
    enum Either<L, R> {
        Left(L),
        Right(R),
    }

    性能:Monomorphization

    Rust 通过 单态化(monomorphization) 实现零成本抽象:编译器在编译时为每个实际使用的具体类型生成独立的代码。

    // 编译器会将以下代码:
    let integer = Some(5);      // Option<i32>
    let float = Some(5.0);      // Option<f64>
    
    // 转换为类似:
    enum Option_i32 { Some(i32), None }
    enum Option_f64 { Some(f64), None }
    let integer = Option_i32::Some(5);
    let float = Option_f64::Some(5.0);
    // 因此运行时没有泛型的性能开销

    单态化的代价是

    编译产物体积增大

    编译时间变长

    。如果需要减少代码膨胀,可以使用

    dyn Trait

    (trait object,动态分发)。

    12. Trait 特征

    定义和实现 Trait

    trait Summary {
        fn summarize(&self) -> String;
        
        // 默认实现
        fn preview(&self) -> String {
            format!("(Read more... {})", self.summarize())
        }
    }
    
    struct Article {
        title: String,
        author: String,
        content: String,
    }
    
    impl Summary for Article {
        fn summarize(&self) -> String {
            format!("{}, by {} - {}", self.title, self.author, &self.content[..20])
        }
    }
    
    struct Tweet {
        username: String,
        content: String,
    }
    
    impl Summary for Tweet {
        fn summarize(&self) -> String {
            format!("@{}: {}", self.username, self.content)
        }
        
        // 重写默认方法
        fn preview(&self) -> String {
            format!("[Tweet] {}", self.summarize())
        }
    }

    孤儿规则(Orphan Rule)

    只能在本地定义的类型或本地定义的 trait 之间实现关系。即不能为第三方库的类型实现第三方库的 trait,防止冲突。

    // OK:本地类型 + 本地 trait
    impl MyTrait for MyType { }
    
    // OK:本地类型 + 标准库 trait
    impl std::fmt::Display for MyType { }
    
    // OK:标准库 trait + 本地类型(通过泛型)
    impl<T> std::fmt::Display for MyWrapper<T> { }
    
    // 错误:第三方类型 + 第三方 trait
    // impl std::fmt::Display for serde_json::Value { }  // 错误!
    
    // 解决方案:使用 Newtype 模式
    struct MyValue(serde_json::Value);
    impl std::fmt::Display for MyValue { }

    Trait 作为参数

    // impl Trait 语法(静态分发,编译时确定类型)
    fn notify(item: &impl Summary) {
        println!("突发: {}", item.summarize());
    }
    
    // Trait Bound 语法
    fn notify<T: Summary>(item: &T) {
        println!("突发: {}", item.summarize());
    }
    
    // 多 Trait Bound
    fn notify(item: &impl Summary + std::fmt::Display) { }
    
    // where 从句(更清晰,特别是复杂约束时)
    fn some_function<T, U>(t: &T, u: &U) -> i32
    where
        T: Display + Clone,
        U: Clone + Debug,
    {
        0
    }
    
    // 返回 impl Trait(只能返回一种类型)
    fn create_summary() -> impl Summary {
        Tweet {
            username: String::from("rust"),
            content: String::from("Hello!"),
        }
    }
    
    // 返回多种类型时使用 trait object(dyn)
    fn create_summary(is_tweet: bool) -> Box<dyn Summary> {
        if is_tweet {
            Box::new(Tweet { /*...*/ })
        } else {
            Box::new(Article { /*...*/ })
        }
    }

    常用标准库 Trait

    // 自动派生
    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
    struct User {
        name: String,
        age: u32,
    }
    
    // Display trait
    use std::fmt;
    impl fmt::Display for User {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "User({}, {})", self.name, self.age)
        }
    }
    
    // From / Into(类型转换)
    impl From<&str> for User {
        fn from(s: &str) -> Self {
            User {
                name: s.to_string(),
                age: 0,
            }
        }
    }
    let user: User = "Alice".into();
    
    // Iterator trait
    struct Counter { count: u32 }
    impl Iterator for Counter {
        type Item = u32;
        fn next(&mut self) -> Option<Self::Item> {
            self.count += 1;
            if self.count <= 5 {
                Some(self.count)
            } else {
                None
            }
        }
    }
    
    // Add / Sub / Mul / Div 等运算 trait
    use std::ops::Add;
    impl Add for Point {
        type Output = Self;
        fn add(self, other: Self) -> Self {
            Self {
                x: self.x + other.x,
                y: self.y + other.y,
            }
        }
    }
    let p3 = p1 + p2;  // 调用 add
    
    // Index trait
    use std::ops::Index;
    impl Index<usize> for MyVec {
        type Output = i32;
        fn index(&self, index: usize) -> &Self::Output {
            &self.data[index]
        }
    }

    关联类型(Associated Types)

    // 与泛型不同,关联类型只能有一个具体实现
    pub trait Iterator {
        type Item;  // 关联类型
        fn next(&mut self) -> Option<Self::Item>;
    }
    
    impl Iterator for Counter {
        type Item = u32;  // 指定具体类型
        fn next(&mut self) -> Option<Self::Item> {
            /* ... */
        }
    }
    
    // 对比泛型 trait(可以多次实现)
    pub trait Iterator<T> {
        fn next(&mut self) -> Option<T>;
    }
    
    // 可以分别为不同类型实现
    impl Iterator<u32> for Counter { }
    impl Iterator<i32> for Counter { }  // 也允许

    完全限定语法(Fully Qualified Syntax)

    trait Pilot {
        fn fly(&self);
    }
    
    trait Wizard {
        fn fly(&self);
    }
    
    struct Human;
    
    impl Pilot for Human {
        fn fly(&self) {
            println!("This is your captain speaking.");
        }
    }
    
    impl Wizard for Human {
        fn fly(&self) {
            println!("Up!");
        }
    }
    
    impl Human {
        fn fly(&self) {
            println!(*waving arms furiously*);
        }
    }
    
    fn main() {
        let h = Human;
        h.fly();                  // 默认调用 Human 的 fly
        Pilot::fly(&h);            // 调用 Pilot 的 fly
        Wizard::fly(&h);           // 调用 Wizard 的 fly
        
        // 没有 self 参数的情况
        trait Animal {
            fn baby_name() -> String;
        }
        struct Dog;
        impl Dog {
            fn baby_name() -> String { String::from("Spot") }
        }
        impl Animal for Dog {
            fn baby_name() -> String { String::from("puppy") }
        }
        
        println!("{}", Dog::baby_name());           // Spot
        println!("{}", <Dog as Animal>::baby_name()); // puppy
    }

    Supertrait

    use std::fmt;
    
    // 实现 OutlinePrint 的类型必须也实现 Display
    trait OutlinePrint: fmt::Display {
        fn outline(&self) {
            println!("**********");
            println!("* {} *", self);
            println!("**********");
        }
    }
    
    struct Point { x: i32, y: i32 }
    
    // 必须先实现 Display 才能实现 OutlinePrint
    impl fmt::Display for Point {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "({}, {})", self.x, self.y)
        }
    }
    
    impl OutlinePrint for Point {}

    Trait Object (动态分发)

    trait Drawable {
        fn draw(&self);
        fn area(&self) -> f64;
    }
    
    struct Circle { radius: f64 }
    impl Drawable for Circle {
        fn draw(&self) { println!("○"); }
        fn area(&self) -> f64 { std::f64::consts::PI * self.radius.powi(2) }
    }
    
    struct Square { side: f64 }
    impl Drawable for Square {
        fn draw(&self) { println!("□"); }
        fn area(&self) -> f64 { self.side.powi(2) }
    }
    
    // 使用 trait object
    fn draw_all(shapes: &[&dyn Drawable]) {
        for shape in shapes {
            shape.draw();
            println!("面积: {}", shape.area());
        }
    }
    
    fn main() {
        let shapes: Vec<Box<dyn Drawable>> = vec![
            Box::new(Circle { radius: 5.0 }),
            Box::new(Square { side: 4.0 }),
        ];
        
        for shape in &shapes {
            shape.draw();
        }
    }
    
    // 对象安全(Object Safety)要求:
    // 1. 方法不能有泛型参数
    // 2. 方法不能返回 Self(除非 Sized)
    // 3. 不能有非静态生命周期的返回引用

    13. 生命周期

    生命周期基础

    生命周期确保引用在使用时始终有效:

    // 这段代码无法编译
    // {
    //     let r;
    //     {
    //         let x = 5;
    //         r = &x;  // x 的生命周期短于 r
    //     }
    //     println!("{}", r);  // 悬垂引用!
    // }
    
    // 需要显式标注生命周期的情况
    fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
        if x.len() > y.len() {
            x
        } else {
            y
        }
    }
    
    fn main() {
        let s1 = String::from("long string");
        let result;
        {
            let s2 = String::from("xyz");
            result = longest(s1.as_str(), s2.as_str());
            println!("{}", result);  // OK,s2 仍然有效
        }
        // println!("{}", result);  // 错误!s2 已失效
    }

    生命周期省略规则

    编译器会自动推断一些常见情况:

    1. 每个引用参数获得自己的生命周期参数
    2. 如果只有一个输入生命周期参数,它被赋给所有输出
    3. 如果有 &self&mut self,self 的生命周期被赋给所有输出
    4. // 编译器自动推断(不需要标注)
      fn first_word(s: &str) -> &str { }  // OK - 规则 1+2
      fn len(s: &str) -> usize { }      // OK - 无输出引用
      
      impl MyStruct {
          fn get_name(&self) -> &str { }  // OK - 规则 3
      }
      
      // 需要显式标注
      fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { }
      
      // 方法中的生命周期
      struct Important<'a> {
          part: &'a str,
      }
      
      impl<'a> Important<'a> {
          fn level(&self) -> i32 { 3 }  // 不需要标注
          fn announce(&self, announcement: &str) -> &str {  // 有歧义
              // 需要标注:&self 还是 announcement?
              self.part
          }
      }

      结构体中的生命周期

      // 包含引用的结构体必须标注生命周期
      struct Excerpt<'a> {
          part: &'a str,
      }
      
      impl<'a> Excerpt<'a> {
          // 返回引用的方法
          fn level(&self) -> i32 { 3 }
          
          // 返回结构体字段引用的方法
          fn part(&self) -> &str {
              self.part
          }
          
          // 返回传入参数的引用(不同的生命周期)
          fn announce_and_return<'b>(&self, announcement: &'b str) -> &'b str {
              println!("Attention: {}", announcement);
              announcement
          }
      }
      
      fn main() {
          let novel = String::from("Call me Ishmael. Some years ago...");
          let first_sentence = novel.split('.').next().expect("Could not find '.'");
          let i = Excerpt {
              part: first_sentence,  // first_sentence 的生命周期足够长
          };
          println!("{}", i.part());
      }

      静态生命周期

      // 'static 生命周期:贯穿整个程序运行期
      let s: &'static str = "I have a static lifetime";
      
      // 字符串字面量默认是 'static 的(存储在二进制文件中)
      fn get_static() -> &'static str {
          "this lives forever"
      }
      
      // 注意:'static 不一定意味着"永远存活"
      // 而是意味着"可以永远存活"(数据存储在只读内存中)
      // 但引用本身可以提前丢弃

      生命周期子类型

      // 'a 活得比 'b 久:'a: 'b
      fn example<'a: 'b, 'b>(x: &'a str, y: &'b str) -> &'b str {
          // 可以返回 y,也可以返回 x(因为 'a 比 'b 长)
          if x.len() > y.len() { x } else { y }
      }

      14. 闭包与迭代器

      闭包(Closures)

      闭包是可以捕获环境的匿名函数:

      fn main() {
          // 基本语法
          let add_one = |x: i32| -> i32 { x + 1 };
          let multiply = |x, y| x * y;
          let add = |x, y| { x + y };
          
          // 类型推断
          let expensive = |x: i32| -> i32 {
              println!("calculating...");
              x * 2
          };
          
          // 捕获环境变量(三种方式)
          let name = String::from("world");
          let greet = || println!("Hello, {}!", name);  // 不可变借用 &T
          greet();
          println!("{}", name);  // name 仍然可用
          
          // 可变借用
          let mut count = 0;
          let mut inc = || {
              count += 1;
              println!("count: {}", count);
          };
          inc();
          inc();
          println!("final: {}", count);
          
          // 获取所有权(move)
          let s = String::from("hello");
          let consume = move || {
              println!("{}", s);
          };
          // s 不再可用,所有权已转移给闭包
          consume();
          
          // move 在多线程中特别重要
          use std::thread;
          let data = vec![1, 2, 3];
          thread::spawn(move || {
              println!("Captured: {:?}", data);
          }).join().unwrap();
      }

      Fn Trait 族

      // FnOnce: 只能调用一次,获取所有权(自动实现于所有闭包)
      // FnMut: 可以多次调用,可变借用
      // Fn: 可以多次调用,不可变借用
      
      // 关系:Fn <: FnMut <: FnOnce
      // 实现了 Fn 的闭包也自动实现了 FnMut 和 FnOnce
      
      fn apply_once<F: FnOnce(i32) -> i32>(f: F, x: i32) -> i32 {
          f(x)
      }
      
      fn apply_mut<F: FnMut()>(mut f: F) {
          f();
          f();
      }
      
      fn apply_ref<F: Fn()>(f: F) {
          f();
          f();
          f();
      }
      
      // 返回闭包
      fn make_adder(x: i32) -> impl Fn(i32) -> i32 {
          move |y| x + y
      }
      
      // 需要 FnMut 时用 Box
      fn make_counter() -> Box<dyn FnMut() -> i32> {
          let mut count = 0;
          Box::new(move || {
              count += 1;
              count
          })
      }
      
      fn main() {
          let add5 = make_adder(5);
          println!("{}", add5(3));  // 8
          
          let mut counter = make_counter();
          println!("{}", counter());  // 1
          println!("{}", counter());  // 2
      }

      迭代器

      fn main() {
          let v = vec![1, 2, 3, 4, 5];
          
          // iter() - 不可变引用(最常用)
          for val in v.iter() {
              println!("{}", val);
          }
          
          // into_iter() - 获取所有权
          for val in v.into_iter() {
              println!("{}", val);
          }
          
          // iter_mut() - 可变引用
          let mut v = vec![1, 2, 3];
          for val in v.iter_mut() {
              *val *= 2;
          }
          
          // 常用迭代器适配器
          let v = vec![1, 2, 3, 4, 5];
          
          let doubled: Vec<_> = v.iter().map(|x| x * 2).collect();
          let evens: Vec<_> = v.iter().filter(|x| x % 2 == 0).collect();
          let sum: i32 = v.iter().sum();
          let count = v.iter().count();
          let max = v.iter().max();
          let min = v.iter().min();
          
          // 链式调用
          let result: Vec<_> = (1..10)
              .filter(|x| x % 2 != 0)
              .map(|x| x * x)
              .take(3)
              .collect();  // [1, 9, 25]
          
          // fold / reduce
          let sum = v.iter().fold(0, |acc, &x| acc + x);
          let product = v.iter().product::<i32>();
          let reduced = v.iter().copied().reduce(|acc, x| acc + x);
          
          // enumerate
          for (i, val) in v.iter().enumerate() {
              println!("[{}]: {}", i, val);
          }
          
          // zip
          let names = vec!["Alice", "Bob"];
          let ages = vec![30, 25];
          let zipped: Vec<_> = names.iter().zip(ages.iter()).collect();
          
          // any / all
          let has_even = v.iter().any(|&x| x % 2 == 0);
          let all_positive = v.iter().all(|&x| x > 0);
          
          // find / position
          let first_even = v.iter().find(|&x| x % 2 == 0);
          let pos = v.iter().position(|&x| x == 3);
          
          // flatten / flat_map
          let nested = vec![vec![1, 2], vec![3, 4]];
          let flat: Vec<_> = nested.iter().flatten().collect(); // [1,2,3,4]
          
          // partition
          let (evens, odds): (Vec<_>, Vec<_>) = v.iter().partition(|&x| x % 2 == 0);
          
          // inspect (调试用)
          v.iter()
              .inspect(|x| println!("before: {}", x))
              .map(|x| x * 2)
              .inspect(|x| println!("after: {}", x))
              .for_each(|x| println!("result: {}", x));
      }

      15. 迭代器进阶

      Iterator trait 详解

      pub trait Iterator {
          type Item;
          
          // 必须实现
          fn next(&mut self) -> Option<Self::Item>;
          
          // 提供默认实现的常用方法:
          fn size_hint(&self) -> (usize, Option<usize>);
          fn count(self) -> usize;
          fn last(self) -> Option<Self::Item>;
          fn nth(&mut self, n: usize) -> Option<Self::Item>;
          fn step_by(self, step: usize) -> StepBy<Self>;
          fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter>;
          fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>;
          fn map<B, F>(self, f: F) -> Map<Self, F>;
          fn filter<P>(self, predicate: P) -> Filter<Self, P>;
          fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>;
          fn enumerate(self) -> Enumerate<Self>;
          fn peekable(self) -> Peekable<Self>;
          fn skip(self, n: usize) -> Skip<Self>;
          fn take(self, n: usize) -> Take<Self>;
          fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>;
          fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>;
          fn flat_map<F, U>(self, f: F) -> FlatMap<Self, U, F>;
          fn flatten(self) -> Flatten<Self>;
          fn fuse(self) -> Fuse<Self>;
          fn inspect<F>(self, f: F) -> Inspect<Self, F>;
          fn by_ref(&mut self) -> &mut Self;
          fn fold<B, F>(self, init: B, f: F) -> B;
          fn all<F>(&mut self, f: F) -> bool;
          fn any<F>(&mut self, f: F) -> bool;
          fn find<P>(&mut self, predicate: P) -> Option<Self::Item>;
          fn find_map<B, F>(&mut self, f: F) -> Option<B>;
          fn position<P>(&mut self, predicate: P) -> Option<usize>;
          fn collect<B: FromIterator<Self::Item>>(self) -> B;
          fn partition<B, F>(self, f: F) -> (B, B);
          fn for_each<F>(self, f: F);
          fn sum<S>(self) -> S;
          fn product<P>(self) -> P;
          fn min(self) -> Option<Self::Item>;
          fn max(self) -> Option<Self::Item>;
          fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>;
          fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>;
          fn rev(self) -> Rev<Self>;
          fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB);
          fn copied<'a, T>(self) -> Copied<Self>;
          fn cloned<'a, T>(self) -> Cloned<Self>;
          fn cycle(self) -> Cycle<Self>;
      }

      IntoIterator trait

      // for 循环自动调用 into_iter()
      for item in collection {
          // ...
      }
      // 等价于:
      let mut iter = collection.into_iter();
      while let Some(item) = iter.next() {
          // ...
      }
      
      // 三种迭代方式
      let v = vec![1, 2, 3];
      
      // 1. &Vec<T> -> IntoIterator (不可变引用)
      for x in &v { }              // x: &i32
      
      // 2. &mut Vec<T> -> IntoIterator (可变引用)
      for x in &mut v { }          // x: &mut i32
      
      // 3. Vec<T> -> IntoIterator (所有权)
      for x in v { }                // x: i32

      自定义迭代器

      // 斐波那契数列迭代器
      struct Fibonacci {
          a: u64,
          b: u64,
      }
      
      impl Fibonacci {
          fn new() -> Self {
              Fibonacci { a: 0, b: 1 }
          }
      }
      
      impl Iterator for Fibonacci {
          type Item = u64;
          
          fn next(&mut self) -> Option<Self::Item> {
              let result = self.a;
              let next = self.a + self.b;
              self.a = self.b;
              self.b = next;
              Some(result)
          }
      }
      
      fn main() {
          let fib: Vec<_> = Fibonacci::new().take(10).collect();
          println!("{:?}", fib);  // [0,1,1,2,3,5,8,13,21,34]
          
          // 过滤偶数
          let even_fibs: Vec<_> = Fibonacci::new()
              .filter(|&x| x % 2 == 0)
              .take(5)
              .collect();
          println!("{:?}", even_fibs);  // [0,2,8,34,144]
      }
      
      // 范围类型迭代器
      struct Range {
          current: i32,
          end: i32,
      }
      
      impl Iterator for Range {
          type Item = i32;
          
          fn next(&mut self) -> Option<Self::Item> {
              if self.current < self.end {
                  let result = self.current;
                  self.current += 1;
                  Some(result)
              } else {
                  None
              }
          }
      }
      
      // 实现 ExactSizeIterator 提供精确长度信息
      impl ExactSizeIterator for Range {
          fn len(&self) -> usize {
              (self.end - self.current) as usize
          }
      }
      
      // 实现 DoubleEndedIterator 支持反向迭代
      impl DoubleEndedIterator for Range {
          fn next_back(&mut self) -> Option<Self::Item> {
              if self.current < self.end {
                  self.end -= 1;
                  Some(self.end)
              } else {
                  None
              }
          }
      }

      迭代器性能

      Rust 迭代器是惰性求值(lazy)的,只有调用消耗器(如 collectfor)时才会执行。编译器能极大优化迭代器链:

      // 编译器会优化成类似这样的代码:
      let result: Vec<i32> = (1..100)
          .filter(|x| x % 2 == 0)
          .map(|x| x * 2)
          .collect();
      
      // 优化后:
      let mut result = Vec::new();
      for x in 1..100 {
          if x % 2 == 0 {
              result.push(x * 2);
          }
      }
      // 甚至进一步优化为无分配、向量化等

      最佳实践:

      优先使用迭代器而非手写循环。编译器通过内联、循环展开、向量化等技术,通常能让迭代器链达到与手写循环相同甚至更好的性能。

      FromIterator trait

      // 让类型可以通过 collect() 收集
      use std::iter::FromIterator;
      
      struct MyCollection {
          data: Vec<i32>,
      }
      
      impl FromIterator<i32> for MyCollection {
          fn from_iter<I: IntoIterator<Item = i32>>(iter: I) -> Self {
              MyCollection {
                  data: iter.into_iter().collect(),
              }
          }
      }
      
      let c: MyCollection = (0..10).collect();
      
      // 字符串收集
      let s: String = "hello".chars().filter(|c| *c != 'l').collect();  // "heo"
      
      // HashMap 收集
      use std::collections::HashMap;
      let pairs = vec![("a", 1), ("b", 2)];
      let map: HashMap<_, _> = pairs.into_iter().collect();

      16. 智能指针

      Box<T> - 堆上分配

      fn main() {
          // 将数据放在堆上
          let b = Box::new(5);
          println!("b = {}", b);
          
          // 递归类型必须用 Box(编译时需要知道大小)
          enum List {
              Cons(i32, Box<List>),
              Nil,
          }
          
          use List::{Cons, Nil};
          let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
          
          // Box 用于返回 trait object
          fn make_shape(kind: &str) -> Box<dyn Drawable> {
              match kind {
                  "circle" => Box::new(Circle { radius: 5.0 }),
                  _ => Box::new(Square { side: 4.0 }),
              }
          }
          
          // Box::leak - 永久泄露,获得 'static 引用
          let static_str: &'static str = Box::leak(Box::new(String::from("hello")));
      }

      Rc<T> - 引用计数(单线程)

      use std::rc::Rc;
      
      fn main() {
          let a = Rc::new(5);
          println!("引用计数: {}", Rc::strong_count(&a));  // 1
          
          let b = Rc::clone(&a);  // 计数变为 2
          let c = Rc::clone(&a);  // 计数变为 3
          
          println!("引用计数: {}", Rc::strong_count(&a));  // 3
          
          {
              let d = Rc::clone(&a);
              println!("引用计数: {}", Rc::strong_count(&a));  // 4
          }  // d 被 drop,计数变为 3
          
          // Rc 只支持不可变引用
          // 需要内部可变性时使用 RefCell
          
          // Weak 弱引用(避免循环引用)
          use std::rc::Weak;
          let strong = Rc::new(42);
          let weak: Weak<i32> = Rc::downgrade(&strong);
          println!("strong: {}, weak: {}", 
              Rc::strong_count(&strong),
              Rc::weak_count(&strong));
          
          // 升级弱引用
          if let Some(upgraded) = weak.upgrade() {
              println!("值: {}", *upgraded);
          }
      }
      
      // 注意:Rc 不是线程安全的,多线程使用 Arc

      RefCell<T> - 内部可变性

      use std::cell::RefCell;
      
      fn main() {
          let data = RefCell::new(5);
          
          let val = data.borrow();      // 不可变借用 Ref<T>
          println!("{}", *val);
          
          {
              let mut val_mut = data.borrow_mut();  // 可变借用 RefMut<T>
              *val_mut += 10;
          }
          
          println!("{}", *data.borrow());  // 15
          
          // 违反借用规则会运行时 panic
          // let a = data.borrow();
          // let b = data.borrow_mut();  // panic!
          
          // Rc + RefCell = 多所有者 + 可变性
          use std::rc::Rc;
          let shared = Rc::new(RefCell::new(vec![1, 2, 3]));
          let clone1 = Rc::clone(&shared);
          shared.borrow_mut().push(4);
          println!("{:?}", clone1.borrow());
          
          // try_borrow - 失败返回 Result
          let r1 = data.try_borrow();
          let r2 = data.try_borrow_mut();  // Err 因为 r1 还持有借用
      }

      Arc<T> - 原子引用计数(线程安全)

      use std::sync::Arc;
      use std::thread;
      
      fn main() {
          let data = Arc::new(vec![1, 2, 3]);
          
          let handles: Vec<_> = (0..3).map(|i| {
              let data = Arc::clone(&data);
              thread::spawn(move || {
                  println!("Thread {}: {:?}", i, data);
              })
          }).collect();
          
          for h in handles {
              h.join().unwrap();
          }
      }
      
      // Arc<Mutex<T>> = 多线程共享可变数据
      use std::sync::Mutex;
      let counter = Arc::new(Mutex::new(0));
      let c = Arc::clone(&counter);
      thread::spawn(move || {
          *c.lock().unwrap() += 1;
      });

      Cow<T> - Clone on Write

      use std::borrow::Cow;
      
      // 避免不必要的拷贝
      fn remove_spaces(input: &str) -> Cow<str> {
          if input.contains(' ') {
              Cow::Owned(input.replace(" ", ""))
          } else {
              Cow::Borrowed(input)
          }
      }
      
      fn main() {
          let a = remove_spaces("hello");       // 借用,无拷贝
          let b = remove_spaces("hello world"); // 拥有,拷贝
          
          // 统一使用
          println!("a: {}", a);
          println!("b: {}", b);
          
          // 转为 owned
          let owned: String = a.into_owned();
      }

      智能指针对比

      类型作用线程安全可变性
      Box<T>堆分配,独占所有权通过 &mut
      Rc<T>引用计数,多所有者不可变
      Arc<T>原子引用计数不可变
      RefCell<T>运行时借用检查内部可变
      Mutex<T>互斥锁保护内部可变
      RwLock<T>读写锁内部可变
      Cow<T>写时克隆--

      17. 并发编程

      线程

      use std::thread;
      use std::time::Duration;
      
      fn main() {
          let handle = thread::spawn(|| {
              for i in 1..5 {
                  println!("子线程: {}", i);
                  thread::sleep(Duration::from_millis(100));
              }
          });
          
          for i in 1..3 {
              println!("主线程: {}", i);
              thread::sleep(Duration::from_millis(100));
          }
          
          handle.join().unwrap();  // 等待子线程完成
          
          // move 闭包转移所有权
          let s = String::from("hello");
          let handle = thread::spawn(move || {
              println!("{}", s);
          });
          handle.join().unwrap();
          
          // 线程构建器
          let builder = thread::Builder::new()
              .name("my-thread".into())
              .stack_size(32 * 1024 * 1024);  // 32MB
          let handler = builder.spawn(|| {
              println!("Named thread");
          }).unwrap();
          
          // 当前线程信息
          let id = thread::current().id();
          let name = thread::current().name();
          
          // 线程作用域 (Rust 1.63+)
          let mut data = vec![1, 2, 3];
          thread::scope(|s| {
              s.spawn(|| {
                  println!("{:?}", data);  // 借用 data,安全
              });
              s.spawn(|| {
                  data.push(4);  // 可变借用
              });
          });  // 所有线程在此结束
      }

      消息传递 - Channel

      use std::sync::mpsc;  // multi-producer, single-consumer
      use std::thread;
      use std::time::Duration;
      
      fn main() {
          let (tx, rx) = mpsc::channel();
          
          // 克隆发送端用于多线程
          let tx2 = tx.clone();
          
          thread::spawn(move || {
              let vals = vec!["hi", "from", "thread"];
              for val in vals {
                  tx.send(val).unwrap();
                  thread::sleep(Duration::from_millis(100));
              }
          });
          
          thread::spawn(move || {
              tx2.send("another message").unwrap();
          });
          
          // 接收(阻塞)
          for received in rx {
              println!("收到: {}", received);
          }
          
          // 非阻塞接收
          match rx.try_recv() {
              Ok(msg) => println!("{}", msg),
              Err(mpsc::TryRecvError::Empty) => println!("空"),
              Err(mpsc::TryRecvError::Disconnected) => println!("已断开"),
          }
          
          // 带超时的接收
          match rx.recv_timeout(Duration::from_secs(1)) {
              Ok(msg) => println!("{}", msg),
              Err(e) => println!("Error: {:?}", e),
          }
      }

      共享状态 - Mutex 和 RwLock

      use std::sync::{Arc, Mutex, RwLock};
      use std::thread;
      
      fn main() {
          // Mutex - 互斥锁
          let counter = Arc::new(Mutex::new(0));
          let mut handles = vec![];
          
          for _ in 0..10 {
              let counter = Arc::clone(&counter);
              let handle = thread::spawn(move || {
                  let mut num = counter.lock().unwrap();
                  *num += 1;
              });
              handles.push(handle);
          }
          
          for handle in handles {
              handle.join().unwrap();
          }
          
          println!("结果: {}", *counter.lock().unwrap());  // 10
          
          // RwLock - 读写锁(多读单写)
          let data = Arc::new(RwLock::new(vec![1, 2, 3]));
          
          // 多个读锁可同时持有
          let r1 = Arc::clone(&data);
          let r2 = Arc::clone(&data);
          thread::spawn(move || {
              let read = r1.read().unwrap();
              println!("r1: {:?}", *read);
          });
          thread::spawn(move || {
              let read = r2.read().unwrap();
              println!("r2: {:?}", *read);
          });
          
          // 写锁(独占)
          let w = Arc::clone(&data);
          thread::spawn(move || {
              let mut write = w.write().unwrap();
              write.push(4);
          });
      }

      原子类型

      use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering};
      use std::sync::Arc;
      use std::thread;
      
      fn main() {
          let counter = Arc::new(AtomicUsize::new(0));
          let running = Arc::new(AtomicBool::new(true));
          
          let mut handles = vec![];
          
          for _ in 0..10 {
              let counter = Arc::clone(&counter);
              let handle = thread::spawn(move || {
                  for _ in 0..1000 {
                      counter.fetch_add(1, Ordering::SeqCst);
                  }
              });
              handles.push(handle);
          }
          
          for h in handles {
              h.join().unwrap();
          }
          
          println!("Final: {}", counter.load(Ordering::SeqCst));  // 10000
      }
      
      // 常用原子操作:
      // - load: 读取
      // - store: 写入
      // - swap: 交换
      // - compare_exchange: CAS 操作
      // - fetch_add, fetch_sub, fetch_or 等
      
      // Ordering 内存顺序:
      // - Relaxed: 无同步保证
      // - Acquire: 读操作同步
      // - Release: 写操作同步
      // - AcqRel: 读写同步
      // - SeqCst: 顺序一致(最强)

      Send 和 Sync Trait

      // Send: 类型的所有权可以跨线程转移
      // Sync: 类型的引用可以跨线程共享(&T 是 Send 的)
      
      // 几乎所有类型都是 Send 和 Sync 的
      // 例外:Rc 不是 Send/Sync(使用 Arc)
      //      RefCell 不是 Sync(使用 Mutex)
      //      裸指针不是 Send/Sync
      
      // 手动实现(unsafe)
      struct MyType {
          ptr: *const i32,
      }
      
      unsafe impl Send for MyType {}
      unsafe impl Sync for MyType {}
      
      // 函数中的 Send 约束
      fn spawn_task<T>(f: impl FnOnce() -> T + Send + 'static) 
          -> thread::JoinHandle<T>
      where
          T: Send + 'static,
      {
          thread::spawn(f)
      }

      Rayon - 数据并行

      use rayon::prelude::*;
      
      fn main() {
          let numbers: Vec<i32> = (0..1_000_000).collect();
          
          // 并行迭代(自动分块多线程处理)
          let sum: i64 = numbers.par_iter()
              .map(|&x| x as i64)
              .sum();
          
          // 并行 for_each
          numbers.par_iter().for_each(|&x| {
              // 并行处理每个元素
          });
          
          // 并行排序
          let mut data = vec![3, 1, 4, 1, 5, 9, 2, 6];
          data.par_sort_unstable();
          
          // 配置线程池
          use rayon::ThreadPoolBuilder;
          let pool = ThreadPoolBuilder::new()
              .num_threads(8)
              .build()
              .unwrap();
          
          pool.install(|| {
              numbers.par_iter().map(|x| x * 2).collect::<Vec<_>>()
          });
      }

      18. 异步深入

      Future trait

      // Future 是异步计算的核心抽象
      use std::pin::Pin;
      use std::task::{Context, Poll};
      
      pub trait Future {
          type Output;
          
          fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
      }
      
      pub enum Poll<T> {
          Ready(T),
          Pending,
      }
      
      // async fn 返回实现了 Future 的类型
      async fn hello() -> String {
          String::from("Hello, world!")
      }
      
      // 等价于(编译器生成):
      fn hello() -> impl Future<Output = String> {
          async {
              String::from("Hello, world!")
          }
      }

      async/await 详解

      use tokio;
      
      // 基础异步函数
      async fn fetch_data(url: &str) -> Result<String, reqwest::Error> {
          let response = reqwest::get(url).await?;
          response.text().await
      }
      
      // 异步闭包
      let async_closure = async |x: i32| -> i32 {
          // 异步操作
          x * 2
      };
      
      // 异步块
      let future = async {
          let x = compute().await;
          x + 1
      };
      
      // 并发执行多个异步任务
      #[tokio::main]
      async fn main() {
          // tokio::join! - 并发等待多个 future
          let (r1, r2, r3) = tokio::join!(
              fetch_data("https://api1.example.com"),
              fetch_data("https://api2.example.com"),
              fetch_data("https://api3.example.com"),
          );
          
          // tokio::try_join! - 任一失败则提前返回
          let result = tokio::try_join!(
              fetch_data("https://api1.example.com"),
              fetch_data("https://api2.example.com"),
          );
          
          // tokio::select! - 等待第一个完成的
          let fastest = tokio::select! {
              r1 = fetch_data("https://api1.example.com") => r1,
              r2 = fetch_data("https://api2.example.com") => r2,
          };
          
          // spawn 创建新任务
          let handle = tokio::spawn(async {
              // 异步工作
              42
          });
          let result = handle.await.unwrap();
          
          // 超时
          use tokio::time::{timeout, Duration};
          let result = timeout(Duration::from_secs(5), fetch_data("https://api.example.com")).await;
          match result {
              Ok(Ok(data)) => println!("成功: {}", data),
              Ok(Err(e)) => println!("失败: {}", e),
              Err(_) => println!("超时"),
          }
      }

      Stream trait(异步迭代器)

      use futures::stream::{self, Stream, StreamExt};
      
      // Stream 是 Future 的迭代版本
      pub trait Stream {
          type Item;
          fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) 
              -> Poll<Option<Self::Item>>;
      }
      
      async fn process_stream() {
          // 创建 stream
          let mut stream = stream::iter(1..=5);
          
          // 消费 stream
          while let Some(value) = stream.next().await {
              println!("{}", value);
          }
          
          // 链式操作
          let result: Vec<_> = stream::iter(1..=10)
              .filter(|x| async { *x % 2 == 0 })
              .map(|x| async { x * 2 })
              .collect().await;
          
          // channel 作为 stream
          use tokio::sync::mpsc;
          let (tx, mut rx) = mpsc::channel(100);
          
          tokio::spawn(async move {
              for i in 0..10 {
                  tx.send(i).await.unwrap();
              }
          });
          
          while let Some(msg) = rx.recv().await {
              println!("{}", msg);
          }
      }

      Pin 和 Unpin

      // Pin 确保值在内存中的位置不会改变
      // 对于自引用的异步状态机是必需的
      
      use std::pin::Pin;
      
      // 大多数类型是 Unpin 的(可以在内存中移动)
      // 例如:i32, String, Vec<T>, Box<T>
      
      // 自引用结构体需要 Pin
      struct SelfReferential {
          value: String,
          reference: *const String,  // 指向 value
      }
      
      // 实现 !Unpin(不能移动)
      use std::marker::PhantomPinned;
      struct NotMovable {
          value: String,
          _pin: PhantomPinned,
      }
      
      // Pin::new 用于 Unpin 类型
      let mut boxed = Box::new(5);
      let pinned = Pin::new(&mut boxed);
      
      // Pin::new_unchecked 用于非 Unpin 类型(需要保证不移动)
      // Box::pin 创建堆上的 pinned 值
      let pinned = Box::pin(NotMovable { 
          value: String::from("test"), 
          _pin: PhantomPinned,
      });

      异步运行时对比

      运行时特点适用场景
      tokio最成熟,生态最丰富,多线程大多数 Web 服务
      async-std标准库风格的 API学习、简单应用
      smol极简、轻量嵌入式、小型工具
      glommio单线程、thread-per-core高性能数据库
      monoioio_uring、thread-per-core极致性能场景

      选择 tokio 的理由:

      最丰富的生态(reqwest、sqlx、axum 等都基于 tokio),最活跃的社区,完善的多线程支持,生产环境久经考验。

      19. Cargo 与生态

      Cargo 常用命令

      # 项目管理
      cargo new my_project          # 创建新项目
      cargo new --lib my_lib        # 创建库项目
      cargo init                    # 在当前目录初始化
      cargo build                   # 编译
      cargo build --release         # 优化编译
      cargo run                     # 编译并运行
      cargo check                   # 快速类型检查(最快)
      cargo test                    # 运行测试
      cargo test -- --test-threads=1  # 单线程测试
      cargo doc --open              # 生成文档
      cargo doc --no-deps           # 不包含依赖文档
      cargo clippy                  # 代码检查(lint)
      cargo clippy --fix            # 自动修复
      cargo fmt                     # 代码格式化
      cargo fmt -- --check          # 检查是否已格式化
      cargo bench                   # 性能测试
      
      # 依赖管理
      cargo add serde              # 添加依赖
      cargo add tokio --features full
      cargo add serde --dev         # dev-dependencies
      cargo add serde --optional    # 可选依赖
      cargo remove serde            # 移除依赖
      cargo update                  # 更新依赖
      cargo update -p serde         # 更新特定依赖
      cargo tree                    # 查看依赖树
      cargo tree -d                 # 查看重复依赖
      cargo outdated                # 查看过期依赖(需安装)
      
      # 工作区
      cargo workspace               # 管理工作区
      
      # 发布
      cargo login                   # 登录 crates.io
      cargo publish --dry-run       # 测试发布
      cargo publish                 # 发布包
      cargo yank --vers 1.0.0       # 撤回版本
      
      # 工具
      cargo install ripgrep         # 安装全局工具
      cargo uninstall ripgrep
      cargo clean                   # 清理构建产物
      cargo metadata                # 输出元数据(JSON)

      Cargo.toml 配置

      # Cargo.toml 示例
      [package]
      name = "my_project"
      version = "0.1.0"
      edition = "2021"
      authors = ["Your Name <you@example.com>"]
      description = "A great project"
      license = "MIT"
      license-file = "LICENSE"
      repository = "https://github.com/user/repo"
      documentation = "https://docs.rs/my_project"
      homepage = "https://example.com"
      readme = "README.md"
      keywords = ["cli", "tool"]
      categories = ["command-line-utilities"]
      exclude = ["/.github", "/tests"]
      include = ["/src", "/Cargo.toml"]
      publish = true                # false 则不发布
      rust-version = "1.70"        # 最低 Rust 版本
      
      [dependencies]
      serde = { version = "1.0", features = ["derive"] }
      tokio = { version = "1", features = ["full"] }
      reqwest = { version = "0.11", features = ["json"], optional = true }
      anyhow = "1.0"
      thiserror = "1.0"
      log = "0.4"
      env_logger = "0.10"
      local_crate = { path = "../local_crate" }
      git_crate = { git = "https://github.com/user/repo", branch = "main" }
      
      [dev-dependencies]
      criterion = { version = "0.5", features = ["html_reports"] }
      mockall = "0.11"
      
      [build-dependencies]
      cc = "1.0"
      
      [[bench]]
      name = "my_benchmark"
      harness = false
      
      [features]
      default = ["std"]
      std = []
      json = ["serde", "reqwest"]
      full = ["std", "json"]
      
      [profile.dev]
      opt-level = 0
      debug = true
      debug-assertions = true
      overflow-checks = true
      
      [profile.release]
      opt-level = 3
      debug = false
      strip = true               # 剥离符号
      lto = true                 # 链接时优化
      codegen-units = 1          # 最大化优化
      panic = "abort"            # 减少体积
      incremental = false
      
      [profile.test]
      opt-level = 1
      
      [workspace]
      members = ["crate1", "crate2", "apps/*"]
      exclude = ["legacy"]
      
      # 别名
      [alias]
      b = "build --release"
      t = "test"
      r = "run"
      c = "check"

      工作区(Workspace)

      # 根 Cargo.toml
      [workspace]
      members = [
          "core",
          "cli",
          "web",
          "common",
      ]
      
      # 工作区级别的依赖配置(统一版本)
      [workspace.dependencies]
      serde = { version = "1.0", features = ["derive"] }
      tokio = { version = "1", features = ["full"] }
      anyhow = "1.0"
      
      [workspace.package]
      version = "0.1.0"
      edition = "2021"
      authors = ["Team"]
      
      # 子包 Cargo.toml(如 core/Cargo.toml)
      [package]
      name = "my-core"
      version.workspace = true
      edition.workspace = true
      
      [dependencies]
      serde.workspace = true
      anyhow.workspace = true
      
      # 工作区命令
      cargo build --workspace       # 构建所有成员
      cargo test --workspace
      cargo clippy --workspace
      cargo build -p my-core        # 构建特定成员

      常用 Crate 生态

      类别Crate说明
      序列化serde, serde_json, serde_yaml, toml序列化标准
      异步tokio, async-std, futures异步运行时
      HTTPreqwest, hyper, ureqHTTP 客户端/服务器
      Web 框架axum, actix-web, rocket, warpWeb 开发
      数据库sqlx, diesel, sea-orm, sled数据库访问
      命令行clap, structopt参数解析
      正则regex正则表达式
      时间chrono, time日期时间
      错误anyhow, thiserror错误处理
      日志log, tracing, env_logger日志追踪
      并行rayon, crossbeam并行计算
      随机rand随机数
      加密ring, rustls, sha2, aes-gcm密码学
      压缩flate2, zip, tar压缩解压
      图片image图片处理
      GUItauri, iced, egui图形界面

      20. 测试进阶

      单元测试

      // 在同一文件中的测试
      pub fn add(a: i32, b: i32) -> i32 {
          a + b
      }
      
      pub fn divide(a: f64, b: f64) -> Result<f64, String> {
          if b == 0.0 {
              Err(String::from("除数为零"))
          } else {
              Ok(a / b)
          }
      }
      
      #[cfg(test)]
      mod tests {
          use super::*;
          
          #[test]
          fn test_add() {
              assert_eq!(add(2, 3), 5);
              assert_ne!(add(2, 3), 6);
              assert!(add(2, 3) > 4);
          }
          
          #[test]
          fn test_add_with_message() {
              assert_eq!(add(2, 3), 5, "2 + 3 should equal 5");
          }
          
          #[test]
          fn test_divide() {
              assert_eq!(divide(10.0, 2.0), Ok(5.0));
              assert!(divide(10.0, 0.0).is_err());
          }
          
          #[test]
          fn test_with_result() -> Result<(), String> {
              if 2 + 2 == 4 {
                  Ok(())
              } else {
                  Err(String::from("math is broken"))
              }
          }
          
          #[test]
          #[should_panic(expected = "index out of bounds")]
          fn test_should_panic() {
              let v: Vec<i32> = vec![];
              v[100];
          }
          
          #[test]
          #[ignore]
          fn expensive_test() {
              // 耗时的测试
              // cargo test -- --ignored 运行
          }
          
          #[tokio::test]
          async fn test_async() {
              let result = async { 42 }.await;
              assert_eq!(result, 42);
          }
      }
      
      # 运行测试命令
      cargo test                       # 运行所有测试
      cargo test test_add              # 运行匹配名称的测试
      cargo test -- --test-threads=1   # 单线程运行
      cargo test -- --nocapture        # 显示 println 输出
      cargo test -- --ignored          # 只运行 ignored 测试
      cargo test -- --skip slow        # 跳过名称含 slow 的测试

      集成测试

      // tests/integration_test.rs
      // 每个文件是独立的 crate,只能访问公开的 API
      use my_crate;
      
      #[test]
      fn test_public_api() {
          assert_eq!(my_crate::add(2, 3), 5);
      }
      
      // tests/common/mod.rs - 共享测试辅助
      pub fn setup() -> TestContext {
          // 初始化测试环境
      }
      
      // tests/integration_test.rs
      mod common;
      
      #[test]
      fn test_with_setup() {
          let ctx = common::setup();
          // 测试...
      }

      文档测试(Doc Tests)

      /// 计算两数之和
      ///
      /// # Examples
      ///
      /// ```
      /// let result = my_crate::add(2, 3);
      /// assert_eq!(result, 5);
      /// ```
      ///
      /// # Panics
      ///
      /// 不会 panic
      pub fn add(a: i32, b: i32) -> i32 {
          a + b
      }
      
      /// 可能失败的示例
      ///
      /// ```should_panic
      /// panic!("this will panic");
      /// ```
      ///
      /// 隐藏部分代码
      ///
      /// ```
      /// # // 这行不会显示在文档中
      /// # use my_crate::add;
      /// assert_eq!(add(2, 3), 5);
      /// ```
      ///
      /// 不运行的代码
      ///
      /// ```ignore
      /// some_complex_code();
      /// ```
      ///
      /// 不编译的代码
      ///
      /// ```compile_fail
      /// let x: i32 = "not a number";
      /// ```
      ///
      /// 不测试的代码
      ///
      /// ```no_run
      /// loop_forever();
      /// ```
      pub fn documented_function() { }
      
      # 运行文档测试
      cargo test --doc

      基准测试

      // benches/my_benchmark.rs
      use criterion::{criterion_group, criterion_main, Criterion, black_box};
      
      fn fibonacci(n: u64) -> u64 {
          match n {
              0 => 0,
              1 => 1,
              _ => fibonacci(n - 1) + fibonacci(n - 2),
          }
      }
      
      fn benchmark_fibonacci(c: &mut Criterion) {
          c.bench_function("fib 20", |b| {
              b.iter(|| fibonacci(black_box(20)))
          });
      }
      
      // 参数化基准测试
      fn benchmark_fibonacci_params(c: &mut Criterion) {
          let mut group = c.benchmark_group("fibonacci");
          for n in [10, 15, 20] {
              group.bench_function(format!("fib {}", n), |b| {
                  b.iter(|| fibonacci(black_box(n)))
              });
          }
          group.finish();
      }
      
      criterion_group!(benches, benchmark_fibonacci);
      criterion_main!(benches);
      
      # 运行基准测试
      cargo bench
      cargo bench -- --save-baseline master
      cargo bench -- --baseline master  # 与之前对比

      测试辅助工具

      // mockall - 自动生成 mock
      use mockall::*;
      
      #[automock]
      trait Database {
          fn get_user(&self, id: u32) -> Option<User>;
          fn save_user(&self, user: &User) -> Result<(), Error>;
      }
      
      #[test]
      fn test_with_mock() {
          let mut mock_db = MockDatabase::new();
          mock_db.expect_get_user()
              .with(eq(1))
              .returning(|_| Some(User { name: "Alice".into() }));
          
          // 使用 mock_db...
      }
      
      // pretty_assertions - 更友好的 diff 显示
      use pretty_assertions::{assert_eq, assert_ne};
      
      // insta - 快照测试
      use insta::assert_snapshot;
      
      #[test]
      fn test_snapshot() {
          let output = generate_output();
          assert_snapshot!(output);
      }
      
      # 更新快照
      cargo insta review

      覆盖率测试

      # 安装 cargo-tarpaulin
      cargo install cargo-tarpaulin
      
      # 生成覆盖率报告
      cargo tarpaulin --out Html
      
      # 使用 grcov
      cargo install grcov
      export CARGO_INCREMENTAL=0
      export RUSTFLAGS="-Cinstrument-coverage"
      export LLVM_PROFILE_FILE="coverage-%p-%m.profraw"
      cargo test
      grcov . -s . --binary-path ./target/debug/ -t html --branch --ignore-not-existing -o ./coverage/

      21. 宏

      声明式宏 (macro_rules!)

      // 自定义 vec! 宏的简化版
      #[macro_export]
      macro_rules! vec {
          ( $( $x:expr ),* ) => {
              {
                  let mut temp_vec = Vec::new();
                  $(
                      temp_vec.push($x);
                  )*
                  temp_vec
              }
          };
          ( $( $x:expr ),+ ) => {
              {
                  let mut temp_vec = Vec::new();
                  $(
                      temp_vec.push($x);
                  )+
                  temp_vec
              }
          };
      }
      
      // 使用
      let v = vec![1, 2, 3];
      
      // 多模式匹配
      macro_rules! calculate {
          (eval $e:expr) => {
              {
                  let val: usize = $e;
                  println!("{} = {}", stringify!($e), val);
              }
          };
          (add $a:expr, $b:expr) => {
              $a + $b
          };
      }
      
      calculate!(eval 2 + 3);
      let sum = calculate!(add 5, 10);
      
      // 常见重复模式
      macro_rules! hashmap {
          ( $( $key:expr => $value:expr ),* $(,)? ) => {
              {
                  let mut map = std::collections::HashMap::new();
                  $(
                      map.insert($key, $value);
                  )*
                  map
              }
          };
      }
      let map = hashmap!{
          "a" => 1,
          "b" => 2,
          "c" => 3,
      };

      宏的元变量类型

      类型匹配
      item任何项(函数、结构体、模块等)
      block{ ... }
      stmt语句
      pat模式(Rust 2021+ 使用 pat_param)
      expr表达式
      ty类型
      ident标识符
      path路径 a::b::c
      tt单个 token tree(任意,最灵活)
      meta属性内容
      lifetime生命周期 'a
      literal字面量
      vis可见性修饰符

      重复模式

      // $()* - 零次或多次
      // $()+ - 一次或多次
      // $()? - 零次或一次
      
      macro_rules! print_all {
          ( $( $x:expr ),* ) => {
              $(
                  println!("{}", $x);
              )*
          };
      }
      
      print_all!("a", "b", "c");
      
      // 嵌套重复
      macro_rules! tuples {
          ( $( ( $( $x:expr ),* ) ),* ) => {
              $(
                  $(
                      println!("{}", $x);
                  )*
              )*
          };
      }
      tuples!((1, 2), (3, 4, 5));

      过程宏(Procedural Macros)

      // 过程宏必须在单独的 crate 中定义
      // Cargo.toml:
      # [lib]
      # proc-macro = true
      # [dependencies]
      # syn = "2.0"
      # quote = "1.0"
      # proc-macro2 = "1.0"
      
      use proc_macro::TokenStream;
      use quote::quote;
      use syn::{parse_macro_input, DeriveInput};
      
      // 1. 派生宏(derive)
      #[proc_macro_derive(MyMacro)]
      pub fn my_macro_derive(input: TokenStream) -> TokenStream {
          let input = parse_macro_input!(input as DeriveInput);
          let name = &input.ident;
          
          let expanded = quote! {
              impl #name {
                  fn my_method(&self) -> String {
                      format!("Hello from {}!", stringify!(#name))
                  }
              }
          };
          
          expanded.into()
      }
      
      // 使用:
      #[derive(MyMacro)]
      struct MyStruct;
      
      // 2. 属性宏
      #[proc_macro_attribute]
      pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
          // attr: GET, "/"
          // item: fn index() { ... }
          item
      }
      
      #[route(GET, "/")]
      fn index() { }
      
      // 3. 函数宏
      #[proc_macro]
      pub fn sql(input: TokenStream) -> TokenStream {
          // 解析 SQL 并生成代码
          input
      }

      常用内置宏

      fn main() {
          // 输出
          println!("{} {}", "hello", "world");
          eprintln!("error!");
          print!("no newline");
          
          // 格式化字符串
          let s = format!("Hello, {}!", "Rust");
          let s = format_args!("{}", 42);
          
          // 创建集合
          let v = vec![1, 2, 3];
          
          // 断言
          assert!(true);
          assert_eq!(1 + 1, 2);
          assert_ne!(1, 2);
          debug_assert!(1 == 1);  // 只在 debug 构建
          
          // panic
          // panic!("error: {}", 42);
          
          // 编译时信息
          // compile_error!("This feature is not supported");
          
          // 其他
          let file = file!();
          let line = line!();
          let col = column!();
          let module = module_path!();
          let str = stringify!(some expression);
          todo!();   // 标记未完成代码
          unimplemented!();
          unreachable!();
          let x = dbg!(2 * 3);  // 打印并返回值
          
          // 配置
          #[cfg(target_os = "linux")]
          fn linux_only() { }
          
          // cfg! 宏(运行时)
          if cfg!(target_os = "linux") {
              println!("Running on Linux");
          }
          
          // env! 宏(编译时环境变量)
          let target = env!("TARGET");
          let default = option_env!("OPTIONAL").unwrap_or("default");
          
          // include! 宏
          // include!("other.rs");
          // include_str!("file.txt");
          // include_bytes!("file.bin");
      }

      22. Unsafe Rust

      什么是 Unsafe

      Rust 的 safe 代码无法实现某些底层操作时使用 unsafe。它不会关闭借用检查器,而是提供额外的能力:

      • 解引用裸指针
      • 调用 unsafe 函数或方法
      • 访问或修改可变的静态变量
      • 实现 unsafe trait
      • 访问 union 的字段

      裸指针

      fn main() {
          let mut num = 5;
          
          // 创建裸指针(safe)
          let r1 = &num as *const i32;
          let r2 = &mut num as *mut i32;
          
          // 解引用需要 unsafe
          unsafe {
              println!("r1: {}", *r1);
              println!("r2: {}", *r2);
              *r2 = 10;
              println!("r2 after: {}", *r2);
          }
          
          // 指向任意内存地址
          let address = 0x12345usize;
          let r = address as *const i32;
          // unsafe { *r }  // 可能访问无效内存
          
          // 裸指针方法
          let p: *const i32 = #
          let mut mp: *mut i32 = &mut num;
          
          p.is_null();
          p.as_ref();       // unsafe,返回 Option
          mp.as_mut();
          p.offset(1);      // unsafe,指针运算
          mp.add(1);         // unsafe
          mp.sub(1);
          mp.write(42);      // unsafe
          p.read();          // unsafe
          p.copy_to(mp, 1);  // unsafe
          p.copy_to_nonoverlapping(mp, 1);
      }

      Unsafe 函数

      // 定义 unsafe 函数
      unsafe fn dangerous() {
          println!("This is unsafe!");
      }
      
      // 调用需要 unsafe 块
      unsafe {
          dangerous();
      }
      
      // 安全抽象包装(最常见用法)
      fn safe_wrapper() {
          // 维护安全不变量
          unsafe {
              dangerous();
          }
      }
      
      // split_at_mut 的安全实现(标准库中的例子)
      fn split_at_mut<T>(slice: &mut [T], mid: usize) -> (&mut [T], &mut [T]) {
          let len = slice.len();
          let ptr = slice.as_mut_ptr();
          
          assert!(mid <= len);
          
          unsafe {
              (
                  std::slice::from_raw_parts_mut(ptr, mid),
                  std::slice::from_raw_parts_mut(ptr.add(mid), len - mid),
              )
          }
      }
      
      // 调用外部 C 函数 (FFI)
      extern "C" {
          fn abs(input: i32) -> i32;
          fn malloc(size: usize) -> *mut std::ffi::c_void;
          fn free(ptr: *mut std::ffi::c_void);
      }
      
      fn main() {
          unsafe {
              println!("abs(-3): {}", abs(-3));
          }
      }
      
      // 导出 Rust 函数给 C 调用
      #[no_mangle]
      pub extern "C" fn rust_function(x: i32) -> i32 {
          x * 2
      }

      静态变量与 Trait

      // 可变静态变量
      static mut COUNTER: u32 = 0;
      
      fn add_to_count(inc: u32) {
          unsafe {
              COUNTER += inc;
          }
      }
      
      fn get_counter() -> u32 {
          unsafe {
              COUNTER
          }
      }
      
      // Unsafe trait
      unsafe trait Foo {
          fn method(&self);
      }
      
      unsafe impl Foo for i32 {
          fn method(&self) {
              println!("{}", self);
          }
      }
      
      // Union (共用体,类似 C 的 union)
      union MyUnion {
          f1: u32,
          f2: f32,
      }
      
      fn main() {
          let u = MyUnion { f1: 42 };
          unsafe {
              println!("{}", u.f1);
          }
          
          // 使用 match 安全访问
          fn get_value(u: MyUnion) {
              unsafe {
                  match u {
                      MyUnion { f1 } => println!("u32: {}", f1),
                  }
              }
          }
      }

      使用原则:

      • 只在必要时使用 unsafe
      • 用 safe 抽象包裹 unsafe 代码
      • 文档说明安全约束条件(# Safety 章节)
      • 尽量缩小 unsafe 块的范围
      • 提供安全的公共 API

      安全文档示例

      /// 从指针读取值
      ///
      /// # Safety
      ///
      /// 调用者必须保证:
      /// - 指针非空
      /// - 指针指向有效的、已初始化的 T 类型数据
      /// - 指针具有正确的对齐
      pub unsafe fn read_value<T>(ptr: *const T) -> T {
          // 调用者保证安全,此处直接读取
          *ptr
      }

      23. FFI 外部函数接口

      调用 C 库

      use std::ffi::{CStr, CString};
      use std::os::raw::{c_int, c_char, c_void};
      
      // 声明 C 函数
      extern "C" {
          fn puts(s: *const c_char) -> c_int;
          fn strlen(s: *const c_char) -> usize;
          fn malloc(size: usize) -> *mut c_void;
          fn free(ptr: *mut c_void);
          fn abs(n: c_int) -> c_int;
      }
      
      fn main() {
          unsafe {
              // Rust 字符串转 C 字符串
              let s = CString::new("Hello from Rust!").unwrap();
              puts(s.as_ptr());
              
              // C 字符串转 Rust 字符串
              let c_str = CStr::from_ptr(s.as_ptr());
              let rust_str = c_str.to_str().unwrap();
              println!("{}", rust_str);
              
              // 使用 malloc/free
              let ptr = malloc(std::mem::size_of::<i32>()) as *mut i32;
              *ptr = 42;
              println!("{}", *ptr);
              free(ptr as *mut c_void);
              
              println!("abs(-5): {}", abs(-5));
          }
      }

      使用 bindgen 自动生成绑定

      # 安装 bindgen
      cargo install bindgen-cli
      
      # 生成绑定
      bindgen wrapper.h -o bindings.rs
      
      # 在 build.rs 中使用
      use std::env;
      use std::path::PathBuf;
      
      fn main() {
          // 告诉 cargo 链接 C 库
          println!("cargo:rustc-link-lib=mylib");
          println!("cargo:rustc-link-search=native=/path/to/lib");
          
          // 使用 bindgen 生成绑定
          let bindings = bindgen::Builder::default()
              .header("wrapper.h")
              .parse_callbacks(Box::new(bindgen::CargoCallbacks))
              .generate()
              .expect("Unable to generate bindings");
          
          let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
          bindings
              .write_to_file(out_path.join("bindings.rs"))
              .expect("Couldn't write bindings!");
      }

      导出 Rust 函数给 C 使用

      // lib.rs
      use std::ffi::{CStr, CString};
      use std::os::raw::c_char;
      
      // #[no_mangle] 防止编译器修改符号名
      #[no_mangle]
      pub extern "C" fn rust_add(a: i32, b: i32) -> i32 {
          a + b
      }
      
      #[no_mangle]
      pub extern "C" fn rust_greet(name: *const c_char) -> *mut c_char {
          let name = unsafe { CStr::from_ptr(name) };
          let name = name.to_str().unwrap_or("stranger");
          
          let greeting = format!("Hello, {}!", name);
          let c_string = CString::new(greeting).unwrap();
          c_string.into_raw()  // 转移所有权给 C
      }
      
      // 提供释放函数
      #[no_mangle]
      pub extern "C" fn rust_free_string(s: *mut c_char) {
          if s.is_null() { return; }
          unsafe {
              CString::from_raw(s);  // 重新获取所有权并 drop
          }
      }
      
      // 导出不透明类型
      pub struct MyObject {
          value: i32,
      }
      
      #[no_mangle]
      pub extern "C" fn my_object_new(value: i32) -> *mut MyObject {
          Box::into_raw(Box::new(MyObject { value }))
      }
      
      #[no_mangle]
      pub extern "C" fn my_object_get_value(obj: *const MyObject) -> i32 {
          unsafe { (*obj).value }
      }
      
      #[no_mangle]
      pub extern "C" fn my_object_free(obj: *mut MyObject) {
          if !obj.is_null() {
              unsafe {
                  let _ = Box::from_raw(obj);
              }
          }
      }

      C 与 Rust 类型对照

      C 类型Rust 类型
      intstd::os::raw::c_int (i32)
      unsigned intstd::os::raw::c_uint (u32)
      longstd::os::raw::c_long
      charstd::os::raw::c_char (i8)
      char*mut c_char / const c_char
      const char**const c_char
      void**mut c_void
      size_tusize
      ssize_tisize
      int32_ti32
      uint64_tu64
      boolbool 或 std::os::raw::c_uchar

      推荐工具:

      • bindgen:自动生成 C 头文件的 Rust 绑定
      • cbindgen:从 Rust 代码生成 C 头文件
      • cc crate:在 build.rs 中编译 C/C++ 代码

      24. 设计模式

      Builder 模式

      struct HttpRequest {
          url: String,
          method: String,
          headers: Vec<(String, String)>,
          body: Option<String>,
          timeout: u64,
      }
      
      struct HttpRequestBuilder {
          url: String,
          method: String,
          headers: Vec<(String, String)>,
          body: Option<String>,
          timeout: u64,
      }
      
      impl HttpRequestBuilder {
          fn new(url: &str) -> Self {
              Self {
                  url: url.to_string(),
                  method: "GET".to_string(),
                  headers: Vec::new(),
                  body: None,
                  timeout: 30,
              }
          }
          
          fn method(mut self, method: &str) -> Self {
              self.method = method.to_string();
              self
          }
          
          fn header(mut self, key: &str, value: &str) -> Self {
              self.headers.push((key.to_string(), value.to_string()));
              self
          }
          
          fn body(mut self, body: &str) -> Self {
              self.body = Some(body.to_string());
              self
          }
          
          fn timeout(mut self, seconds: u64) -> Self {
              self.timeout = seconds;
              self
          }
          
          fn build(self) -> HttpRequest {
              HttpRequest {
                  url: self.url,
                  method: self.method,
                  headers: self.headers,
                  body: self.body,
                  timeout: self.timeout,
              }
          }
      }
      
      let request = HttpRequestBuilder::new("https://api.example.com")
          .method("POST")
          .header("Content-Type", "application/json")
          .body(r#"{"key":"value"}"#)
          .timeout(60)
          .build();

      Newtype 模式

      // 为第三方类型实现第三方 trait
      struct Wrapper(Vec<String>);
      
      impl std::fmt::Display for Wrapper {
          fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
              write!(f, "[{}]", self.0.join(", "))
          }
      }
      
      // 类型安全(区分不同语义的相同类型)
      struct Meters(f64);
      struct Millimeters(f64);
      struct Seconds(f64);
      
      // 不能混合使用
      // let distance = Meters(100.0) + Millimeters(50.0); // 编译错误
      
      impl Meters {
          fn to_millimeters(self) -> Millimeters {
              Millimeters(self.0 * 1000.0)
          }
      }
      
      // 邮箱类型验证
      struct Email(String);
      
      impl Email {
          fn new(s: String) -> Result<Self, &'static str> {
              if s.contains('@') {
                  Ok(Email(s))
              } else {
                  Err("Invalid email")
              }
          }
          
          fn as_str(&self) -> &str {
              &self.0
          }
      }

      Typestate 模式

      // 使用类型系统防止无效状态
      struct Draft;
      struct PendingReview;
      struct Published;
      
      struct Post<State> {
          content: String,
          _state: std::marker::PhantomData<State>,
      }
      
      impl Post<Draft> {
          fn new() -> Self {
              Post {
                  content: String::new(),
                  _state: std::marker::PhantomData,
              }
          }
          
          fn add_text(&mut self, text: &str) {
              self.content.push_str(text);
          }
          
          fn request_review(self) -> Post<PendingReview> {
              Post {
                  content: self.content,
                  _state: std::marker::PhantomData,
              }
          }
      }
      
      impl Post<PendingReview> {
          fn approve(self) -> Post<Published> {
              Post {
                  content: self.content,
                  _state: std::marker::PhantomData,
              }
          }
      }
      
      impl Post<Published> {
          fn content(&self) -> &str {
              &self.content
          }
      }
      
      fn main() {
          let mut post = Post::new();
          post.add_text("Hello world");
          
          // post.content(); // 编译错误!Draft 状态没有 content 方法
          
          let post = post.request_review();
          // post.content(); // 编译错误!PendingReview 也没有
          
          let post = post.approve();
          println!("{}", post.content());  // OK
      }

      RAII 模式

      // Rust 自动使用 RAII(资源获取即初始化)
      
      // 文件自动关闭
      use std::fs::File;
      use std::io::Write;
      
      fn write_to_file() -> std::io::Result<()> {
          let mut file = File::create("test.txt")?;
          file.write_all("Hello".as_bytes())?;
          Ok(())
      }  // file 自动关闭
      
      // 锁自动释放
      use std::sync::Mutex;
      let m = Mutex::new(0);
      {
          let mut guard = m.lock().unwrap();
          *guard += 1;
      }  // 锁自动释放
      
      // 自定义 RAII 类型
      struct Timer {
          start: std::time::Instant,
          name: String,
      }
      
      impl Timer {
          fn new(name: &str) -> Self {
              Self {
                  start: std::time::Instant::now(),
                  name: name.to_string(),
              }
          }
      }
      
      impl Drop for Timer {
          fn drop(&mut self) {
              println!("{} took {:?}", self.name, self.start.elapsed());
          }
      }
      
      fn expensive_operation() {
          let _timer = Timer::new("expensive_operation");
          // 执行操作...
      }  // 自动打印耗时

      State 模式

      // 使用 trait object 实现状态模式
      trait State {
          fn request_review(self: Box<dyn State>) -> Box<dyn State>;
          fn approve(self: Box<dyn State>) -> Box<dyn State>;
          fn content<'a>(self: &'a Box<dyn State>, post: &'a Post) -> &'a str {
              ""
          }
      }
      
      struct Draft;
      impl State for Draft {
          fn request_review(self: Box<dyn State>) -> Box<dyn State> {
              Box::new(PendingReview)
          }
          fn approve(self: Box<dyn State>) -> Box<dyn State> {
              self
          }
      }
      
      struct PendingReview;
      impl State for PendingReview {
          fn request_review(self: Box<dyn State>) -> Box<dyn State> {
              self
          }
          fn approve(self: Box<dyn State>) -> Box<dyn State> {
              Box::new(Published)
          }
      }
      
      struct Published;
      impl State for Published {
          fn request_review(self: Box<dyn State>) -> Box<dyn State> {
              self
          }
          fn approve(self: Box<dyn State>) -> Box<dyn State> {
              self
          }
          fn content<'a>(self: &'a Box<dyn State>, post: &'a Post) -> &'a str {
              &post.content
          }
      }
      
      pub struct Post {
          state: Option<Box<dyn State>>,
          content: String,
      }
      
      impl Post {
          pub fn new() -> Post {
              Post {
                  state: Some(Box::new(Draft)),
                  content: String::new(),
              }
          }
          
          pub fn add_text(&mut self, text: &str) {
              self.content.push_str(text);
          }
          
          pub fn request_review(&mut self) {
              if let Some(s) = self.state.take() {
                  self.state = Some(s.request_review());
              }
          }
          
          pub fn approve(&mut self) {
              if let Some(s) = self.state.take() {
                  self.state = Some(s.approve());
              }
          }
          
          pub fn content(&self) -> &str {
              self.state.as_ref().unwrap().content(self)
          }
      }

      25. 内存布局

      类型大小与对齐

      use std::mem;
      
      fn main() {
          // 类型大小
          println!("bool: {} bytes", mem::size_of::<bool>());       // 1
          println!("i32: {} bytes", mem::size_of::<i32>());         // 4
          println!("i64: {} bytes", mem::size_of::<i64>());         // 8
          println!("char: {} bytes", mem::size_of::<char>());       // 4
          println!("&str: {} bytes", mem::size_of::<&str>());       // 16 (指针 + 长度)
          println!("String: {} bytes", mem::size_of::<String>());   // 24 (指针 + 长度 + 容量)
          println!("Vec<T>: {} bytes", mem::size_of::<Vec<i32>>()); // 24
          println!("Option<i32>: {}", mem::size_of::<Option<i32>>()); // 8
          println!("Option<&i32>: {}", mem::size_of::<Option<&i32>>()); // 8(指针优化)
          
          // 对齐
          println!("i32 align: {}", mem::align_of::<i32>());       // 4
          println!("i64 align: {}", mem::align_of::<i64>());       // 8
          
          // 结构体布局
          struct A {
              a: u8,
              b: u32,
              c: u8,
          }
          println!("A size: {}", mem::size_of::<A>());  // 12 (有填充)
          
          // 重排字段顺序减少填充
          struct B {
              b: u32,
              a: u8,
              c: u8,
          }
          println!("B size: {}", mem::size_of::<B>());  // 8 (更紧凑)
          
          // 字段偏移
          println!("A.b offset: {}", mem::offset_of!(A, b));
          
          // 交换
          let mut x = 5;
          let mut y = 10;
          mem::swap(&mut x, &mut y);
          
          // 替换
          let old = mem::replace(&mut x, 20);
          
          // take(替换为默认值)
          let old = mem::take(&mut x);
          
          // 忘记 drop(危险!)
          // mem::forget(value);
          
          // 零初始化
          // let x: i32 = mem::zeroed();  // unsafe in modern Rust
          let x: MaybeUninit<i32> = MaybeUninit::zeroed();
      }
      
      use std::mem::MaybeUninit;
      
      // 安全使用 MaybeUninit
      let mut x = MaybeUninit::<i32>::uninit();
      x.write(42);
      let x = unsafe { x.assume_init() };

      repr 属性

      // 控制数据布局
      
      // C 兼容布局(保证与 C 结构体一致)
      #[repr(C)]
      struct CStruct {
          a: u8,
          b: u32,
          c: u8,
      }
      // 保证字段顺序不变,有对齐填充
      
      // 紧凑布局(无填充)
      #[repr(packed)]
      struct Packed {
          a: u8,
          b: u32,
          c: u8,
      }
      println!("Packed size: {}", mem::size_of::<Packed>());  // 6
      
      // 特定对齐
      #[repr(align(16))]
      struct Aligned {
          data: [u8; 4],
      }
      println!("Aligned: size={}, align={}", 
          mem::size_of::<Aligned>(),
          mem::align_of::<Aligned>());  // 16, 16
      
      // 透明包装(Newtype 不影响布局)
      #[repr(transparent)]
      struct Wrapper(i32);
      // 保证与 i32 完全相同的布局和 ABI
      
      // Rust 默认布局(可重排字段)
      #[repr(Rust)]  // 默认
      struct Default {
          a: u8,
          b: u32,
          c: u8,
      }
      
      // 枚举布局
      #[repr(C)]
      enum CEnum { A, B, C }
      
      #[repr(u8)]
      enum SmallEnum { A, B, C }  // 使用 1 字节表示
      
      // C 兼容的枚举 + 数据
      #[repr(C)]
      enum Tagged {
          A { x: i32 },
          B(f64),
      }

      指针大小

      // 不同类型引用的大小
      println!("&i32: {}", mem::size_of::<&i32>());         // 8 (64-bit)
      println!("&str: {}", mem::size_of::<&str>());         // 16 (胖指针:指针+长度)
      println!("&[i32]: {}", mem::size_of::<&[i32]>());   // 16 (胖指针)
      println!("&dyn Trait: {}", mem::size_of::<&dyn std::fmt::Display>()); // 16 (指针+vtable)
      
      // 动态大小类型 (DST)
      // str, [T], dyn Trait 都是 DST
      // 不能直接拥有,必须通过引用或 Box
      let s: &str = "hello";           // OK
      let b: Box<str> = Box::from("hello"); // OK
      // let s: str = "hello";  // 错误!

      26. 条件编译

      cfg 属性

      // 按操作系统
      #[cfg(target_os = "linux")]
      fn linux_only() { }
      
      #[cfg(target_os = "windows")]
      fn windows_only() { }
      
      #[cfg(target_os = "macos")]
      fn macos_only() { }
      
      #[cfg(any(target_os = "linux", target_os = "macos"))]
      fn unix_like() { }
      
      // 按架构
      #[cfg(target_arch = "x86_64")]
      fn x86_64_only() { }
      
      #[cfg(target_arch = "aarch64")]
      fn arm_only() { }
      
      #[cfg(target_arch = "wasm32")]
      fn wasm_only() { }
      
      // 按构建类型
      #[cfg(debug_assertions)]
      fn debug_only() { }
      
      #[cfg(not(debug_assertions))]
      fn release_only() { }
      
      // 按特性(feature)
      #[cfg(feature = "json")]
      fn json_feature() { }
      
      #[cfg(all(feature = "json", feature = "async"))]
      fn both_features() { }
      
      // 按测试
      #[cfg(test)]
      mod tests { }
      
      // 自定义条件
      #[cfg(my_custom_condition)]
      fn custom() { }
      # 编译时启用:rustc --cfg my_custom_condition
      
      // cfg! 宏(运行时检查)
      if cfg!(target_os = "linux") {
          println!("Running on Linux");
      } else {
          println!("Not Linux");
      }
      
      // 常用 target_* 配置
      // target_os: "linux", "windows", "macos", "ios", "android", "freebsd"
      // target_arch: "x86", "x86_64", "arm", "aarch64", "wasm32", "riscv64"
      // target_family: "unix", "windows"
      // target_env: "gnu", "msvc", "musl"
      // target_endian: "little", "big"
      // target_pointer_width: "32", "64"

      Feature Flags

      # Cargo.toml
      [features]
      default = ["std"]
      std = []
      json = ["serde", "serde_json"]
      async = ["tokio"]
      full = ["std", "json", "async"]
      
      # 可选依赖作为 feature
      [dependencies]
      serde = { version = "1.0", optional = true }
      serde_json = { version = "1.0", optional = true }
      tokio = { version = "1", optional = true }
      
      # 在代码中使用
      #[cfg(feature = "json")]
      use serde::{Serialize, Deserialize};
      
      #[cfg(feature = "json")]
      pub fn to_json<T: Serialize>(value: &T) -> String {
          serde_json::to_string(value).unwrap()
      }
      
      # 构建时启用 features
      cargo build --features json
      cargo build --features "json async"
      cargo build --no-default-features
      cargo build --all-features

      Build Scripts

      # build.rs - 在编译前运行
      use std::env;
      use std::path::Path;
      
      fn main() {
          // 告诉 cargo 重新运行条件
          println!("cargo:rerun-if-changed=build.rs");
          println!("cargo:rerun-if-changed=src/data.txt");
          
          // 设置环境变量
          println!("cargo:rustc-env=BUILD_TIME={}", chrono::Utc::now());
          
          // 链接库
          println!("cargo:rustc-link-lib=sqlite3");
          println!("cargo:rustc-link-search=native=/usr/lib");
          
          // 条件编译标志
          println!("cargo:rustc-cfg=has_openssl");
          
          # 生成代码
          let out_dir = env::var("OUT_DIR").unwrap();
          let dest_path = Path::new(&out_dir).join("generated.rs");
          std::fs::write(dest_path, "pub const VERSION: &str = \"1.0.0\";").unwrap();
          
          # 编译 C/C++ 代码
          # cc::Build::new()
          #     .file("src/native.c")
          #     .compile("native");
      }
      
      # 使用生成的代码
      include!(concat!(env!("OUT_DIR"), "/generated.rs"));

      27. 最佳实践

      代码风格与规范

      // 使用 rustfmt 统一风格
      // 使用 clippy 检查代码质量
      
      // 变量命名:snake_case
      let user_name = "Alice";
      let max_retry_count = 3;
      
      // 类型命名:PascalCase
      struct UserProfile { }
      enum ConnectionState { }
      
      // 函数命名:snake_case
      fn calculate_total() { }
      fn is_valid() -> bool { }
      
      // 常量:SCREAMING_SNAKE_CASE
      const MAX_CONNECTIONS: usize = 100;
      const DEFAULT_TIMEOUT: u64 = 30;
      
      // 生命周期:单个小写字母
      fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { }
      
      // Trait 命名:PascalCase
      trait Drawable { }
      trait Iterator { }

      错误处理最佳实践

      // 1. 库代码:返回具体的 Result
      pub fn parse_config(content: &str) -> Result<Config, ConfigError> {
          // ...
      }
      
      // 2. 应用代码:使用 anyhow
      use anyhow::{Result, Context};
      fn main() -> Result<()> {
          let config = parse_config(&content)
              .context("failed to parse config")?;
          Ok(())
      }
      
      // 3. 避免 unwrap 在生产代码
      // 使用 expect 提供信息
      let value = opt.expect("配置项 'foo' 必须存在");
      
      // 4. 提供上下文
      let file = File::open(path)
          .with_context(|| format!("failed to open {}", path.display()))?;

      性能优化建议

      • 优先使用迭代器而非手写循环(编译器可更好优化)
      • 避免不必要的 clone(),使用引用或 Cow
      • 使用 String::with_capacity() 预分配
      • 使用 Vec::with_capacity() 避免重新分配
      • 使用 rayon 进行并行计算
      • Profile 后再优化,避免过早优化
      • 使用 Box<[T]>Vec 处理动态大小的集合
      • 使用 smallvec crate 避免小集合的堆分配
      • 使用 hashbrownahash 替代默认 HashMap(更快)
      • 使用 parking_lot 替代标准 Mutex(更快)
      • 使用 once_cell / LazyLock 替代 lazy_static
      • 避免在热路径上使用动态分发(dyn Trait
      • 使用 #[inline] 内联关键函数
      • 使用 likely() / unlikely() 优化分支预测
      use std::hint::{unlikely, black_box};
      
      fn process(x: i32) -> i32 {
          if unlikely(x < 0) {
              // 很少发生的错误路径
              return -1;
          }
          // 常见路径
          x * 2
      }

      项目结构建议

      my_project/
      ├── Cargo.toml
      ├── Cargo.lock
      ├── README.md
      ├── LICENSE
      ├── CHANGELOG.md
      ├── .gitignore
      ├── src/
      │   ├── main.rs           # 二进制入口(尽量薄)
      │   ├── lib.rs             # 库入口(导出公共 API)
      │   ├── config/
      │   │   ├── mod.rs
      │   │   └── settings.rs
      │   ├── models/
      │   │   ├── mod.rs
      │   │   ├── user.rs
      │   │   └── order.rs
      │   ├── services/
      │   │   ├── mod.rs
      │   │   └── auth.rs
      │   ├── errors.rs          # 统一错误定义
      │   ├── utils.rs
      │   └── prelude.rs         # 常用导入
      ├── tests/
      │   ├── common/
      │   │   └── mod.rs
      │   └── integration_tests.rs
      ├── benches/
      │   └── performance.rs
      ├── examples/
      │   └── basic_usage.rs
      ├── migrations/
      │   └── 001_create_users.sql
      └── docs/
          └── architecture.md

      常用工具链

      工具用途
      rustupRust 版本管理
      cargo构建和包管理
      rustfmt代码格式化
      clippy代码静态分析
      rust-analyzerIDE 支持(VSCode 推荐)
      cargo-watch文件监控自动重新编译
      cargo-expand展开宏查看生成代码
      cargo-flamegraph性能分析火焰图
      cargo-audit检查依赖的安全漏洞
      cargo-deny检查许可证和依赖
      cargo-nextest更快的测试运行器
      cargo-tarpaulin代码覆盖率
      cargo-edit命令行编辑依赖

      学习资源推荐

      官方资源:

      • 《The Rust Programming Language》(TRPL) - 官方入门书

      • 《Rust by Example》 - 通过示例学习

      • 《Rustlings》 - 小练习集

      • 《Rust Reference》 - 语言参考

      • 《The Cargo Book》 - Cargo 手册

      • 《The Rustonomicon》 - Unsafe Rust 指南

      • crates.io - 包仓库

      • docs.rs - 文档

      进阶书籍:

      • 《Programming Rust》(O'Reilly) - 深入系统编程

      • 《Rust for Rustaceans》 - 中级到高级

      • 《Asynchronous Programming in Rust》 - 异步专题

      • 《Zero To Production In Rust》 - 后端开发实战

      实践项目:

      • 实现一个 HTTP 服务器

      • 实现一个 JSON 解析器

      • 实现一个解释器

      • 重写一个 Unix 工具(ls, grep, cat)

      • 实现一个数据库存储引擎

      Rust 2024 Edition 新特性

      # 使用 Rust 2024 Edition
      [package]
      edition = "2024"
      
      // 主要变化:
      // 1. 更严格的 unsafe extern 块
      unsafe extern "C" {
          fn c_function();
      }
      
      // 2. RPITIT(Return Position Impl Trait In Traits)
      trait Iterator {
          fn filter<P>(self, predicate: P) -> impl Iterator<Item = Self::Item>;
      }
      
      // 3. 更严格的 never type 行为
      // 4. Prelude 变化
      // 5. 生命周期捕获规则改进
      
      # 迁移工具
      cargo fix --edition

      没有找到相关内容

← 返回IT 技术 yicool 百科 · Rust 语言教程 - 完整指南(增强版)

评论 0