部分的ムーブ
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
は必須です。