将向量传递到"for"循环而不是对向量的引用是什么意思? [英] What does it mean to pass in a vector into a `for` loop versus a reference to a vector?

查看:52
本文介绍了将向量传递到"for"循环而不是对向量的引用是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm confused by how Rust for loops work. Consider the following:

#![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是什么意思?为什么当您传递参考时,您会获得对项目的参考,而当您传递实际向量时,您会获得实际的项目吗?

What does it mean to pass in a vector into for versus a reference to a vector? Why, when you pass in a reference, do you get a reference to the items and when you pass in an actual vector, you get the actual items?

推荐答案

for循环的参数必须实现文档,您将参见IntoIterator的这两个实现:

The argument to a for loop must implement IntoIterator. If you check out the docs for Vec, you will see these two implementations of IntoIterator:

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的值,因为这是定义迭代器的方式.

You get references for &vec and values for vec because that's how the iterators are defined.

有时候,您会看到这些形式,它们是更明确的形式: .逻辑相同.参见 iter和into_iter有什么区别?

Sometimes, you'll see these as the more explicit forms: iter or into_iter. The same logic applies; see What is the difference between iter and into_iter?

您将遇到另一种形式:&mut vec

There's another form that you will encounter: &mut vec and iter_mut. These return mutable references to the elements in the vector.

关于为什么完全不同...

As to why the differences at all...

使用对向量的引用可以使您在循环完成后访问向量.编译:

Using a reference to the vector allows you to access the vector after the loop is done. This compiles:

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无法产生不是引用的值.

Ownership-wise, you can't get a value from a reference unless you clone the value (assuming the type can even be cloned!). This means &vec is unable to yield values that aren't references.

Vec的迭代器的实现者可以选择仅产生引用,但是将元素的所有权转让给迭代器可以使迭代器的使用者做更多的事情.从功能的角度来看,它是首选.

The implementer of Vec's iterator could have chosen to only yield references, but transferring ownership of the elements to the iterator allows the iterator's consumer to do more things; from a capability perspective it's preferred.

另请参阅:

  • What is the difference between iter and into_iter?
  • Why can I iterate over a slice twice, but not a vector?

这篇关于将向量传递到"for"循环而不是对向量的引用是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆