Rust 中的迭代器 (Iterator) 是一个强大灵活的工具,将数据和处理过程分离,可以简化对数组、Map、链表等的访问操作。实现时,采用惰性求值,有效降低非必要的性能开销。
简介
迭代器通过实现 std::iter::Iterator
特征定义,最基础的通过 next()
逐一返回下个元素,直到 None
结束。
pub trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}
使用简介
如下以 Vector
为例介绍使用方法,很多其它集合也可以使用。
fn main() {
let mut v0 = vec![1, 2, 3];
// 创建借用迭代器,后面可以多次调用
for v in v0.iter() {
println!("{}", v);
}
let mut iter = v0.iter();
while let Some(v) = iter.next() {
println!("{}", v);
}
// 可变借用迭代器,可以修改内部成员
for i in v0.iter_mut() {
*i *= 2;
}
println!("{:?}", v0); // [2, 4, 6]
// 所有权迭代器,后面不能再调用
let mut iter = v0.into_iter();
while let Some(v) = iter.next() {
println!("{}", v);
}
}
常用方法
使用最多的还是函数式编程方法,
fn main() {
let v1: Vec<i32> = v0.iter().map(|x| x * x).collect();
println!("{:?}", v1); // [1, 4, 9]
let v1: Vec<&i32> = v0.iter().filter(|x| *x % 2 == 0).collect();
println!("{:?}", v1); // [2]
let v1: i32 = v0.iter().fold(0, |a, x| a + x);
println!("{:?}", v1); // 6
let v2 = vec![4, 5, 6];
let v1: Vec<i32> = v0.iter().chain(v2.iter()).copied().collect();
println!("{:?}", v1); // [1, 2, 3, 4, 5, 6]
let v2 = vec!["Andy", "Tom", "Bob"];
for (key, val) in v2.iter().zip(v0.iter()) {
println!("{}={}", key, val); // Andy=1 Tome=2 Bob=3
}
}
如下对常用的函数简单说明:
map
转换数据,通过闭包处理其中每个元素,然后返回新的含结果迭代器,原迭代器不变。filter
过滤数据,同样通过闭包处理每个元素,当闭包返回true
时对应元素包含在新的迭代器中。fold
聚合数据,通过初始值和闭包循环调用每个元素,最终生成单一最终值。chain
用于将两个迭代器链接在一起,会先遍历第一然后第二个。zip
将两个迭代器同时进行遍历处理,每次同时返回对应的元素。copied()
复制所有的元素,可以将&T
转换为T
类型,其作用与map(|&x| x)
相同。
注意,闭包调用时,某些函数使用的是引用。