부분 이동
단일 변수의 구조 분해 내에서 이동에 의한(by-move) 패턴 바인딩과 참조에 의한(by-reference) 패턴 바인딩을 동시에 사용할 수 있습니다. 이렇게 하면 변수의 _부분 이동(partial move)_이 발생하는데, 이는 변수의 일부는 이동하고 다른 부분은 남아있음을 의미합니다. 이런 경우 부모 변수는 전체로서 나중에 사용될 수 없지만, 참조만 되고 이동되지 않은 부분은 여전히 사용될 수 있습니다. Drop 트레이트를 구현한 타입은 부분적으로 이동될 수 없다는 점에 유의하세요. 왜냐하면 해당 타입의 drop 메서드가 나중에 전체로서 사용될 것이기 때문입니다.
fn main() {
#[derive(Debug)]
struct Person {
name: String,
age: Box<u8>,
}
// 에러! `Drop` 트레이트를 구현한 타입에서는 이동해 나올 수 없습니다
//impl Drop for Person {
// fn drop(&mut self) {
// println!("Person 구조체를 드롭합니다 {:?}", self)
// }
//}
// TODO ^ 이 줄들의 주석을 해제해 보세요
let person = Person {
name: String::from("앨리스"),
age: Box::new(20),
};
// `name`은 person에서 밖으로 이동되지만, `age`는 참조됩니다
let Person { name, ref age } = person;
println!("이 사람의 나이는 {}입니다", age);
println!("이 사람의 이름은 {}입니다", name);
// 에러! 부분적으로 이동된 값의 빌림: `person`의 부분 이동이 발생했습니다
//println!("Person 구조체는 {:?}입니다", person);
// `person`은 사용할 수 없지만 `person.age`는 이동되지 않았으므로 사용할 수 있습니다
println!("person 구조체에서 가져온 이 사람의 나이는 {}입니다", person.age);
}
(이 예제에서는 부분 이동을 설명하기 위해 age 변수를 힙에 저장합니다. 위 코드에서 ref를 삭제하면 person.age의 소유권이 age 변수로 이동하기 때문에 에러가 발생합니다. Person.age가 스택에 저장되어 있었다면, age의 정의가 person.age에서 데이터를 이동 없이 복사하므로 ref가 필요하지 않았을 것입니다.)