Why is struct consumed when using self but not when deconsturcting?

I started learning rust from https://doc.rust-lang.org/rust-by-example/, and as far as I understand rust uses move on an assignment, and you explicitly have to tell it to copy with clone().

#[derive(Debug)]
struct Point {
    x: f32,
    y: f32,
}

impl Point {
    fn destroy(self) {
        let Point{x, y} = self;
        println!("pt is consumed: {}, {}", x, y);
    }
}

fn main() {
    let pt = Point{x: 2f32, y: 2f32};
    let Point{x, y} = pt; //#a
    println!("destructured, pt not consumed: {}, {}", x, y);
    let pt2 = pt; //#b
    //println!("pt is consumed: {:?}", pt);
    pt2.destroy(); //#c
    //println!("pt2 is consumed: {:?}", pt2);
}

So pt is consumed on #b, that is clear why. But why is it consumed on #c when it’s not consumed on #a?

>Solution :

Since f32 implement Copy the assignment at #a which could also be written as

let x = pt.x;
let y = pt.y;

performs 2 implicit copies of the two float values and thus doesn’t move pt.

But Point::destroy() takes ownership of the Point (by using self instead of &self) and thus moves the Point into it’s body.
What it does inside of the function is irrelevant (i.e. you can still use self after let Point{ x, y } = self; but not pt2 after pt2.destroy()).

Leave a Reply