Reputation: 2552
The following code throws an error:
struct Foo {
a: Vec<u64>,
}
impl Foo {
fn change_a(&mut self, new_a: Vec<u64>) {
self.a = *choose(&self.a, &new_a);
}
}
fn choose<'a>(x: &'a Vec<u64>, y: &'a Vec<u64>) -> &'a Vec<u64> {
return if x > y { x } else { y };
}
fn main() {
let mut foo = Foo { a: vec![1] };
foo.change_a(vec![3]);
println!("{:?}", foo.a);
}
The error is:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:7:18
|
7 | self.a = *choose(&self.a, &new_a);
| ^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
This code works fine if I replace the Vec<u64>
s with just u64
s.
What is the difference?
Upvotes: 0
Views: 338
Reputation: 65692
The difference is that u64
implements Copy
while Vec<u64>
does not. When you try to move a value of a type that implements Copy
but the value being moved from cannot be moved, the compiler will not actually move it, but will copy it instead, which is why the version with u64
compiles fine.
Upvotes: 2
Reputation: 500
The primitive type u64
implements Copy
. This means that u64
has "copy semantics": if the compiler finds that we are trying to take ownership of T: Copy
but the value being moved from is still used, T
will be copied.
Vec
is not Copy
, but it is Clone
, meaning that we can do
self.a = choose(& self.a, & new_a).clone();
To fix this problem.
Here is another example of copy semantics using your example
Upvotes: 2