for-loop - 与引用向量相比,将向量传递到 `for`循环是什么意思?

标签 for-loop rust

我对Rust for循环的工作方式感到困惑。考虑以下:

#![feature(core_intrinsics)]

fn print_type_of<T>(_: T) {
    println!("{}", unsafe { std::intrinsics::type_name::<T>() });
}

fn main() {
    let nums = vec![1, 2, 3];
    for num in &nums { print_type_of(num); }
    for num in  nums { print_type_of(num); }
}

它输出以下内容:
&i32
&i32
&i32
i32
i32
i32

将向量传递给for而不是对向量的引用意味着什么?为什么当您传递引用时,您获得对项目的引用,而当您传递实际向量时,您就获得了实际项目?

最佳答案

for循环的参数必须实现 IntoIterator 。如果 checkout docs for Vec ,则会看到IntoIterator的这两个implementations:

impl<T> IntoIterator for Vec<T> {
    type Item = T;
    type IntoIter = IntoIter<T>
}

impl<'a, T> IntoIterator for &'a Vec<T> {
    type Item = &'a T;
    type IntoIter = Iter<'a, T>
}

您可以获得&vec的引用和vec的值,因为这是定义迭代器的方式。

有时,您会看到这些形式更明确: iter into_iter 。逻辑相同。见What is the difference between iter and into_iter?

您还会遇到另一种形式:&mut vec iter_mut 。这些返回对向量中元素的可变引用。

至于为什么根本不同...

使用对向量的引用可以使您在循环完成后访问向量。编译如下:
let v = vec![1, 2, 3];
for i in &v {}
for i in &v {}

这不是:
let v = vec![1, 2, 3];
for i in v {}
for i in v {}

error[E0382]: use of moved value: `v`
 --> src/main.rs:4:14
  |
3 |     for i in v {}
  |              - value moved here
4 |     for i in v {}
  |              ^ value used here after move
  |
  = note: move occurs because `v` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait

在所有权方面,除非克隆值(假设甚至可以克隆类型!),否则无法从引用中获取值。这意味着&vec无法产生不是引用的值。
Vec的迭代器的实现者可以选择仅产生引用,但是将元素的所有权转让给迭代器可以使迭代器的使用者做更多的事情。从功能的角度来看,它是首选。

也可以看看:
  • What is the difference between iter and into_iter?
  • Why can I iterate over a slice twice, but not a vector?
  • 关于for-loop - 与引用向量相比,将向量传递到 `for`循环是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63508534/

    相关文章:

    javascript - 如何减少这段 JS 代码的行数,使其更短、更高效?

    javascript - 为什么我只在对象位于 "for loop"时获取第一个对象并在 vuejs 中返回其值?

    debugging - 通过写入 std::io::stdout() 输出不可见

    rust - Rust-使用serde/reqwest “Invalid type”反序列化

    java - TTS 中读取 "Strings"的编号

    javascript - 如何在 javascript 中在 for-in 中跳到下一个,并在其中一段时间​​?

    java - 在 Java 的 for 循环中使用 Println 函数?

    rust - 如何在其多态类型上调用 Display 特征?

    rust - "cannot find value __collect"将 flatten 添加到枚举结构变体时

    arrays - 如何使用另一个数组的长度来初始化 Rust 中的数组?