Open4

Rust勉強

りくとりくと

所有権

let user_name = String::from("doraemon");
let copy_user_name = user_name;
println!("{}", user_name);
//                  ^^value used here after move (ムーブ後にここで使用されている)

このときuser_nameは有効ではないためコンパイルエラーが起こる
それはなぜか、公式の説明によると

スタックにあるポインタ、長さ、 許容量をコピーするということです。
ポインタが指すヒープ上のデータはコピーしません。

ということらしい。
つまり、let copy_user_name = user_nameしたときにuser_nameの所有権がcopy_user_nameに移動する。(このときuser_nameは有効ではなくなる)
スタックにある文字列型の情報をコピーするが、文字列データ(ヒープ上にある)自体はコピーしないのでcopy_user_nameが文字列データの新しい所有者になる。

りくとりくと

では

let age = 23;
let copy_age = age;
println!("age: {} copy_age: {}", age, copy_age);

なぜこのコードはうまくいくのか?
公式には

整数のようなコンパイル時に既知のサイズを持つ型は、スタック上にすっぽり保持されるので、 実際の値をコピーするのも高速だからです。

つまり、既知のサイズをもつ型はコピーをするのが高速だから無効化する必要がないためということ

りくとりくと

ムーブするときはどういうときか

let str = String::from("nyaa");

// String型を代入してムーブする
let cat_message = str;

// 値が関数に渡されてムーブする
cat_method(str);

// 戻り値をcatにムーブする
let cat = method();
りくとりくと

参照と借用

参照とは、所有権をもらうことなく値にアクセスできるもの。
借用とは、引数に参照を取ること。
これらはデータに対する変更はできない。

可変な参照

let mut doraemon = String::from("nekogata");
change(&mut doraemon);

fn change(str: &String) {
  str.push_str("_robot");
}

可変参照には所有権を移動せずに値を変更できるという利点がある。
これにより同じデータにアクセスできるため再利用性が高まる。
ただし、同じスコープからは同時にアクセスできない。

  • &sは値を変更できないがどこからでも同時に参照できる。
  • &mut sは値を変更できるが同時の参照はできない。
    • この場合の同時というのは先に&sがある場合も参照できない。