首页 技术杂谈 正文
  • 本文约1496字,阅读需7分钟
  • 244
  • 0

Rust - 迭代器

摘要

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方法的返回类型(迭代器的放回类型)
  • 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产生的迭代器中
评论