将向量传递到“ for”循环中而不是对向量的引用意味着什么?

Ana*_*Ana 2 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); }
}
Run Code Online (Sandbox Code Playgroud)

它输出以下内容:

&i32
&i32
&i32
i32
i32
i32
Run Code Online (Sandbox Code Playgroud)

传递向量for与引用向量相比是什么意思?为什么当您传递参考时,您获得对项目的参考,而当您传递实际向量时,却获得了实际项目?

She*_*ter 6

for循环的参数必须实现IntoIterator。如果检查出文档的Vec,你会看到这两个实现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>
}
Run Code Online (Sandbox Code Playgroud)

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

有时,您会看到以下更明确的形式:iterinto_iter。逻辑相同。请参阅iter和into_iter有什么区别?

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


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

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

let v = vec![1, 2, 3];
for i in &v {}
for i in &v {}
Run Code Online (Sandbox Code Playgroud)

这不是:

let v = vec![1, 2, 3];
for i in v {}
for i in v {}
Run Code Online (Sandbox Code Playgroud)
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>
}
Run Code Online (Sandbox Code Playgroud)

在所有权方面,除非克隆值(假设甚至可以克隆类型!),否则无法从引用中获取值。这意味着&vec无法产生非参考值。

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

也可以看看:

  • 也许也值得一提第三个:`impl &lt;'a,T&gt;&'a mut Vec &lt;T&gt;的IntoIterator。 (2认同)