Partial Move Destructuring in Rust

RustRustBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

In this lab, we learn about partial moves within the destructuring of a single variable, where both by-move and by-reference pattern bindings can be used simultaneously. This results in a partial move of the variable, allowing some parts to be moved while others can still be referenced. If a parent variable is partially moved, it cannot be used as a whole afterwards, but the parts that are only referenced and not moved can still be used.

Note: If the lab does not specify a file name, you can use any file name you want. For example, you can use main.rs, compile and run it with rustc main.rs && ./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("`Rust`")) -.-> rust/BasicConceptsGroup(["`Basic Concepts`"]) rust(("`Rust`")) -.-> rust/DataTypesGroup(["`Data Types`"]) rust(("`Rust`")) -.-> rust/FunctionsandClosuresGroup(["`Functions and Closures`"]) rust(("`Rust`")) -.-> rust/MemorySafetyandManagementGroup(["`Memory Safety and Management`"]) rust(("`Rust`")) -.-> rust/DataStructuresandEnumsGroup(["`Data Structures and Enums`"]) rust(("`Rust`")) -.-> rust/AdvancedTopicsGroup(["`Advanced Topics`"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("`Variable Declarations`") rust/DataTypesGroup -.-> rust/integer_types("`Integer Types`") rust/DataTypesGroup -.-> rust/string_type("`String Type`") rust/DataTypesGroup -.-> rust/type_casting("`Type Conversion and Casting`") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("`Function Syntax`") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("`Expressions and Statements`") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("`Lifetime Specifiers`") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("`Method Syntax`") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("`Traits for Operator Overloading`") subgraph Lab Skills rust/variable_declarations -.-> lab-99197{{"`Partial Move Destructuring in Rust`"}} rust/integer_types -.-> lab-99197{{"`Partial Move Destructuring in Rust`"}} rust/string_type -.-> lab-99197{{"`Partial Move Destructuring in Rust`"}} rust/type_casting -.-> lab-99197{{"`Partial Move Destructuring in Rust`"}} rust/function_syntax -.-> lab-99197{{"`Partial Move Destructuring in Rust`"}} rust/expressions_statements -.-> lab-99197{{"`Partial Move Destructuring in Rust`"}} rust/lifetime_specifiers -.-> lab-99197{{"`Partial Move Destructuring in Rust`"}} rust/method_syntax -.-> lab-99197{{"`Partial Move Destructuring in Rust`"}} rust/operator_overloading -.-> lab-99197{{"`Partial Move Destructuring in Rust`"}} end

Partial moves

Within the [destructuring] of a single variable, both by-move and by-reference pattern bindings can be used at the same time. Doing this will result in a partial move of the variable, which means that parts of the variable will be moved while other parts stay. In such a case, the parent variable cannot be used afterwards as a whole, however the parts that are only referenced (and not moved) can still be used.

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
    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);
}

(In this example, we store the age variable on the heap to illustrate the partial move: deleting ref in the above code would give an error as the ownership of person.age would be moved to the variable age. If Person.age were stored on the stack, ref would not be required as the definition of age would copy the data from person.age without moving it.)

Summary

Congratulations! You have completed the Partial Moves lab. You can practice more labs in LabEx to improve your skills.

Other Rust Tutorials you may like