Z
ZHANK
进阶技巧

闭包与迭代器

Fn/FnOnce/FnMut trait、闭包捕获环境、迭代器适配器 map/filter

闭包与迭代器

Rust 闭包自动推导参数和返回类型,实现 Fn/FnMut/FnOnce trait。迭代器零成本抽象——编译后和手写循环一样快。

学完本章你将: 掌握 Fn/FnOnce/FnMut、闭包捕获、迭代器适配器。


闭包

rust
fn main() {
    // 闭包——自动推导类型
    let add = |a: i32, b: i32| -> i32 { a + b };
    let square = |x| x * x;  // 参数和返回类型都可省略

    println!("{}", add(3, 5));     // 8
    println!("{}", square(4));     // 16

    // 捕获环境变量
    let factor = 10;
    let multiply = |x| x * factor;  // 捕获 &factor
    println!("{}", multiply(5));    // 50
}

Fn / FnMut / FnOnce

rust
// FnOnce —— 获取所有权(只能调用一次)
let s = String::from("hello");
let consume = || drop(s);  // 获取 s 的所有权
consume();
// consume();  // ❌ 不能再次调用

// FnMut —— 可变借用(可修改捕获的变量)
let mut count = 0;
let mut inc = || { count += 1; count };
println!("{}", inc());  // 1
println!("{}", inc());  // 2

// Fn —— 不可变借用(可多次调用)
let name = String::from("Rust");
let greet = || println!("Hello, {}", name);
greet();
greet();

迭代器适配器

rust
let nums = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 链式调用——迭代器是惰性的
let result: Vec<i32> = nums.iter()
    .filter(|&&x| x % 2 == 0)     // 过滤偶数
    .map(|&x| x * x)               // 平方
    .take(3)                        // 取前 3 个
    .collect();                     // 收集为 Vec

println!("{:?}", result);  // [4, 16, 36]

// 常用适配器
nums.iter().skip(3)       // 跳过
nums.iter().enumerate()   // 带索引
nums.iter().rev()         // 反转
nums.iter().sum::<i32>()  // 求和