什么是迭代器

  • 迭代器模式: 对一系列项目执行某些任务
  • 迭代器负责:
    • 遍历每个项
    • 确定序列(遍历)何时完成

      Rust的迭代器是懒惰的:除非调用消费迭代器的方法,否则迭代器本身没有任何效果

  1. fn main(){
  2. let v = vec![1,2,3];
  3. // 获取迭代器,但是这时候没有使用,也就是没有消费该迭代器,所以他是没任何用的
  4. let v_iter = v.iter();
  5. // 我们通过调用 for..in 来消费迭代器
  6. for item in v_iter{
  7. println!("{}",item);
  8. }

Iterator trait

  • 所有迭代器都实现了Itertor trait

Itertor trait 在标准库中的定义

  1. pub trait Itertor {
  2. type item;
  3. fn next(&mut self) -> Option<Self::item>;
  4. }
  • 实现Itertor trait需要你定义一个item类型,这个类型就是next方法需要返回的类型(迭代器的返回类型)

    迭代方法

  • iter:创建的迭代器不会获得所有权

  • into_iter:创建的迭代器会获得所有权
  • iter_mut: 创建的迭代器中的元素都是可变的

    消耗迭代器的方法

  • 在标准库中,Itertor trait有一些默认实现的方法

  • 其中有一些方法会调用next方法
    • 这也是实现Itertor trait时必须实现next方法的原因之一
  • 调用next的方法叫做“消耗型适配器”
    • 因为调用他们会把迭代器消耗尽
  • 例如:

    • sum方法
    • collect方法:把结果收集到一个集合类型中

      产生其他迭代器的方法(map)

  • 定义在Itertor trait上另外一些方法叫做“迭代器适配器

    • 就是把迭代器转换为不同种类的迭代器


  • 可以用过链式调用使用多个迭代器适配器来执行复杂的操作

Map

  • 接收一个闭包,闭包作用于每个元素
  • 会形成另一个迭代器
    1. fn main(){
    2. let mut v: Vec<i32> = vec![1, 2, 3];
    3. // 这时就是形成了另一个迭代器,但是还没消耗它
    4. let new_iter = v.iter().map(|x| x + 1);
    5. // 我们在这里将迭代器消耗,把迭代器里的每个元素都放到了一个vec集合中
    6. let new_v: Vec<_> = new_iter.collect();
    7. }

    零开销抽象(Zero-Cost Abstraction)

    使用抽象时不会引入额外的运行时开销

    类似 for循环和迭代器方法(map、filter)谁的效率更高? 迭代器方法就是高度的抽象,是不会影响效率的。所以可以放心使用