Rust
ドキュメント
公式が一番参考になるのでぐぐる必要はない
https://lib.rs/ (crate.ioよりも洗練されてて事実上の標準ライブラリがわかるようになっていてよい)
命名規約
Clippy
https://rust-lang.github.io/rust-clippy/master/index.html
Cookbook
必須ツール
rls(LSP)
clippy
rustfmt
https://www.rust-lang.org/tools
代表的なプロダクト
基本
文字列
formatの指定の仕方
https://qiita.com/YusukeHosonuma/items/13142ab1518ccab425f4
formatでn文字ぴったりにする
7文字制限だと
関数の引数の入出力
入力は&str
(がんばるなら>(s: S)がいい)、出力はString
がよい気がする
型変換
https://qiita.com/legokichi/items/0f1c592d46a9aaf9a0ea
リファクタリング
https://doc.rust-jp.rs/book/second-edition/ch12-03-improving-error-handling-and-modularity.html
ファイル分割
https://keens.github.io/blog/2018/12/08/rustnomoju_runotsukaikata_2018_editionhan/
OptionとResultの使い方
https://qiita.com/tatsuya6502/items/cd41599291e2e5f38a4a
イテレータ
https://qiita.com/lo48576/items/34887794c146042aebf1
非同期プログラミング
rust-jp slackのtatsuya6502さんのコメントより
スケジューラ(または実行モデル)の分類について、上のOPTiMさんの記事ではM:Nモデルを「スレッドプール」と「ワークスティーリング」の2つに分けています。しかし実際にはスレッドプールと呼んでいるものがさらに2つに分かれて、しかも性能特性が逆なので少し注意が必要です。 https://tokio.rs/blog/2019-10-scheduler/ の記事の解説に合わせて3つに分類すると以下のようになります。(記事の図を見ると違いがわかりやすいです) 1. One queue, many processors
単一の実行キューを複数プロセッサで共有するタイプ
全てのタスクが公平にスケジューリングされる
実行キューが常に複数プロセッサ(複数のOSスレッド)からアクセスされるため、タスク切り替えのオーバーヘッドが高い。(非同期タスクではタスク切り替えの頻度が非常に高く、性能への影響が大きい)
実装がシンプル(ランタイムがバグりにくい)
Many processors, each with their own run queue
個々のプロセッサがそれ専用の実行キューを持つタイプ
タスクのスケジューリングにばらつきがでる(不公平)
実行キューが単一のプロセッサ(OSスレッド)からしかアクセスされないため、タスク切り替えのオーバーヘッドが低い
実装がシンプル(ランタイムがバグりにくい)
Work-stealing
性能は2番に近く、2番の欠点である不公平なスケジューリングの解決を図ったもの
個々のプロセッサがそれ専用の実行キューを持つが、プロセッサが暇になると他のプロセッサの実行キューからタスクを奪うタイプ
全てのタスクがほぼ公平にスケジューリングされる
ほとんどの場合、実行キューが単一のプロセッサ(OSスレッド)からアクセスされるため、タスク切り替えのオーバーヘッドが低い
実装が複雑(ランタイムがバグりやすい)
テストコード
単体テストコードはソースコードの中に書く。modでくくる
結合テストはtests/
ディレクトリに格納する
テストデータの置き場
rlsはtests/fixtures/に置いてる模様
ripgrepはtests/data
testdata派もいるみたい
Cargo
Cargoで使える環境変数
RUSTUP_HOME: ~/.rustup
CARGO_HOME: ~/.cargo
OUT_DIR: ./target/debug/build/xxx-hashyyy/out
https://doc.rust-lang.org/cargo/reference/environment-variables.html
テスト
Tips
FixtureTest
FixtureTestは2019/07/12現在サポートされていない。
https://internals.rust-lang.org/t/pre-rfc-lightweight-test-fixtures/6605
デバッグ
lldb
型を表示する
type lookup xxx
仕様
借用と参照と関数の引数の関係
https://qiita.com/yz2cm/items/9a8337c368cf055b4255#%E3%81%BE%E3%81%A8%E3%82%81%E3%82%8B%E3%81%A8
後置のif
ない模様
https://github.com/rust-lang/rfcs/issues/1362
CI
CIでやること
https://github.com/sagiegurari/cargo-make
よく使う構文
Vecの要素を条件ごとに削除したりしたい
https://stackoverflow.com/questions/37792471/removing-elements-from-a-vec-based-on-some-condition
現在時刻取得
Utc::now().naive_utc()
static変数
よく使うcrate
clap
引数処理
特定の値だけを許容してenumに突っ込みたい
possible_valuesを使ってfrom_strで変換するのがよさげ
https://yuk1tyd.hatenablog.com/entry/2018/03/21/225533
並列/並行処理
スレッド
https://totem3.hatenablog.jp/entry/2017/05/10/210000
Tips
&OptionからOptionに変換したい
aaa.as_ref() でOption<&T>に変換して、 aaa.as_ref().cloned() でOptionにする
OsStringからfailtureに変換する
the trait std::error::Error
is not implemented for std::ffi::OsString
boolをResult型に変換する
boolinatorを使うのがよさそう
文字列から改行を削除する
https://blog.v-gar.de/2019/04/rust-remove-trailing-newline-after-input/
関数の引数でたくさんの型を許容したい
&Tとmut &Tを受け付けたい: Borrowを使う
https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/borrow-and-asref.html
Pathっぽいものを受け付けたい:AsRefを使う
&strとStringを受け入れたい: Into or AsRef
https://exoskeleton.dev/proglang/rust/rust-8.md#String%E3%81%A8Into%3CString%3E
非同期で関数をループ実行
std::threadで? operatorを使いたい
fast returnしたいときのやり方。closureに戻り値を書く
ジェネリクスでの型を指定する
turbofish ::<>を使う
最適化したい
rustcにオプションをつける -C opt-level=3 -C debug_assertions=no
lines()でreferenceが使えない
by_ref()を使う
unit testでプロジェクトルートを取得する
build.rsでprintlnする
cargo build --verbose -vv
で表示できる。表示されないときはファイルを一部更新してもう一度実行してみる。
リポジトリが変更されたら強制的にbuild.rsを呼び出すようにする方法
エラーメッセージでNo such file or directoryがどのファイルかわからない
std::fsのエラーメッセージは貧弱なのでex(https://docs.rs/ex/0.1.3/ex/)を使うとよい模様
https://www.reddit.com/r/rust/comments/bsn0zs/get_which_filename_is_not_found_on_rust_file/
mainで早期リターン
1.26からはmainで?が使えるのでそれを使ったほうがいい。
https://blog.rust-lang.org/2018/05/10/Rust-1.26.html
https://www.reddit.com/r/rust/comments/6c3gjr/early_return_and_if_let/
ワイルドカード(glob)でファイルを消す
文字列で0パディングする
ファイルの更新日時が最新のものを取得する
StringをErrorに変換したい(the trait bound &str: std::error::Error
is not satisfied)
&str: std::error::Error
is not satisfied)format_err!()マクロを使う
OptionalをResultに変換したい
ok_orを使う
info!,debug!をユニットテストでも出力させたい
env_loggerを使って、
をsetupかなにかで毎回実行させる
coverageを表示したい
cargo makeなら
serdeで項目名を変更したい
をフィールドにつけてリネームする
https://serde.rs/container-attrs.html
serdeでシリアライズとデシリアライズの名称を変えたい
https://github.com/serde-rs/serde/issues/1320
テストデータの置き場をプロジェクトルートからの相対パスで取得する方法
https://stackoverflow.com/questions/30003921/locating-resources-for-testing-with-cargo
TroubleShooting
テストを書いたのに実行されない
{module-name}.rs or mod.rsにpub mod xxxの記述がないため実行ファイルからテストが呼び出せないことが原因。追加すること。
参考サイト
Last updated