NF

地方で働くプログラマ

「並行プログラミング入門」読みすすめ その4(借用とか)

「並行プログラミング入門」読みすすめ その1 - NF
「並行プログラミング入門」読みすすめ その2 - NF
「並行プログラミング入門」読みすすめ その3(入力とか) - NF
4回目、まだ基礎。
「借用」が新鮮だったので掘り下げ。この本ではそこまで詳しく書いてない(特に「図2-3 借用時の状態」は分かり辛すぎるような…)ので、他のサイトさんとかで調べつつ。あと所有権周り、説明する人によって使う用語や解説ポイントが結構違うので、ちょっと混乱する。

基礎:Rustにおける変数の種類

  • mutable変数
  • immutable変数(または、単純に変数というらしい)
  • mutable参照
  • immutable参照(または、単純に参照というらしい)

上の2つは、C++で言う(普通の)変数・const変数だと思う。
mutable参照は(普通の)参照でいいのかな?(追記:後述の通り間違ってた)
immutable参照、これはC++とかでは見た事ない概念ぽい。
 

サンプルコード

4種類の変数を取り合えず宣言。

struct Foo {
    x:i32
}
fn main() {
    let mut a: Foo = Foo{x:10};  // mutable変数
    let     b: Foo = Foo{x:20};  // immutable変数
    let     c      = &mut a;     // mutable参照
    let     d:&Foo = c;          // immutable参照
    
    a.x = 11;  // mutable変数は書き込み可
    println!("{}", a.x); // 当然読み込みも可
    
    //b.x = 21;  // immutable変数は書き込み不可
    println!("{}", b.x); // 読み込みは可
}

ここまでは普通。
 

mutable参照について

    println!("{}", a.x);
    //println!("{}", c.x);  // コンパイルエラー

参照cの宣言後に参照先が使用されていると、参照の使用は読み書き共に不可!!
エラーは、参照cの初期化の行で出る。(cannot borrow `a.x` as immutable)。

    //println!("{}", a.x);
    c.x = 12;  // mutable参照は書き込み可
    println!("{}", c.x);

宣言後に参照先が使用されなければ、参照で読み書き可。
 

immutable参照について

    //d.x = 22;  // コンパイルエラー
    println!("{}", d.x);

参照の読み込みは出来るが、書き込みは出来ない。これはmutable参照と異なるところ。

    //println!("{}", a.x); // コンパイルエラー
    println!("{}", c.x);
    println!("{}", d.x);

一度宣言したら参照先の変数かどちらかかしか使用できない。これはmutable参照と同じ。
また、このケースだと参照先のmutable参照(c)は同時に読み込める。
但し、cに書き込む場合は、dは読み込みも不可になる。


という感じで、C++でイメージしてた参照とは違っていた。
ただ、本に載ってる「貸与中」がまだちゃんと理解出来て無いっぽくて、最後の例で参照cとdに同時にアクセスできるあたりしっくり来てない(cとdが同時に所有権を保持しているように見える。)。一応、破壊的代入を行えるのが同時に1つ、と言う事で読み込みはOKと言う事なんだろうけど、そうするとaはなんで読み込みできないのだろう、という疑問が。
色々読んでみて理解を深めるしかなさそうです。
 
あと、mutable参照とimmutable参照で、宣言時に後者だけ型指定するっていうのが凄く違和感なんですが、前者は省略されてるだけって事なんだろうか。型を指定してmutable参照を宣言したかったんだけど、色々試してもやり方分からず、宿題。

    let     c      = &mut a;     // mutable参照
    let     d:&Foo = c;          // immutable参照


ーーー
借用と全然関係ないですが、本読んでて「関数」と「メソッド」がRsutだと厳密に使い分けられてるってのが新鮮でした。C++だと、どっちも関数って呼ばれてる気がする?(TODO:調べる)