その他

【Rust】所有権の借用について

その他
この記事は約3分で読めます。

はじめに

『Ownership』(所有権)の概念は、Rustの大きな特徴の一つです。

3つのルールを押さえておく必要があります。

  1. あらゆる値は変数に所有される
  2. オーナーがスコープから外れたら値も解放される
  3. オーナーは常に1人

変数を関数の引数に渡したりなど、所有権の移動にうまく対応する必要があります。
ゆえに、借用の概念が存在します。

所有権の移動の例

fn main() {
    let mut input = String::new();
    // 所有権はfunctionの引数strへ
    function(input);

    // エラー: inputはもはや値への参照を持たない
    io::stdin().read_line(&mut input);
}

fn function(str: String) {}

借用

所有権を移動させずに、あくまで参照することで元の所有者を保ちながら値のやりとりをすることができます。

所有権ではなく、その参照に止めるには『&』を変数の前に付けます。

fn main() {
    let mut input = String::new();
    function(&input);

    io::stdin().read_line(&mut input);
}
// &をつける
fn function(str: &String) {}

変更可能(ミュターブル)な借用

Rustの変数はデフォルトで変更不可(イミュータブル)です。
借用した変数を変更するためにはmutキーワードを付けます。

fn main() {
    let mut input = String::new();
    function(&mut input);

    io::stdin().read_line(&mut input);
}
// &mutをつける
fn function(str: &mut String) {
  str.push_str("rust");
}

複数の借用(エラー)

同時に複数の変更可能(ミュターブル)な借用はエラーになります。

let mut input = String::new();

let mut s1 = &input;
let mut s2 = &input;

これは他の言語で好きに変数を渡すことに慣れていると最初不便なこともありますが、データレース(競合)のない安心感があります。

let mut input = String::new();

let s1 = &input;
let s2 = &input;

mutキーワードのない変更不可(イミュータブル)な借用は、もちろん複数存在できます。こちらはただの参照であり、値の変更による競合がありえないからです。