Rust 迭代器与闭包实战:用 filter/map/fold 替代手写循环
test12026-09-263 次阅读
迭代器的惰性求值
Rust 的迭代器是惰性的:iter()、filter、map 这类适配器只是描述计算过程,不立即执行,直到遇到 collect、sum、fold 等消费型方法才真正跑数据。这让你可以把多个变换串成一条流水线,且零额外分配。
常用适配器
let nums = vec![1, 2, 3, 4, 5, 6];
let even_sum: i32 = nums
.iter()
.filter(|&&x| x % 2 == 0) // 保留偶数
.map(|&x| x * x) // 平方
.sum(); // 消费:1+4+16+36 = 57
println!("{}", even_sum);
相比手写 for 循环,链式写法没有中间数组,filter 和 map 通常还能被编译器内联到接近手写性能。
用 fold 实现自定义聚合
let words = ["a", "bb", "ccc"];
let total_len = words.iter().fold(0, |acc, w| acc + w.len());
// 等价于从 0 开始,对每个元素累加长度
fold 的初值类型不要求和元素类型相同,因此可以做"边走边构造一个 HashMap"这类转换,比 for 循环更声明式。
自定义迭代器
给自己的类型实现 Iterator trait,就能直接用 for 遍历或接上所有适配器。
struct Counter { n: u32, max: u32 }
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<u32> {
self.n += 1;
if self.n <= self.max { Some(self.n) } else { None }
}
}
for i in Counter { n: 0, max: 3 } {
println!("{}", i); // 1 2 3
}
闭包作为参数的三种 trait
把闭包传给函数时,按捕获方式选择 Fn、FnMut、FnOnce,决定能否多次调用或是否拿走所有权。
fn repeat(mut f: F, times: usize) {
for _ in 0..times { f(); }
}
let mut count = 0;
repeat(|| { count += 1; }, 5);
println!("{}", count); // 5
- 只读捕获用
Fn,要修改外部状态用FnMut,要消费掉捕获值用FnOnce。 - 优先用迭代器而非索引循环,既安全又易于并行化(
par_iter)。
T
test1
文章作者
迭代器的惰性求值 Rust 的迭代器是惰性的:iter()、filter、map 这类适配器只是描述计算过程,不立即执...
- 分类
- 技术
- 发布时间
- 2026-09-26
- 字数
- 约 1271 字
- 阅读
- 3 次
