部分的なムーブ
単一の変数のデストラクチャリング内では、by-move と by-reference のパターン束縛を同時に使用できます。これを行うと、 変数の 部分的なムーブ が発生します。つまり、変数の一部はムーブされ、 他の部分は残ります。このような場合、その親変数は以後、全体としては 使用できませんが、参照されただけで(ムーブされていない)部分は引き続き 使用できます。なお、Drop トレイトを実装している型からは 部分的にムーブできません。なぜなら、その drop メソッドが後でそれを 全体として使用するためです。
fn main() { #[derive(Debug)] struct Person { name: String, age: Box<u8>, } // エラー! `Drop` トレイトを実装している型からはムーブできない //impl Drop for Person { // fn drop(&mut self) { // println!("Dropping the person struct {:?}", self) // } //} // TODO ^ これらの行のコメントを外してみてください 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 は不要です。)