借用
実際には、データの所有権を完全に受け渡すことなく一時的にアクセスしたいという場合がほとんどです。そのために、Rustでは 借用 という仕組みを用います。値そのもの(T)を受け渡すのではなく、その参照(&T)を渡すのです。
コンパイラは借用チェッカを用いて参照が 常に 有効なオブジェクトへの参照であることを、コンパイル時に保証します。つまり、あるオブジェクトへの参照が存在しているならば、そのオブジェクトを破壊することはできないということです。
// この関数はボックスの所有権を奪い、破棄します。
fn eat_box_i32(boxed_i32: Box<i32>) {
println!("Destroying box that contains {}", boxed_i32);
}
// この関数はi32を借用します。
fn borrow_i32(borrowed_i32: &i32) {
println!("This int is: {}", borrowed_i32);
}
fn main() {
// Create a boxed i32 in the heap, and an i32 on the stack
// Remember: numbers can have arbitrary underscores added for readability
// 5_i32 is the same as 5i32
let boxed_i32 = Box::new(5_i32);
let stacked_i32 = 6_i32;
// Boxの中身を借用。所有権を奪うわけではないため、
// 直後にもう一度借用できます。
borrow_i32(&boxed_i32);
borrow_i32(&stacked_i32);
{
// ボックス内の要素に対する参照を取得。
let _ref_to_i32: &i32 = &boxed_i32;
// エラー!
// ボックス内の要素が借用されているため、`boxed_i32`を破棄する
// ことはできません。
eat_box_i32(boxed_i32);
// FIXME ^ この行をコメントアウトしましょう
// Attempt to borrow `_ref_to_i32` after inner value is destroyed
borrow_i32(_ref_to_i32);
// ここで`_ref_to_i32`はスコープを抜け、借用もなくなります。
}
// `boxed_i32` can now give up ownership to `eat_box_i32` and be destroyed
eat_box_i32(boxed_i32);
}