← [ BACK_TO_NOTES ]

Rust 迭代器

Iterator trait、惰性适配器、消费者与 collect;零成本抽象下的集合处理主路径。

#concept #growing #dev #rust

[!info] related notes

Rust 迭代器

这个概念为什么出现

处理集合的标准方式不应是满屏下标。
Iterator 把“如何产生下一个元素”抽象出来,适配器(map/filter)惰性组合,消费者(collect/sum)触发执行。

[!abstract] 一句话理解 实现 Iterator 的类型可产生一系列 Item;适配器惰性变换流;collect 等消费者强制求值。

最小可运行示例

场景:订单金额——筛选大额并计算税费后总额

财务任务:金额列表中筛 >=100 的订单,加 10% 税后求和。

// 业务意图:筛选大额订单并计税汇总。
// 教学点:iter/map/filter/sum 惰性链;闭包捕获。

fn main() {
    let amounts = [50_u32, 120, 80, 200];
    let taxed_total: u64 = amounts
        .iter()
        .copied()
        .filter(|a| *a >= 100)
        .map(|a| u64::from(a) + u64::from(a) / 10) // 每笔按整数单位向下取整
        .sum();
    println!("taxed_total={taxed_total}");
}

建议运行:cargo run

期望输出:

taxed_total=352

(120→132,200→220,和 352)。此处四个 u32 输入用 u64 汇总足够;任意长度的金额流仍需检查总和溢出,并明确按笔还是汇总后舍入。

结合场景再看三个关注点

  1. 中间步骤不建临时 Vec(直到需要)
  2. 可读的数据管道
  3. 类型由 sum/collect 注解引导

核心概念与准确模型

trait Iterator {
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
}
  • iter:&T
  • iter_mut:&mut T
  • 拥有的 Vec 上 into_iter() 产出 T;&Vec<T> 上则产出 &T,IntoIterator 不统一等于移动元素

map/filter 的闭包随消费执行,构造适配器不会遍历全部输入;但调用前的参数表达式仍会求值。for、next、sum、find 等都可消费,不必先 collect。

Iterator 本身不保证返回 None 后永远结束,需此保证可用 fuse / FusedIterator。collect::<Result<Vec<_>, E>>() 在首个 Err 短路,后续元素不再处理;此前副作用不会回滚。

设计动机

  • 统一遍历协议
  • 优化友好的惰性融合(实现可优化)
  • 函数式表达力 + 系统性能

边界与误区

  • 忘了消费者导致“没执行”
  • 在迭代同一集合时修改结构需遵守借用
  • 无限迭代器要 take

[!warning] 常见误区:以为 map 立刻生成新 Vec 默认惰性;collect 才物化。

工程实践

  1. 优先迭代器链表达变换
  2. 热路径看汇编/基准,不盲信
  3. 复杂链抽函数命名
  4. 错误用 collect::<Result<Vec<_>,_>>() 模式

本节总结

  • Iterator + 适配器 + 消费者
  • 惰性默认
  • 与闭包深度结合

自测题

  1. iter 与 into_iter 区别?
  2. 为何需要 collect 类型注解?
参考答案
  1. Vec 的 iter 借用元素;IntoIterator 的产出取决于接收者是拥有值还是引用。
  2. 可收集进多种目标类型,编译器需知道目标。

延伸阅读与资料来源

资料类型支撑内容
The Book — Iterators官方书迭代器
std::iter::Iterator标准库API
创建于 2026/7/15 更新于 2026/10/7
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本