「並行プログラミング入門」読みすすめ その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:調べる)