Reputation: 751
This code doesn't compile:
fn main() {
let x = "".to_string();
let y = &x;
let z = *y;
}
Compiler error output is:
cannot move out of
*y
which is behind a shared referencemove occurs because
*y
has typeString
, which does not implement theCopy
trait
I'm not very clear what's happening here and looking for an explanation.
I was expecting z
taking ownership of the String
and x
and y
becoming unusable.
Upvotes: 5
Views: 2102
Reputation: 11
I have a different understanding. But my understanding may be incorrect. Through derefence operator(*y),an unnamed temporary variable is generated. This temporary variable differs from x(let x = "".to_string();) in that it does not take ownership. (let z = *y;) => moved out temporary variable, but not owner. So error.
https://rustwiki.org/en/reference/expressions.html#moved-and-copied-types
Upvotes: -1
Reputation: 22748
let z = *y;
This line only knows y
, and y
is a &String
. &String
doesn't carry any information where it comes from, it only carries the information that it is a reference to a String
. It doesn't know or care about the fact that x
contains the actual content, nor does it have any control over x
, apart of the fact that the borrow checker makes sure that x
stays in scope and immutable.
So *y
doesn't actually produce x
, but an anonymous String
value that is only accessible through a reference, meaning it can be used, but not owned.
By doing z = *y
, you are attempting to own the value behind a reference. But as I said, this would require modifying x
(as it isn't valid any more afterwards), and y
has no power over x
. So this isn't possible.
Because doing z = *y
wouldn't be a problem with copyable types, as they don't require a transfer of ownership but simply get copied, Rust informs you that this isn't possible because the value that y
references doesn't implement Copy
.
Upvotes: 3