Progrust Library.

// dictionary

参照.

別の誰かが持っている値を指し示しつつ、その所有権を持たない値のことを参照(reference)と呼びます。
参照は主に、値xに対して&&mutなどのような参照演算子が付与された式(&x&mut x)から取得できます。(それ以外の方法でも参照が自動的に作成されるケースがあります。)
参照を作成して別の変数などに渡すことで、ムーブすることなく渡した先で値を利用できます。

fn count_chars(text: &str) -> usize {
    text.chars().count() // 参照経由で値を読める
}

fn main() {
    let message = String::from("こんにちは");
    let len = count_chars(&message); // 参照を作成して関数へ渡す(所有権はムーブしない)
    println!("「{message}」は{len}文字"); // 「message」の所有権は残っているので引き続き使える
}
Playgroundで開く

2種類の参照

共有参照(不変参照)

主に&の参照演算子を付与して作成する参照を共有参照と呼びます。共有参照では指し示している値を書き換えることはできません(内部可変性パターンのデータ型を除く)。1つの値を指し示す複数の共有参照が同時に存在していても問題ありません。(共有)

fn main() {
    let message = String::from("こんにちは");
    let message1 = &message;
    let message2 = &message; // 複数の共有参照を同時に作成可能
    // message1.push_str(", 世界"); のような値の変更はできない
    println!("「{message1}」「{message2}」");
}
Playgroundで開く

排他参照(可変参照)

主に&mutの参照演算子を付与して作成する参照を排他参照と呼びます。排他参照では指し示している値を書き換えることができます。1つの値を指し示す複数の排他参照が同時に存在することはできません。(排他)

fn main() {
    let mut message = String::from("こんにちは");
    let message1 = &mut message;
    message1.push_str(", 世界"); // 排他参照では値の書き換えができる
    // let message2 = &mut message; // 複数の排他参照を同時に作成することはできない
    // let message3 = &message; // 排他参照が有効な間は共有参照を作成することはできない(逆も同じ)
    println!("「{message1}」");
}
Playgroundで開く

補足

排他参照だけでは値の変更はできない

排他参照に対してそれが指し示す値を書き換えたい場合は参照外しを通す必要があります。

fn deposit(balance: &mut i32, amount: i32) {
    *balance += amount; // 参照先の値を書き換える
}

fn main() {
    let mut balance = 1000;
    deposit(&mut balance, 500);
    println!("入金後の残高: {balance}円");
}
Playgroundで開く

ただし、メソッド呼び出しなど一部の機能では自動参照・自動参照外しが働き、*(参照外し)を書かずとも値を変更することができます。

fn main() {
    let mut message = String::from("こんにちは");
    let message = &mut message;
    message.push_str(", 世界"); // 自動参照外しにより書き換え
    println!("「{message}」");
}
Playgroundで開く
mutでない変数からは排他参照を作れない

排他参照は「書き換えてよい」という許可を借りるものなので、そもそも書き換えを許していない(mutなしで宣言された)変数からは作れません。

fn main() {
    let balance = 1000; // mutが付いていない
    let r = &mut balance; // エラー: E0596(不変の変数は排他借用できない)
    *r += 500;
}
Playgroundで開く
共有参照と排他参照の名前の由来について

「共有参照と排他参照」は「不変参照と可変参照」とも呼ばれることがありますが、&T&mut Tの本質的な対比は不変/可変ではなく共有/排他であるという理解がRustコミュニティに浸透した結果、近年のRustではこの「共有参照と排他参照」という呼び方が好まれる傾向にあります。

実際に共有参照&Tであったとしても、内部可変性パターンのデータ型の場合は値を変更することが可能になります。

この辞書が使われているページ

backlinks 21

  1. 辞書for式
  2. 辞書NLL(非レキシカルライフタイム)
  3. 辞書クローン
  4. 辞書スライス
  5. 辞書ダングリング参照
  6. 辞書プリミティブ型
  7. 辞書ベクタ(Vec)
  8. 辞書ムーブ
  9. 辞書メソッド
  10. 辞書関連関数
  11. 辞書参照外し
  12. 辞書自動参照・自動参照外し
  13. 辞書借用
  14. 辞書所有権
  15. 辞書文字列スライス
  16. 辞書文字列リテラル
  17. 辞書文字列型
  18. 辞書論理演算子
  19. 動かして学ぶRustプログラミング問題集 › 第10章 メソッドと関連関数
  20. 動かして学ぶRustプログラミング問題集 › 第8章 参照と借用
  21. 動かして学ぶRustプログラミング問題集 › 第9章 構造体