部分的ムーブ

1つの変数の デストラクト の中で、ムーブ参照 の両方のパターン束縛を同時に使用することができます。両方を使用すると、変数の一部がムーブされ、他の部分が参照として残るという変数の部分的ムーブが発生した状態になります。変数の部分的ムーブが発生すると親変数はその後使用できませんが、参照されているだけの部分(ムーブされていない部分)は使用することができます。

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

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

    // `name` は person からムーブしたが、 `age` は参照されています。
    let Person { name, ref age } = person;

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

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

    // エラー!部分的ムーブした値の借用:`person` では部分的ムーブが発生しています。
    //println!("The person struct is {:?}", person);

    // `person` は使用できませんが、
    // `person.age` はムーブしていないので使用できます。
    println!("The person's age from person struct is {}", person.age);
}

この例では、age変数をヒープ上に保持し、部分的ムーブを説明しています。上記コードでrefを削除すると、person.ageの所有権がage変数にムーブされるため、エラーになります。もしもPerson.ageがスタック上に保持されていたら、ageの定義がperson.ageをムーブすることなくデータをコピーするので、refは必須ではないのですが、実際にはヒープ上に保持されているためrefは必須です。

参照

デストラクト