所有権とムーブ
変数は所有するリソースを開放する必要があるため、 リソースは一つの所有者 しか持ちません。リソースを2度以上開放しないためでもあります。すべての変数 がリソースを持つわけではないことに注意してください(例えば参照)。
変数に値を代入(let x = y)したときや、関数に値を渡した(foo(x))とき、
リソースの所有権が渡されます。これをRustでは、ムーブと呼んでいます。
リソースをムーブしたら、元の所有者はもうそのリソースを使うことができません。 これによって、危険なポインタを作成するのを防ぎます。
// ヒープに確保したメモリの所有権を必要とする関数 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 ^ この行をアンコメントしてみてください }