Vectors borrowing and ownership [duplicate]

∥☆過路亽.° 提交于 2020-06-27 16:58:10

问题


This doesn't work:

let vectors = vec![1, 2, 3, 4, 5, 6, 7];

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

let largest = vectors[0];

Error message:

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

The vector has been moved into the loop. Its ownership — and that of its individual elements — has been transferred there permanently.

But this works:

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

I don't know why; the vectors[0] value should have been moved to largest and largest2 should then fail, but it didn't.


回答1:


When you use vectors inside a for..in loop, Rust will call the IntoIterator::into_iter trait method of the Vec, which takes ownership of self. Therefore you cannot use vectors afterwards.

use std::iter::IntoIterator;

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

The index operator, on the other hands, calls the Index::index trait method of the Vec, which takes self by reference. Additionally, it automatically dereferences the value, so that if the items inside the vector implement Copy, they will be copied out of the vector instead of borrowed (you need to explicitly borrow if you want a reference):

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:


The type of the values (probably i32) in your Vec implement the Copy trait, which means that they do not get moved out when indexing the vector, they get copied instead.

A Vec of such Copy types still doesn't implement Copy itself, so it gets moved into the loop. You can avoid this e.g. by writing

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

The dereference (*) gives you an owned value like you'd get in your original code sample. It isn't necessary for println!, but might be necessary for other uses.



来源:https://stackoverflow.com/questions/61169889/vectors-borrowing-and-ownership

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!