Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

부분 이동

단일 변수의 구조 분해 내에서 이동에 의한(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가 필요하지 않았을 것입니다.)

참고:

구조 분해