本文へスキップ
BecomeCoder

Rustコース · 第5章 参照と借用 · レッスン19

参照と借用 ― & で貸す

ブラウザで完結

導入

「所有権を渡す(ムーブ)」のではなく、「ちょっと見せて(貸して)、使い終わったら返す」ができれば、前章の悩みは消えます。これが参照です。記号 & を使います。

説明

前章でムーブしてしまった関数を、参照で書き直します。

fn main() {
    let s = String::from("hello");

    let n = calc_length(&s);      // &s =「s を貸す」。所有権はムーブしない

    println!("'{s}' の長さは {n}");  // s はまだ使える!
}

fn calc_length(text: &String) -> usize {   // &String =「String を借りる」型
    text.len()
}   // ← text はスコープを抜けるが、借りていただけなので何も解放しない
  • &s … 「s への参照」を作ります。所有権は渡さず、s貸すだけ。この行為を 借用(borrowing) と呼びます。
  • text: &String … 関数は String借りている(所有していない)ことを型で表します。
  • 関数が終わっても、text は借り物なのでヒープを解放しません。所有者はあくまで mains。だから main に戻っても s は健在です。

参照は「ヒープデータそのもの」ではなく「所有者を指すポインタ」だと考えるとしっくりきます。

graph LR
    subgraph stack["スタック"]
        text["text(&String・借用)"]
        s["s(String・所有者)"]
    end
    subgraph heap["ヒープ"]
        d["h | e | l | l | o"]
    end
    text -->|指す| s
    s -->|所有| d

texts を指し、s がヒープを所有する。だから借用中にヒープが勝手に解放される心配はありません(所有者 s が生きている限り、データは有効)。

このように「所有権を渡さずに値へアクセスする参照を作ること」が借用です。既定の & で作る参照は 不変(読み取り専用) で、借りた値を書き換えることはできません。書き換えたいときは次のレッスンの &mut を使います。

試すには

前章のムーブでエラーになったコードを、関数の引数を &s&String に変えるだけで解決できます。clone() のようなコピーコストもかかりません。「渡す」を「貸す」に変えるだけ——この置き換えを体に染み込ませましょう。

実際に動かしてみよう

下のエディタにRustを書いて「実行」を押すと、学習用シミュレータが println! の出力を表示します(本物のrustcではなく、教材の範囲を再現した軽量エンジンです)。struct・enum・match・トレイト・Vec/String/HashMap・Option/Result なども動きます。本文の例を書き換えて動かしてみましょう(所有権・借用チェッカーのコンパイルエラーは再現しないため、動きの確認用として使ってください)。

Rust — ブラウザ内で実行(学習用シミュレータ)

Rustの教材サブセットを動かす学習用シミュレータを読み込みます(本物のrustcではなく、動きを再現した軽量な自作エンジンです)。
スクロールして表示された時点でも自動で読み込まれます。