迭代器

好的,我们来详细解释一下 Rust 中的 into_iter(), iter(), 和 iter_mut() 这三个方法。它们都是用于从集合(如 Vec, HashMap, String, 数组等)创建迭代器的核心方法,但它们在处理集合 ​​ 所有权 ​​ 和 ​​ 元素访问权限 ​​ 上有本质区别。

​ 核心区别总结:​

方法 所有权转移 元素访问方式 返回的迭代器类型 集合之后是否可用
into_iter() ​ 消耗 ​​ 集合 (Move) ​ 拥有 ​​ 元素 (T) IntoIterator::Item = T ​ 不可用 ​
iter() ​ 借用 ​​ 集合 (Immutable Borrow) ​ 不可变引用 ​​ (&T) Iterator::Item = &T ​ 可用 ​
iter_mut() ​ 可变借用 ​​ 集合 (Mutable Borrow) ​ 可变引用 ​​ (&mut T) Iterator::Item = &mut T ​ 可用 ​

​ 详细解释:​

  1. into_iter() (Into Iterator)​

    • ​ 所有权:​​ 这个方法 ​​ 消耗 ​​(consume)集合本身。调用 into_iter() 后,​​ 原始集合的所有权被转移 ​​ 到迭代器中。这意味着你不能再使用原来的集合变量(除非它实现了 Copy trait,但集合类型通常不会)。
    • ​ 元素访问:​​ 迭代器 ​​ 产出集合中每个元素本身 (T)​​。你获得了元素的所有权。
    • ​ 用途:​
      • 当你 ​​ 不再需要原始集合 ​​,并且想逐个 ​​ 拥有 ​​ 集合中的元素进行处理时。
      • for 循环中直接使用集合变量时,Rust 会 ​​ 隐式调用 into_iter()​。例如:
      1
      2
      3
      4
      5
      let v = vec![1, 2, 3];
      for num in v { // 等价于 `for num in v.into_iter()`
      println!("{}", num);
      }
      // println!("{:?}", v); // 错误!v 的所有权已被移动
      • 需要将集合 ​​ 转换 ​​ 成另一种类型时(例如 Vec<T> 转换成 Vec<U>)。
    • ​ 返回值:​​ 一个迭代器,其 Item 类型是 T(元素类型本身)。
  2. iter() (Iterator)​

    • ​ 所有权:​​ 这个方法对集合进行 ​​ 不可变借用 ​​。调用 iter() 后,你仍然可以继续使用原始集合。
    • ​ 元素访问:​​ 迭代器 ​​ 产出集合中每个元素的不可变引用 (&T)​​。你可以读取元素的值,但不能修改它们。
    • ​ 用途:​
      • 当你只需要 ​​ 读取 ​​ 集合中的所有元素,而不需要修改它们或集合本身时。
      • 需要多次遍历同一个集合时。
      • for 循环中显式使用 iter() 来避免移动所有权:
        1
        2
        3
        4
        5
        let v = vec![1, 2, 3];
        for num in v.iter() { // num 是 &i32
        println!("{}", num);
        }
        println!("{:?}", v); // 正确,v 仍然可用
    • ​ 返回值:​​ 一个迭代器,其 Item 类型是 &T(元素的不可变引用)。
  3. iter_mut() (Mutable Iterator)​

    • ​ 所有权:​​ 这个方法对集合进行 ​​ 可变借用 ​​。调用 iter_mut() 后,在迭代器存活期间,你 ​​ 不能 ​​ 再通过原始变量或其他方式 ​​ 可变地访问 ​​ 这个集合(Rust 的借用规则确保只有一个可变引用存在)。但是,你仍然可以在迭代完成后使用集合。
    • ​ 元素访问:​​ 迭代器 ​​ 产出集合中每个元素的可变引用 (&mut T)​​。你可以 ​​ 读取并修改 ​​ 元素的值。
    • ​ 用途:​
      • 当你需要 ​​ 修改 ​​ 集合中的元素时。
      • 例如:
        1
        2
        3
        4
        5
        let mut v = vec![1, 2, 3];
        for num in v.iter_mut() { // num 是 &mut i32
        *num *= 2; // 解引用并修改值
        }
        println!("{:?}", v); // 输出: [2, 4, 6]
    • ​ 返回值:​​ 一个迭代器,其 Item 类型是 &mut T(元素的可变引用)。

​ 关键点记忆:​

  • into_iter():​​ “我全都要!” - 拿走整个集合和里面所有东西的所有权。原集合消失。
  • iter():​​ “借我看看!” - 只读借用集合和里面的东西。原集合完好无损,可以继续用。
  • iter_mut():​​ “借我改改!” - 可修改借用集合里的东西。原集合结构还在,但里面的内容可能变了。

​ 选择哪个?​

  • 想 ​​ 修改元素 ​​?用 iter_mut()
  • 只想 ​​ 读取元素 ​​ 且 ​​ 保留集合 ​​?用 iter()
  • 想 ​​ 消费集合 ​​(比如转换元素类型、把集合所有权传给其他函数)?用 into_iter()(或直接在 for 循环里用集合变量)。

注意:该文章由 DeepSeek R1 结合课程笔记优化生成,并由 Garusuta 修改发布