Skip to content
Go back

Rust走り書き

· Updated:
  • 凍結(freeze):ミュータブルな変数をイミュータブルな変数でシャドーイングすること
    • イミュータブル変数のスコープ中にデータを書き換えられなくする
  • forループのブロックにラベルを付けると、大外のブロックへ脱出することもできる
    • 'outer: loop { 'inner: loop { break 'outer; } }
  • loopも式なので、breakで値を返せる
  • パターンマッチした元々の値を束縛するには@を使う
    • x @ 1..=10
  • デストラクト(destructure):構造をパターンで束縛すること
  • let &(x, y) = &(100, 200);
  • 引数でもパターンを書ける
    • fn foo(&(x, y): &(i32, i32))
  • 型に紐づいて定義したものは「関連」しているという
    • selfを取る関数は特別に「メソッド」と呼ぶ
  • クロージャにムーブでキャプチャさせるには頭にmoveを付ける
    • move |x, y| {...}
  • refmutと同じように「左辺に付けて右辺を変化させる」と考えれば良い
  • 借用は、RAIIのようなスコープ単位ではなく、その変数の使用範囲内に切り詰められる
    • つまり、同じスコープ内で再借用しても、同時でなければエラーにならない
  • 引数のimpl Traitは匿名パラメータによるジェネリクスに相当する
    • C++でのconcept autoのようなイメージ
  • 関数のオーバーロードは同名メソッドを持つtraitを複数用意することで実現できる
    • 曖昧さを解決したいときは、<S as T>::foo(a, b, c)で呼び出す
  • mainの戻り値をResultにすることができる
  • 失敗時にイテレーションを途中で切り上げたい場合、Result<T, E>のイテレータをResult<Vec<T>, E>へcollectする
  • 文字列リテラルはデフォルトで複数行に対応している
  • Fileのopen関数は読み取り専用。書き込み専用はcreate関数で開く
  • Fileはそのままではバッファリングしない。しないと遅いので、BufReader/BufWriterに包む
  • ファイルパスはAsRef<Path>で受けると、strもpathもそのままで渡せるのでうま味
  • Rust 2018からテスト関数でもResult<()>を返せるようになった
  • ドキュメントコメントのコードブロックも単体テストとしてコンパイルされる(!)
  • 強めの別名型を作りたいときは、タプル方式のstructで定義する
    • struct AnotherType(usize);
    • DerefかIntoで中身にアクセスできるようにする?
  • 長過ぎる固定長配列は言語の都合のために利便性が低下することがある
    • 2024/06/24現在、RustはC++のようなジェネリクスパラメータとしての定数を扱えないので、代わりに、実用範囲内のバリエーションが手動で実装される
    • そこでカバーされない長すぎる配列はDefaultなどが定義されていない
  • タプルの無名フィールドは.0.1などの定義位置でアクセスできる
  • 型推論がけっこう優秀なので、書かなくてもやっていけるし、むしろ、書かないように記述したいまである
    • ライフタイムもわりと_で推論させられたりするので思ったより楽できる
    • 定数や戻り値などは言語設計として省略できないので注意
  • 言語サーバーがとにかく優秀なので、頼りまくれ
    • 推論された型や借用やイテレータの中間結果などがどうなっているかをリアルタイムで確認できるので、試行錯誤がしやすい
    • inlay hintsが豊富に表示されるので、コードが何倍も読みやすい
    • ただし、ヒント更新の折々で見た目が崩れるので、カーソルの予期しない動作でモヤッとする時もある
  • structのフィールドのメモリ配置は最適化のために定義されていない
    • 書いた通りにメモリ上に配置させたいときはrepr(C)を付ける
  • std::paniccore::panicのエイリアスでないので、両方useすると曖昧エラーになる