Destructuring & References in Rust
While teaching myself some Rust, it was common to see some code that "looked like" it was destructuring references, like:
fn main() {
let vec = vec![1, 2, 3];
let mut iter = vec.into_iter();
println!("Find 2 in vec: {:?}", iter.find(|&x| x == 2)); // Find 2 in vec: Some(2)
}
At first glance, the semantics were a little hard to predict. My curiosity all came down to this: does this copy the whole value? So I decided to write some code to make things clear.
#[derive(Debug,Clone,Copy)]
struct Foo {
a: u32,
b: u32,
}
fn main() {
let mut x = Foo { a: 3, b: 4 };
let &mut mut y = &mut x; // destructure mutable reference, AND the variable is mutable
y.a = 50;
println!("{:?} {:?}", x, y); // ??
}
Output:
Foo { a: 3, b: 4 } Foo { a: 50, b: 4 }
A pretty minimal example here, but the syntax looks real weird. I actually had a hard time trying to express what I wanted to because of the syntax.
Once we try to mutate the struct's field, the output shows that only y
is mutated. It shows us that it indeed copies the whole value.
What if we try to destructure something that does not implement the Copy
trait, like a vector?
fn main() {
let mut x = vec![1, 2, 3];
let &mut mut y = &mut x;
println!("{:?}", y);
}
Output:
error[E0507]: cannot move out of a mutable reference
--> src/main.rs:10:22
|
10 | let &mut mut y = &mut x;
| ---------- ^^^^^^
| | |
| | data moved here
| | move occurs because `y` has type `Vec<i32>`, which does not implement the `Copy` trait
| help: consider removing the `&mut`: `mut y`
error: aborting due to previous error; 1 warning emitted
Pretty much the same example except that it's a vector, but the compiler complains for the exact reason why we tried this example in the first place. The destructure does not work because the Vec
struct does not implement Copy
. What I've understood from these examples, is that such destructuring is meant to be used on types that support cheap copying.