TSK
TSK

Reputation: 751

Cannot move behind a shared reference

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 reference

move occurs because *y has type String, which does not implement the Copy 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

Answers (2)

杨尚山
杨尚山

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

Finomnis
Finomnis

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

Related Questions