Rust - 迭代器
一、迭代器
1. 什么是迭代器
- 迭代器模式:对一系列项执行某些任务
- 迭代器负责:
- 遍历每个项
- 确定序列(遍历)何时完成
- Rust的迭代器:
- 懒惰的:除非调用消费迭代器的方法,否则迭代器本身没有任何效果
2. 创建一个迭代器
fn main() {
// 迭代器
let v1 = vec![1,2,3];
// 把它变成迭代器
let v1_iter = v1.iter();
// 遍历迭代器
for i in v1_iter{
println!("{}",i);
}
}
3、Iterator trait
- 所有迭代器都实现了Iterator trait
- Iterator trait定义于标准库
- pub trait Iterator{
type Item;
fn newt(&mut self)->Option
} - type Item 和Self::Item定义了于此该Trait关联的类型
- 实现Iterator trait需要你定义一个Item类型,它用于next方法的返回类型(迭代器的放回类型)
- pub trait Iterator{
- Iterator trait仅要求实现一个方法:next
- next:
- 每次返回迭代器中的一项
- 返回结果包裹在Some里
- 迭代结束,返回None
- 可直接在迭代器上调用next方法
#[cfg(test)] mod tests{ #[test] fn iterator_demonstration(){ let v1 = vec![1,2,3]; let mut v1_iter = v1.iter(); assert_eq!(v1_iter.next(),Some(&1)); assert_eq!(v1_iter.next(),Some(&2)); assert_eq!(v1_iter.next(),Some(&3)); } }
4、几个迭代方法
- iter方法:在不可变引用上创建迭代器
- into_iter方法:创建的迭代器会获得所有权
- iter_mut方法:迭代可变的引用
5、消耗迭代器的方法
- 在标准库中,Iterator tarit有一些带默认实现的方法
- 其中有一些方法会调用next方法
- 实现Iterator tarit时必须实现next方法的原因之一
- 调用next的方法叫做"消耗型适配器"
- 因为调用它们会把迭代器消耗尽
- 例如:SUM()方法就会耗尽迭代器
- 该方法会取得迭代器的所有权
- 通过反复调用next,遍历所有元素
- 每次迭代,把当前元素添加到一个总和里,迭代结束,返回总和
#[test] fn iterator_sum(){ let v2 = vec![1,2,3]; let v2_iter = v2.iter(); let total:i32 = v2_iter.sum(); assert_eq!(total,6); }
6、产生其他迭代器的方法
- 定义在Iterator tarit上的另外一些方法叫做"迭代器适配器"
- 把迭代器转换为不同种类的迭代器
- 可以通过链式调用使用多个迭代器适配器来执行复杂的操作,这种调用可读性较高
- 例如:map
- 接受一个闭包,闭包作用于每个元素
- 产生一个新的迭代器
- collect方法:就是一个消耗型适配器方法,把结果都收集到一个集合类型中
#[test] fn iterator_sums(){ let v3 = vec![1,2,3]; // 因为默认是懒惰的,如果不加collect,就不会出结果 let v3_iter:Vec<_> = v3.iter().map(|x|x+1).collect(); assert_eq!(v3_iter,vec![2,3,4]); }
7、使用闭包捕获环境
- filter方法
- 接受一个闭包
- 这个闭包在遍历迭代器的每个元素时,返回bool类型
- 如果闭包返回true:当前元素将会包含在filter产生的迭代器中
- 如果闭包返回false:当前元素将不会包含在filter产生的迭代器中
推荐阅读: