部分的ムーブ

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

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
    // `name` は person からムーブしたが、 `age` は参照されている
    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
    // エラー!部分的ムーブした値の借用:`person` では部分的ムーブが発生している
    //println!("The person struct is {:?}", person);

    // `person` cannot be used but `person.age` can be used as it is not moved
    // `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は必須です。

参照

デストラクト