Search code examples
rustmove-semanticsdestructuring

How does this "partial move" syntax work?


I am reading this official example from Rust By Example:

fn main() {
    #[derive(Debug)]
    struct Person {
        name: String,
        age: Box<u8>,
    }

    let person = Person {
        name: String::from("Alice"),
        age: Box::new(20),
    };

    // `name` is moved out of person, but `age` is referenced
    // **What is this syntax here and why does it work? 
    let Person { name, ref age } = person;

    println!("The person's age is {}", age);

    println!("The person's name is {}", name);

    // Error! borrow of partially moved value: `person` partial move occurs
    //println!("The person struct is {:?}", person);

    // `person` cannot be used but `person.age` can be used as it is not moved
    println!("The person's age from person struct is {}", person.age);
}

This line of code:

let Person { name, ref age } = person;

caught me off guard; I understand,

let person_a = Person {name: String::from("Bob"), age: Box::new(30)},

and,

let moved_person_a = person_a.

That line of code looks foreign to me.

Secondly, we are accessing age and name directly as if we have defined them directly in the scope of main. Does this have anything to do with the line of code above? Or this is how Rust works (i.e. Accessing member properties of a object without the presence of the object, which already sounds a bit insane to me)?


Solution

  • The line in question is a pattern for destructing structs.

    It creates two variables name and age and initializes them with person.name and person.age. Because of the ref the age variable will have the type &Box<u8> and point to person.age.

    At this point the struct person is partially moved out, because of the move of person.name, so you cannot use it anymore. But you can still use person.age because this was not moves out because of the ref.