プログラミング言語Rust 「3.2 食事する哲学者」写経時のつぶやき
2018/12/07
str型とString型が違うって言われて混乱。調べる
— ちゃまぐ (@tyamaguc07) 2018年12月7日
Stringの方を文字列、strの方を文字列スライスと読んだりする
— ちゃまぐ (@tyamaguc07) 2018年12月7日
String型はu8のベクタ、str型はu8のスライス
ベクタは、他のプログラミング言語でおなじみのヒープに格納される可変長配列
スライスは、実行時に長さの決定する固定長配列https://t.co/njijMTdI4k
■ 関連関数(associated function)
— ちゃまぐ (@tyamaguc07) 2018年12月7日
self を引数に取らない関数
幾つかの言語では、関連関数を「静的メソッド」(static methods)と呼んでいます。
impl ブロックは 構造体に関する定義を与える
— ちゃまぐ (@tyamaguc07) 2018年12月7日
&https://t.co/3Ucpvf6C24_string() は &strの指す文字列のコピーをString型で取得する
Rust言語は「式ベース(expression based)」なので、 Rustではほとんどが値を返す式となる
new()という名前はRustにとって特別な意味を持たないが構造体の新しいインスタンスを生成する関数としてよく用いられる
— ちゃまぐ (@tyamaguc07) 2018年12月7日
Rustでは、メソッドは明示的なselfパラメータを取る
Vec<T> は「ベクタ(vector)」とも呼ばれる、可変長の配列型
ベクタの走査にはforループを使え、それぞれの要素への参照を得れる
millisecondをmillsと省略するのか。
— ちゃまぐ (@tyamaguc07) 2018年12月7日
use は名前をスコープに持ち込む
2018/12/08
Vec<_> の _ は型プレースホルダ。「何らかの型のベクトルとするが、その型が何であるかはRustが解決せよ」という表現
— ちゃまぐ (@tyamaguc07) 2018年12月8日
into_iter()は所有権を持つイテレータを生成する
thread::spawn 関数はクロージャを1つ引数にとり、新しいスレッド上でそのクロージャを実行する
moveアノテーションはキャプチャする値の所有権がクロージャ内へと移動する
— ちゃまぐ (@tyamaguc07) 2018年12月8日
(このmoveはmoveクロージャと言われるものらしい)
thread::spawn 呼び出しの末尾にセミコロンを置かないことで、式としている
式は値を返すが、文は返さない
Rustには2種類の文がある。「宣言文」と「式文」
既に束縛されている変数(例えば、y = 5)への割当ては式
— ちゃまぐ (@tyamaguc07) 2018年12月8日
割当てが割り当てられる値を評価する他の言語とは異なり、Rustでは割当ての値は空のタプル
y=5の場合、割り当てられる値は5
タプルは異なる型の値の集合
式文は式を文に変換する
collect() は何らかのコレクション型を生成する
thread::spawnはスレッドへのハンドルを返す
— ちゃまぐ (@tyamaguc07) 2018年12月8日
joinHandle.join()はスレッドの終了まで待つ
Rustでなにかをunwrap()するとき、こう言っているのと同じです。「計算結果を取り出しなさい。もしエラーになっていたのなら、パニックを起こしてプログラムを終了させなさい。」
2018/12/09
usize => The pointer-sized unsigned integer type.
— ちゃまぐ (@tyamaguc07) 2018年12月9日
lock() 呼び出しは失敗する可能性があり、その場合はプログラムをクラッシュさせる
lock()が失敗するケースはロックを保持しているスレッドがパニックした場合のみ(この状態を「poisoned」 状態と表現する)
Rustは未使用の変数名があると警告を出す
— ちゃまぐ (@tyamaguc07) 2018年12月9日
変数名のプレフィックスにアンダースコア(例えば、_hoge)を使うことでRustは未使用の警告を出さない
「arc」は「アトミック参照カウント(atomic reference count)」を意味する
Arc<T>はRustの標準アトミック参照カウント型
— ちゃまぐ (@tyamaguc07) 2018年12月9日
複数の参照間で値の所有権を同時に共有できるように、値を特別な実行時の管理用データでくるむもの
管理用データは、値への参照がいくつ存在しているかというカウントが記録する=「参照カウント」
複数スレッドから安全にアクセスできる=「アトミック」
ムッシュ・フーコー(Foucault)は 4, 0 を引数にとるべきですが、 代わりに、 0, 4 としています。これはデッドロックを防ぐためのもの
— ちゃまぐ (@tyamaguc07) 2018年12月9日
→ 一人目が2つ目の🍴を取るときには二人目が2つ目の🍴を取る処理になっているため単純にやるとデッドロックする模様
Arc<T> の clone() メソッドにより参照カウントが増加し、 スコープ外に出たときは、参照カウントが減算される
— ちゃまぐ (@tyamaguc07) 2018年12月9日
参照カウントを行わないと、いつ解放すればよいかが分からなくなる
実行結果がサンプルと異なってあれってなった。
— ちゃまぐ (@tyamaguc07) 2018年12月9日
環境によって実行速度が変わるにで、あたり前ではある。
自分の場合は、🍴を取るのにかかる時間(150ms)を変更(15ms)に変更することで、二人同時に食べている状態を作れた。