部分的ムーブ
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. Note that types that implement the Drop
trait cannot be partially moved from, because its drop
method would use it afterwards as a whole.
fn main() { #[derive(Debug)] struct Person { name: String, age: Box<u8>, } // Error! cannot move out of a type which implements the `Drop` trait //impl Drop for Person { // fn drop(&mut self) { // println!("Dropping the person struct {:?}", self) // } //} // TODO ^ Try uncommenting these lines 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
は必須です。