11
闭包与迭代器:Rust 的两大高阶武器
Closures · Iterators
闭包是"能抓环境的匿名函数"(对标 lambda);迭代器是"惰性、零成本的遍历"。这俩是 Rust 写函数式风格代码的主力。
闭包 Closure
fn main() {
// 闭包语法 |参数| 体;类型自动推断,还能抓外面的变量
let add_one = |x: i32| x + 1;
println!("{}", add_one(5));
// 捕获环境:闭包借用了外面的 factor
let factor = 10;
let multiply = |x: i32| x * factor;
println!("{}", multiply(3));
// move 闭包:强制把环境所有权搬进来(线程里常用)
let owned = String::from("搬走");
let take = move || println!("{}", owned);
take();
}
$ cargo run
6
30
搬走
| trait | 捕获方式 |
|---|---|
| Fn | 不可变借用环境,可多次调用 |
| FnMut | 可变借用环境,能改外面的变量 |
| FnOnce | 消费环境所有权,最多调一次 |
迭代器 Iterator:惰性、零成本
fn main() {
let nums = vec![1, 2, 3, 4, 5];
// 适配器:map/filter,都是惰性的,不消费就不干活
let sum: i32 = nums
.iter() // 不可变引用迭代
.map(|x| x * 2) // 每个翻倍
.filter(|x| *x > 5) // 留下大于 5 的
.sum(); // 消费器:求和,这时才真正跑
println!("结果 {}", sum); // (2*4)+(2*5)=18
// collect 指定目标类型
let doubled: Vec<i32> = nums.iter().map(|&x| x).collect();
println!("{:?}", doubled);
}
$ cargo run
结果 18
[1, 2, 3, 4, 5]
- 适配器(中间操作):
map / filter / flat_map / zip / enumerate / skip / take / rev / chain。 - 消费器(终点操作):
collect / sum / count / find / max / any / all / for_each / fold。 - 三种迭代:
iter()借引用、iter_mut()借可变引用、into_iter()拿走所有权。
论迭代器为什么和手写循环一样快
Rust 编译器把迭代器链内联展开成跟手写 for 循环一模一样的机器码,没有运行时开销。这就是"零成本抽象"——你写得优雅,跑起来跟 C 一样快。