이번 편의 목표: 어떤 값은 복사되고, 어떤 값은 새 이름으로 소유권이 옮겨가는지 구분합니다.

i32처럼 크기가 고정되고 복사가 싼 타입은 Copy입니다. 다른 이름에 넣어도 원래 이름을 계속 쓸 수 있습니다. String은 힙에 글자를 둡니다. 다른 이름에 넣으면 소유권이 옮겨가고, 원래 이름은 더 이상 그 값을 가리키지 않습니다. 스코프가 끝나면 그 시점의 주인이 값을 정리합니다.

Rust
fn main() {
    let days = 3;
    let copied = days;
    println!("{days} {copied}");

    let title = String::from("생각나무");
    let moved = title;
    println!("{moved}");
}

첫 줄은 3 3입니다. days는 복사되었으므로 두 이름 모두 살아 있습니다. 둘째 줄은 생각나무입니다. title을 println!에 다시 넣으면 컴파일러가 이미 옮겨간 값이라고 오류를 냅니다. 실행 중에 같은 메모리를 두 주인이 각각 정리하는 일을 막기 위해서입니다.

둘 다 써야 하면 clone으로 힙의 글자까지 복제합니다. clone은 비용이 있으므로, 필요 없을 때는 소유권을 옮기거나 다음 편의 참조를 씁니다.

직접 해 보기

moved로 옮기기 전에 title.clone()을 다른 이름에 넣고, 원래 title과 복제본을 둘 다 출력하세요.

해설

clone은 새 String을 만듭니다. title의 소유권은 그대로이므로 두 println!이 모두 생각나무를 출력합니다.