소유권과 이동
변수는 자신의 리소스를 해제할 책임이 있으므로, 리소스는 오직 하나의 소유자만 가질 수 있습니다. 이는 리소스가 한 번 이상 해제되는 것을 방지합니다. 모든 변수가 리소스를 소유하는 것은 아닙니다(예: 참조).
할당(let x = y)을 하거나 함수 인자를 값으로 전달(foo(x))할 때, 리소스의 _소유권_이 이전됩니다. Rust 용어로는 이를 _이동(move)_이라고 합니다.
리소스를 이동한 후에는 이전 소유자를 더 이상 사용할 수 없습니다. 이는 댕글링 포인터(dangling pointers) 생성을 방지합니다.
// 이 함수는 힙에 할당된 메모리의 소유권을 가져갑니다
fn destroy_box(c: Box<i32>) {
println!("{}를 포함하는 상자를 파괴 중", c);
// `c`가 파괴되고 메모리가 해제됩니다
}
fn main() {
// _스택_에 할당된 정수
let x = 5u32;
// `x`를 `y`로 *복사* - 리소스가 이동되지 않음
let y = x;
// 두 값 모두 독립적으로 사용될 수 있음
println!("x는 {}이고, y는 {}입니다", x, y);
// `a`는 _힙_에 할당된 정수에 대한 포인터입니다
let a = Box::new(5i32);
println!("a가 포함하는 것: {}", a);
// `a`를 `b`로 *이동*
let b = a;
// `a`의 포인터 주소가 (데이터가 아니라) `b`로 복사됩니다.
// 둘 다 이제 동일한 힙 할당 데이터를 가리키지만,
// 이제 `b`가 소유권을 가집니다.
// 에러! `a`는 더 이상 데이터를 소유하고 있지 않으므로 접근할 수 없습니다.
//println!("a가 포함하는 것: {}", a);
// TODO ^ 이 줄의 주석을 해제해 보세요
// 이 함수는 `b`로부터 힙에 할당된 메모리의 소유권을 가져갑니다
destroy_box(b);
// 이 시점에서 힙 메모리가 해제되었으므로, 이 동작은
// 해제된 메모리를 역참조하는 결과를 낳겠지만, 컴파일러에 의해 금지됩니다.
// 에러! 이전 에러와 같은 이유입니다.
//println!("b가 포함하는 것: {}", b);
// TODO ^ 이 줄의 주석을 해제해 보세요
}