項目29:Clippyに耳を傾けよう
https://effective-rust.com/clippy.html
LT;DR
Clippy の警告は出ない状態を保とう
Clippy は CI 上で動かそう
Clippy の警告のリスト を読もう
これにより、Rust らしい書き方を深く理解することができる
hr.icon
Clippy では、Rust の使い方に対して様々なカテゴリにわたって警告を発する
https://doc.rust-lang.org/stable/clippy/lints.html
正確さ(Correctness): よくあるプログラム上のエラーを警告する
Rust らしさ(Idiom): コードの構成が標準的な Rust のスタイルに従っていないと警告する
簡潔さ(Concision): よりコンパクトにコードを書く方法があれば指摘する
性能(Performance): 不要な処理やメモリ確保を避ける方法があれば提案する
読みやすさ(Readability): 人間にとって読みやすく、理解しやすように書き直す方法を提案する
e.g.
下記のコードは コンパイル できるが Clippy で操作するとエラーを吐く
code:rs
pub fn circle_area(radius: f64) -> f64 {
let pi = 3.14;
pi * radius * radius
}
code:sh
error: approximate value of f{32, 64}::consts::PI found
--> src/main.rs:2:14
|
2 | let pi = 3.14;
| ^^^^
|
= help: consider using the constant directly
= help: for further information visit ...
= note: #[deny(clippy::approx_constant)] on by default
エラーの通りに修正する
code:rs
pub fn circle_area(radius: f64) -> f64 {
std::f64::consts::PI * radius * radius
}
前述の通り、Clippy の警告には エラー内容を記述した Web ページのリンク が付与している
ページではそのコードがなぜ悪いかが記述されている
そのため、プログラマが自身のコードにも適用されるのか、されないのかを判断することができる
項目によっては 偽陽性 の可能性についても書かれている
Rust らしい書き方を深く理解したいなら、この一覧ページを読もう
もし、警告が自身のコードと関係が無いと判断した場合、#[allow(...)] で無効化することが可能
トップレベルで ! を追加して記述する(#![allow(...)])ことで、クレート全体を無効化することもできる
ただし、偽陽性であるかを議論するよりかは、リファクタリング するのに労力を費やしたほうが良い
コードを修正するにせよ、警告を無効にするにせよ、「コードに対してClippy の警告が出ないようにしよう」
これにより、新しい警告が出た場合に気がつくことができる
CI 上でも走らせるべきである(項目32:CIシステムを設定しよう)
Effective Rust ― Rustコードを改善し、エコシステムを最大限に活用するための35項目 の項目の多くが、Clippy によって検知できる
項目1:データ構造を表現するために型システムを用いよう#67582d7975d04f0000ce2503
引数に複数回 bool が現れるケース: fn_params_excessive_bools
構造体に複数回 bool が現れるケース: struct_excessive_books
項目3:OptionとResultに対してはmatchを用いずに変換しよう
Result から Option への不必要な変換があるケース: ok_expect
unwrap_or_default で書き換えられるケース: unwrap_or_default
エラーを呼び出し元に返さないケース: unwrap_in_result
項目5:型変換を理解しよう
From ではなく Into を実装しているケース: from_over_into
as を利用しているケース(warning.icon デフォルトでは無効)
from で回避できる as: cast_lossless
値を丸める 可能性がある as: cast_possible_truncation
ラップアラウンド する可能性がある as: cast_possible_wrap
精度 が低下する可能性がある as: cast_precision_loss
負のオーバーフロー する可能性がある as: cast_sign_loss
すべての as: as_conversions
項目8:参照型とポインタ型に慣れよう
ヒープ 上に確保された コレクション を Box で保持しているケース: box_collection
ヒープ上に確保されたコレクションの要素が Box で保持されているケース: vec_box
Box への参照を取得しているケース: borrowed_box
項目9:明示的なループの代わりにイテレータ変換を使用することを検討しよう
Iterator メソッドの組み合わせがより簡潔に書けるケース: 複数あるため省略
項目10:標準トレイトに習熟しよう
Ord と PartialOrd の実装が矛盾しているケース: derived_ord_xor_partial_ord
PartialEq::ne を実装しているケース: partial_ne_impl
デフォルト実装に委ねていない
項目13:デフォルト実装を用いて、実装しなければならないトレイトメソッドを最小限にしよう
Hash と Eq の実装が矛盾しているケース: derived_hash_with_manual_eq
Copy と Clone の実装が一致していないケース: expl_impl_clone_on_copy
項目18:Don't panic
panic! や expect などの関連メソッドを利用しているケース: 複数あるため省略
項目21:セマンティックバージョン(SemVer)を理解しよう
依存ライブラリのバージョンを * で指定しているケース: wildcard_dependencies
項目23:ワイルドカードインポートを避けよう
ワイルドカードインポート を利用しているケース: wildcard_imports
項目24:APIに型が登場する依存ライブラリは再エクスポートしよう / 項目25:依存グラフを管理しよう
同じクレートの複数のバージョンが依存グラフに現れているケース: multiple_crate_versions
項目26:忍び寄るフィーチャに注意しよう
否定的な feature 名(e.g. no_std や not_std)があるケース: negative_feature_names
あるクレートを使うことだけを明示する feature 名(e.g. use-crate-x や with-crate-x、crate-support)があるケース: redundant_feature_names
項目27:パブリックインターフェイスのドキュメントを書こう
ドキュメンテーションコメント に panic! に関する説明(#Panics セクション)がないケース: missing_panics_doc
unsafe に関する説明がないケース: missing_safety_doc / undocumented_unsafe_blocks
#Rust #Effective_Rust_―_Rustコードを改善し、エコシステムを最大限に活用するための35項目