Nao000のぶろぐ

蝶を追っている少年になりたい

Rust lang の所有権とかを自分なりに整理する

Rust lang の所有権を自分なりに整理する

何を所有しているのか

メモリ上にあるアドレスを所有している。所有権を意識する場面はヒープ領域にあるデータを扱うときに意識します。スタック領域にあるデータは所有権の移動や借用を意識することは無いと思うので。

代入するとムーブして所有権が移動する

スタック領域のデータの代入は所有権を気にせず問題なさそうですが、ユーザー入力のデータや恐らくデータベースからのデータ取得などのヒープ領域のデータの代入は基本的に所有権が移動します。所有権が移動することをムーブというようです。

関数の引数にヒープ領域のデータを渡しても所有権が移動する

後述する借用を使うと所有権は移動しません。

借用

参照と借用 によると借用の説明に以下があります。

関数の引数に参照を取ることを借用と呼びます。

引用元: https://doc.rust-jp.rs/book/second-edition/ch04-02-references-and-borrowing.html#a%E5%8F%82%E7%85%A7%E3%81%A8%E5%80%9F%E7%94%A8

しかし、可変な参照は1つしか取れない時のコンパイルエラーを見る限り、引数に限らず参照を取ること自体を借用と呼ぶようです。

error[E0499]: cannot borrow `s` as mutable more than once at a time
(エラー: 一度に`s`を可変として2回以上借用することはできません)
 --> borrow_twice.rs:5:19
  |
4 |     let r1 = &mut s;
  |                   - first mutable borrow occurs here
  |                    (最初の可変な参照はここ)
5 |     let r2 = &mut s;
  |                   ^ second mutable borrow occurs here
  |                    (二つ目の可変な参照はここ)
6 | }
  | - first borrow ends here
  |   (最初の借用はここで終わり)

引用元: https://doc.rust-jp.rs/book/second-edition/ch04-02-references-and-borrowing.html#a%E5%8F%82%E7%85%A7%E3%81%A8%E5%80%9F%E7%94%A8

借用を利用して関数に所有権を移動させないで参照する

参照を受け取ることで所有権を移動することなく関数にデータを渡せる。ポインタの挙動ですね。

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

    let len = calculate_length(&s1);

    // '{}'の長さは、{}です
    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

引用元: https://doc.rust-jp.rs/book/second-edition/ch04-02-references-and-borrowing.html#a%E5%8F%82%E7%85%A7%E3%81%A8%E5%80%9F%E7%94%A8

これらのアンド記号が参照であり、これのおかげで所有権をもらうことなく値を参照することができるのです。

引用元: https://doc.rust-jp.rs/book/second-edition/ch04-02-references-and-borrowing.html#a%E5%8F%82%E7%85%A7%E3%81%A8%E5%80%9F%E7%94%A8

関数の書き方

関数の書き方を一般化すると次のようになります

fn 関数名(引数名: 型) -> 戻り値の型 {処理}

返り値は return など明記せずに返すことが可能。セミコロンはつけない。

    fn main() {
        let x = sample();

        println!("x is: {}", x);
    }

    fn sample() -> i32 {
        let x = 5;
        let y = 10;

        x + y
    }

実行結果

    x is: 15

文と式をより意識するようになるチュートリアルでした。

https://doc.rust-jp.rs/book/second-edition/ch03-03-how-functions-work.html