当前位置: 首页 > news >正文

学习笔记十四——一文看懂 Rust 迭代器

🌀 一文看懂 Rust 迭代器


📚 目录导航

  1. 什么是迭代器?为什么 Rust 到处都在用它?
  2. Rust 迭代器的底层逻辑是什么?
  3. 适配器 vs 消费者:谁是主角?
  4. 常见适配器:加工数据的全能工厂
  5. 常见消费者:迭代器的“吃货家族”
  6. Rust 如何保证高性能?为什么懒执行这么厉害?
  7. ✅ 高阶技巧通俗讲透:by_ref、提前消费
  8. 🧠 小白也能写的自定义迭代器:从逻辑到实战
  9. 总结 + 常见场景整理

1️⃣ 什么是迭代器?为什么 Rust 到处都在用它?

一句话:迭代器就是一个可以“一个个吐出值”的东西。

再通俗点:它像一个工人,负责“从集合里拿出元素”:

let v = vec![1, 2, 3];
let mut it = v.iter();println!("{:?}", it.next()); // Some(1)
println!("{:?}", it.next()); // Some(2)
println!("{:?}", it.next()); // Some(3)
println!("{:?}", it.next()); // None

每次调用 .next(),它就给你一个 Option<T> 类型的值:

  • 有值:Some(x)
  • 没值了:None

2️⃣ Rust 迭代器的底层逻辑是什么?

Rust 用 trait Iterator 抽象了所有“可以被一项一项访问”的数据结构:

pub trait Iterator {type Item;fn next(&mut self) -> Option<Self::Item>;
}

你只需要实现 next(),它会一项一项地返回数据。每个适配器、消费者,都是围绕 next() 构建的!


3️⃣ 适配器 vs 消费者:谁才是主角?

对比适配器(Adapter)消费者(Consumer)
功能加工、变换、组合数据真正“把数据用掉”
是否懒执行✅ 是❌ 一调用就开始运行
是否返回迭代器✅ 返回新的迭代器❌ 返回值(Vec、i32、bool)
示例.map() .filter() .take().collect() .sum() .find()

类比思路 🧠:

适配器像工厂流水线,把原料(数据)加工好,
消费者像物流运输,把结果打包送到你手里。


4️⃣ 常见适配器:加工数据的全能工厂

名称用法示例通俗场景
map()加工每个元素.map(|x| x + 1)全部加 1、转大写等
filter()筛选元素.filter(|x| *x > 3)只要大于 3 的
take(n)只取前 n 个.take(2)分页、限流
skip(n)跳过前 n 个.skip(2)跳过表头等
enumerate()带索引.enumerate()打印编号
rev()倒序.rev()倒着打印
chain()拼接a.chain(b)合并多个集合

🌰 示例:

let result: Vec<_> = (1..=5).filter(|x| x % 2 == 1).map(|x| x * 10).collect();println!("{:?}", result); // [10, 30, 50]

5️⃣ 常见消费者:迭代器的“吃货家族”

名称用法示例作用
collect()收集为 Vec、HashMap 等.collect::<Vec<_>>()最常用
for_each()遍历做事.for_each(|x| println!("{}", x))替代 for 循环
sum()求和.sum::<i32>()累加数字
product()求积.product::<i32>()全部相乘
count()个数.count()数据量统计
find()找一个满足条件的值.find(|x| *x == 3)搜索场景
any()有一个满足条件?.any(|x| x > 5)判断存在性
all()全部满足条件?.all(|x| x > 0)校验条件

6️⃣ Rust 如何保证高性能?为什么懒执行这么厉害?

Rust 的迭代器用的是“懒加载”思想:

💤 什么叫懒?

不会一开始就执行所有 .map().filter(),而是只有你用 collect() 等消费器,才“触发”处理流程。

let iter = (1..=3).map(|x| {println!("处理 {}", x);x + 1
}); // 什么都不会打印let v: Vec<_> = iter.collect(); // 现在才开始打印

7️⃣ ✅ 高阶技巧通俗讲透

by_ref() 是啥?

你拿一个可变引用传递给某个适配器,就能保留迭代器状态。

🌰 示例:我们只想用这个迭代器的一部分

let mut it = vec![1, 2, 3, 4, 5].iter();let a: Vec<_> = it.by_ref().take(2).collect(); // 拿前两个
let b: Vec<_> = it.collect(); // 剩下的还可以继续用println!("{:?} {:?}", a, b); // [1, 2] [3, 4, 5]

8️⃣ 🧠 小白也能写的自定义迭代器:从逻辑到实战

你只要记住两点:

✅ 一个迭代器必须:

  1. 有个结构体保存状态(比如当前数)
  2. 实现 Iterator trait,提供 next() 方法

🌰 例子:自己写一个“从 1 数到 5”的迭代器

struct CountToFive {count: usize,
}impl Iterator for CountToFive {type Item = usize;fn next(&mut self) -> Option<Self::Item> {if self.count < 5 {self.count += 1;Some(self.count)} else {None}}
}
✅ 用法:
fn main() {let counter = CountToFive { count: 0 };for n in counter {println!("{}", n); // 输出 1 到 5}
}

📌 模板套路(记住就能写):

struct MyIter { 状态字段 }impl Iterator for MyIter {type Item = 返回的类型;fn next(&mut self) -> Option<Self::Item> {// 判断是否结束 + 返回 Some(...) or None}
}

✅ 什么场景该自己写?

  • 你要从 1 到 100,每次跳 7(非普通序列)
  • 你要包装异步、分页、网络流
  • 想把某个结构变成“可遍历”的对象

9️⃣ 总结:迭代器能做什么?为啥这么香?

优点表现
✅ 安全没有手动索引越界的烦恼
✅ 高性能零成本抽象,懒执行,自动内联
✅ 表达力强写起来非常流畅,读起来像“数据管道”
✅ 可组合map + filter + take 无限组合
✅ 可扩展你可以实现自己的迭代器,复用逻辑

🚀 常见实战场景:

  • 遍历 Vec、HashMap、文件行
  • 过滤无效数据
  • 求和 / 聚合统计
  • 实现分页 / 分批处理
  • 管道式业务数据处理(流式处理)

相关文章:

  • SIMULIA-Abaqus有限元分析软件针对汽车行业的解决方案
  • 通信算法之266: 无人机信号带宽计算
  • 软件需求说明书模板
  • 遨游防爆手机:构筑煤矿安全通讯的数字护盾
  • 【Java学习笔记】运算符
  • 【星海随笔】Python-JSON数据的处理
  • C++中类拷贝、赋值与销毁详解
  • FairyGUI图标文字合批失败的原因
  • HarmonyOS 5.0应用开发——五子棋游戏(鸿蒙版)开发
  • 【双指针】专题:LeetCode 611题解——有效三角形的个数
  • OpenCV 图形API(39)图像滤波----同时计算图像在 X 和 Y 方向上的一阶导数函数SobelXY()
  • 企业采购平台搭建指南:从流程重构到生态协同的数字化转型路径
  • 【学习笔记】Taming 3DGS泛读
  • 【android bluetooth 协议分析 02】【bluetooth hal 层详解 1】【uart 介绍】
  • 【病毒分析】定向财务的钓鱼木马分析
  • 过滤器及拦截器
  • 一文掌握RK3568开发板Android13挂载Windows共享目录
  • C++Cherno 学习笔记day21 [86]-[90] 持续集成、静态分析、参数计算顺序、移动语义、stdmove与移动赋值操作符
  • 蓝桥杯 8. 分巧克力
  • oracle判断同表同条件查出两条数据,根据长短判断差异
  • 哪个市文化和旅游网站做的好/北京seo编辑
  • 怎么利用百度云盘做网站/关键词排名优化公司哪家好
  • 风铃做的网站能否推广/成都网络营销策划
  • 怎么做一个属于自己的网页/seo网络优化平台
  • 电子商务网站建设的意义是什么/网站为什么要seo?
  • 没有网站做cpa怎么赚钱/学电子商务出来能干嘛