在 Rust 中,迭代器是一个**惰性(Lazy)**的对象,它负责产生一系列值。与立即计算所有结果的集合不同,迭代器只有在被请求时(调用 .next())才会生成下一个值。
1、核心定义
rust
pub trait Iterator {
type Item; // 迭代产生的元素类型
// 核心方法:返回下一个元素
// Some(item): 还有下一个元素
// None: 迭代结束
fn next(&mut self) -> Option<Self::Item>;
// ... 其他许多默认实现的方法如 map, filter, collect 等
}
- 单一职责 :
next()是唯一必须实现的方法。其他所有功能(如map,filter)都是基于next()构建的默认方法。 - 状态性 :迭代器内部维护状态(当前遍历到了哪里),因此调用
next()需要&mut self a。 - 一次性消费 :大多数迭代器只能遍历一次。一旦
next()返回None,迭代器通常就"耗尽"了。
2、创建迭代器的三种方式
Rust 集合(如 Vec, HashMap, 数组等)通常提供三种方法来创建迭代器,对应不同的所有权语义:
| 方法 | 签名示例 | 产出类型 (Item) |
所有权行为 | 适用场景 |
|---|---|---|---|---|
**.iter()** |
vec.iter() |
&T (不可变引用) |
借用原始集合 | 只读遍历,保留集合所有权 |
**.iter_mut()** |
vec.iter_mut() |
&mut T (可变引用) |
可变借用原始集合 | 需要修改集合中的元素 |
**.into_iter()** |
vec.into_iter() |
T (拥有所有权) |
移动原始集合 | 消耗集合,获取元素所有权 |
3、迭代适配器
适配器是 Iterator trait 提供的默认方法,它们接收一个迭代器,经过转换后返回一个新的迭代器。
核心特性:惰性求值(Laziness)
调用适配器(如 .map(), .filter())不会立即执行任何计算 。它们只是构建了处理逻辑的结构。只有当调用消费方法 (如 .collect(), .sum(), .next(), .for_each())时,整个链条才会真正执行。
(1)转换类
-
map(f):对每个元素应用函数f。rustlet val = (1..6).map(|x| x * 3).collect::<Vec<_>>(); // [3, 6, 9, 12, 15] -
enumerate():将索引和元素配对,产出(usize,Item)。rustlet val = (1..6).enumerate().collect::<Vec<_>>(); // [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)] -
zip(other):将两个迭代器压缩成一个,产出元组(Item1,Item2)。长度以较短者为准。rustlet val = (1..6).zip((15..30)).collect::<Vec<_>>(); // [(1, 15), (2, 16), (3, 17), (4, 18), (5, 19)]
(2)过滤类
-
filter(predicate):返回闭包条件为true的元素rustlet val = (1..6).filter(|x| x % 2 == 0).collect::<Vec<_>>(); // [2, 4] -
take(n):前n个元素。rustlet val = (1..10).take(3).collect::<Vec<_>>(); // [1, 2, 3] -
skip(n):跳过前n个元素。rustlet val = (1..10).skip(3).collect::<Vec<_>>(); // [4, 5, 6, 7, 8, 9]
(3)扁平化类
-
flat_map(f):闭包返回一个迭代器,然后将所有子迭代器"扁平"连接成一个流。常用于处理Option或嵌套集合。rust// 处理嵌套集合 let lists = vec![vec![1, 2], vec![3, 4]]; let val: Vec<i32> = lists.into_iter().flat_map(|list| list.into_iter()).collect(); // [1, 2, 3, 4]rust// 处理 Option let strings = vec!["1", "hello", "3", "world", "5"]; let numbers: Vec<i32> = strings.iter() .flat_map(|s| s.parse::<i32>().ok()) .collect(); // [1, 3, 5]- **流程解析:**
"1"->parse->Ok(1)->.ok()->Some(1)->flat_map产出1"hello"->parse->Err(...)->.ok()->None->flat_map跳过"3"->parse->Ok(3)->.ok()->Some(3)->flat_map产出3
...以此类推。
- 如果你的闭包明确返回
Option,请优先使用 **filter_map**,用法相同。
- **流程解析:**
(4)消费方法
-
collect::<B>():迭代器转为集合。 -
sum():求和。rustlet val: i32 = (1..10).sum(); // 45 -
product():乘积。rustlet val: i32 = (1..10).product(); // 362880 -
fold(init, f):向左折叠,累个计算rustlet val = (1..10).fold(0, |a, x| a + x); // 求和 1+2+..9 let val = (1..10).fold(0, |a, x| a * x); // 乘积 1*2*..9 let val = (1..10).fold(0, |a, x| a - x); // 连减 1-2-..9 -
find(predicate):返回第一个满足条件的元素引用(Option<&Item>),找到后立即停止。rustlet val = (1..10).find(|&x| x % 3 == 0); // Some(3) -
any():是否有任何元素满足条件,支持短路求值。rustlet val = (1..10).any(|x| x % 3 == 0); // true -
all():是否有所有元素满足条件,支持短路求值。rustlet val = (1..10).all(|x| x % 3 == 0); // false
4、自定义迭代器实现 Iterator
rust
struct MyIter { // 自定义迭代器
val: u32, // 初始值的前一个值
max: u32, // 最大值
}
impl MyIter {
fn new(max: u32) -> MyIter { // 根据最大值初始化迭代器
MyIter { val: 0, max }
}
}
impl Iterator for MyIter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.val < self.max {
self.val += 1; // 下一个值 = 上一个值加一
Some(self.val) // 返回当前值
} else {
None // 为None时,结束迭代
}
}
}
fn main() {
let val = MyIter::new(5).collect::<Vec<_>>();
println!("{:?}", val); // [1, 2, 3, 4, 5]
}
5、自定义类型实现 IntoIterator、Iterator
- **
IntoIterator(工厂接口)**:定义了一个类型如何被"加工"成迭代器。生成迭代器 Iterator(产品行为):定义了迭代器本身的行为(即next()方法)。产生值
rust
// 自定义类型
#[derive(Debug)]
struct MyList(Vec<u32>);
impl IntoIterator for MyList { // 实现 IntoIterator,转为迭代器
type Item = u32;
type IntoIter = MyIter; // 迭代器类型为自定义迭代器
fn into_iter(self) -> Self::IntoIter {
MyIter {
data: self.0, // 将Vec所有权移动到迭代器中
index: 0, // 初始化索引
}
}
}
// 自定义迭代器
struct MyIter {
data: Vec<u32>, // 迭代器的值
index: usize, // 索引位置
}
impl Iterator for MyIter { // 实现迭代器
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.index < self.data.len() {
let item = self.data[self.index]; // 当前索引的值
self.index += 1; // 下一个索引
Some(item) // 返回当前值
} else {
None // None时,结束迭代
}
}
}
fn main() {
let list = MyList(vec![1, 2, 3]);
println!("{:?}", list); // MyList([1, 2, 3])
}