向量借用和所有权

10
这个不起作用:
let vectors = vec![1, 2, 3, 4, 5, 6, 7];

for i in vectors {
    println!("Element is {}", i);
}

let largest = vectors[0];

错误信息:
error[E0382]: borrow of moved value: `vectors`
 --> src/main.rs:8:19
  |
2 |     let vectors = vec![1, 2, 3, 4, 5, 6, 7];
  |         ------- move occurs because `vectors` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
3 | 
4 |     for i in vectors {
  |              -------
  |              |
  |              value moved here
  |              help: consider borrowing to avoid moving into the for loop: `&vectors`
...
8 |     let largest = vectors[0];
  |                   ^^^^^^^ value borrowed here after move

矢量已移入循环中。它的所有权及其各个元素的所有权已永久转移至此。

但这是有效的:

let largest = vectors[0];
let largest2 = vectors[0];

我不知道为什么;应该将vectors [0]的值移动到largest中,然后使largest2失败,但实际上并没有。
2个回答

10
当你在 for..in 循环中使用 vectors 时,Rust 会调用 VecIntoIterator::into_iter 特性方法,它会获取 self 的所有权。因此,之后你就不能再使用 vectors 了。
use std::iter::IntoIterator;

// these are equivalent
for i in vectors { /* ... */ }
for i in IntoIterator::into_iter(vectors) { /* ... */ }

另一方面,索引运算符 调用 VecIndex::index 特质方法,该方法通过引用获取 self。此外,它会自动解引用值,因此,如果向量中的项实现了 Copy,它们将从向量中复制出来,而不是借用(如果需要引用,必须显式借用):

use std::ops::Index;

// these are equivalent
let x = vectors[0];
let x = *Index::index(&vectors, 0);

// these are equivalent
let x = &vectors[0];
let x = Index::index(&vectors, 0);

2

您的 Vec 中的值类型(可能是 i32)实现了 Copy 特质,这意味着当索引向量时它们不会被移动出去,而是被复制。

这样的 Copy 类型的 Vec 仍然没有实现 Copy 本身,因此它会被移动到循环中。您可以通过编写以下代码来避免这种情况

for i in vectors.iter() {
    println!("Element is {}", *i);
}
解引用 (*) 可以给你一个像在原始代码示例中一样的拥有值。它对于 println! 来说并不是必需的,但对于其他用途可能是必需的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接