所有権とムーブ

Because variables are in charge of freeing their own resources, resources can only have one owner. This prevents resources from being freed more than once. Note that not all variables own resources (e.g. references).

When doing assignments (let x = y) or passing function arguments by value (foo(x)), the ownership of the resources is transferred. In Rust-speak, this is known as a move.

資源を移動すると、それまでの所有者(訳注:変数などのこと)を使用することはできなくなります。これによりダングリングポインタの発生を防げます。

// この関数はヒープメモリ上の資源の所有権を取ります。
fn destroy_box(c: Box<i32>) {
    println!("Destroying a box that contains {}", c);

    // `c`は破棄されメモリは開放されます。
}

fn main() {
    // _スタック_上に置かれた整数
    let x = 5u32;

    // `x`を`y`に *コピー* します。元の値が移動するわけではありません。
    let y = x;

    // 両方の値はそれぞれ独立に使うことができます。
    println!("x is {}, and y is {}", x, y);

    // `a`は_ヒープ_上の整数へのポインタ。
    let a = Box::new(5i32);

    println!("a contains: {}", a);

    // `a`を`b`に *ムーブ* します。
    let b = a;
    // すなわち、`a`の指すメモリ上の番地が`b`にコピーされるため
    // いずれもヒープ上の同じ値を指すポインタとなります。
    // しかし所有権は`b`にあります。
    
    // エラー!`a`は所有権を持たないため、ヒープ上のデータにアクセスできません。
    //println!("a contains: {}", a);
    // TODO ^ 試しにここをアンコメントしてみましょう。

    // この関数はヒープメモリ上の所有権を`b`から取ります。
    destroy_box(b);

    // この時点でヒープメモリ上の資源は開放されているので、次の操作は
    // 解放済みメモリをデリファレンスすることになります。
    // しかしそれはコンパイラが許しません。
    // エラー!上述の理由より
    //println!("b contains: {}", b);
    // TODO ^ 試しにここをアンコメントしてみましょう。
}