--- description: 'Rustプログラミング言語のコーディング規約とベストプラクティス' applyTo: '**/*.rs' --- # Rustコーディング規約とベストプラクティス Rustコードを記述する際は慣用的なRustプラクティスとコミュニティ標準に従ってください。 これらの指針は[The Rust Book](https://doc.rust-lang.org/book/)、[Rust API Guidelines](https://rust-lang.github.io/api-guidelines/)、[RFC 430 naming conventions](https://github.com/rust-lang/rfcs/blob/master/text/0430-finalizing-naming-conventions.md)、および[users.rust-lang.org](https://users.rust-lang.org)の広範なRustコミュニティに基づいています。 ## 全般指針 - 常に可読性、安全性、保守性を優先する。 - 強い型付けを使用し、メモリ安全性のためRustの所有権システムを活用する。 - 複雑な関数をより小さく管理しやすい関数に分割する。 - アルゴリズム関連コードについては、使用したアプローチの説明を含める。 - 保守性の高い実践に沿ってコードを記述し、なぜその設計決定をしたのかの理由をコメントに含める。 - `Result`を使用してエラーを適切に処理し、意味のあるエラーメッセージを提供する。 - 外部依存関係については、その使用方法と目的を文書に記載する。 - [RFC 430](https://github.com/rust-lang/rfcs/blob/master/text/0430-finalizing-naming-conventions.md)に従った一貫した命名規則を使用する。 - 借用チェッカーのルールに従った慣用的、安全、効率的なRustコードを記述する。 - コードが警告なしでコンパイルされることを確保する。 ## 従うべきパターン - ロジックをカプセル化するためモジュール(`mod`)とパブリックインターフェース(`pub`)を使用する。 - `?`、`match`、または`if let`を使用してエラーを適切に処理する。 - シリアライゼーションには`serde`、カスタムエラーには`thiserror`または`anyhow`を使用する。 - サービスや外部依存関係を抽象化するためトレイトを実装する。 - `async/await`と`tokio`または`async-std`を使用して非同期コードを構造化する。 - 型安全性のためフラグや状態よりもenumを優先する。 - 複雑なオブジェクト作成にはビルダーを使用する。 - テスト可能性と再利用のためバイナリコードとライブラリコードを分離(`main.rs` vs `lib.rs`)。 - データ並列性とCPU集約的タスクには`rayon`を使用する。 - インデックスベースのループよりも、しばしばより高速で安全なイテレーターを使用する。 - 所有権が不要な場合、関数パラメーターには`String`ではなく`&str`を使用する。 - 不要なアロケーションを避けるため、借用とゼロコピー操作を優先する。 ### 所有権、借用、ライフタイム - 所有権転送が必要でない限り、クローンよりも借用(`&T`)を優先する。 - 借用したデータを変更する必要がある場合は`&mut T`を使用する。 - コンパイラーが推論できない場合にライフタイムを明示的に注釈する。 - 単一スレッドの参照カウンティングには`Rc`、スレッドセーフな参照カウンティングには`Arc`を使用する。 - 単一スレッドコンテキストでの内部可変性には`RefCell`、マルチスレッドコンテキストには`Mutex`または`RwLock`を使用する。 ## 避けるべきパターン - 絶対に必要でない限り`unwrap()`や`expect()`を使用しない—適切なエラーハンドリングを優先する。 - ライブラリコードでパニックを避ける—代わりに`Result`を返す。 - グローバルな可変状態に依存しない—依存性注入またはスレッドセーフなコンテナを使用する。 - 深くネストしたロジックを避ける—関数またはコンビネータでリファクタリングする。 - 警告を無視しない—CI中はエラーとして扱う。 - 必要で完全に文書化されていない限り`unsafe`を避ける。 - `clone()`を過度に使用しない、所有権転送が不要な場合はクローンではなく借用を使用する。 - 早すぎる`collect()`を避ける、実際にコレクションが必要になるまでイテレーターを遅延保持する。 - 不要なアロケーションを避ける—借用とゼロコピー操作を優先する。 ## コードスタイルとフォーマット - Rustスタイルガイドに従い、自動フォーマットには`rustfmt`を使用する。 - 可能な場合は行を100文字未満に保つ。 - 関数と構造体の文書は`///`を使用してアイテムの直前に配置する。 - `cargo clippy`を使用して一般的な間違いをキャッチし、ベストプラクティスを強制する。 ## エラーハンドリング - 回復可能なエラーには`Result`、回復不可能なエラーにのみ`panic!`を使用する。 - エラー伝播には`unwrap()`や`expect()`よりも`?`演算子を優先する。 - `thiserror`を使用してカスタムエラー型を作成するか、`std::error::Error`を実装する。 - 存在するかもしれないししないかもしれない値には`Option`を使用する。 - 意味のあるエラーメッセージとコンテキストを提供する。 - エラー型は意味があり適切に動作する(標準トレイトを実装)べきである。 - 関数の引数を検証し、無効な入力に対して適切なエラーを返す。 ## API設計ガイドライン ### 共通トレイトの実装 適切な場合は共通トレイトを積極的に実装: - `Copy`、`Clone`、`Eq`、`PartialEq`、`Ord`、`PartialOrd`、`Hash`、`Debug`、`Display`、`Default` - 標準変換トレイトを使用:`From`、`AsRef`、`AsMut` - コレクションは`FromIterator`と`Extend`を実装すべき - 注意:`Send`と`Sync`は安全な場合にコンパイラーによって自動実装される;`unsafe`コードを使用する場合を除き手動実装を避ける ### 型安全性と予測可能性 - 静的区別を提供するためnewtypeを使用 - 引数は型を通じて意味を伝えるべき;汎用的な`bool`パラメーターよりも特定の型を優先 - 真にオプションな値には適切に`Option`を使用 - 明確なレシーバーを持つ関数はメソッドであるべき - スマートポインターのみが`Deref`と`DerefMut`を実装すべき ### 将来性の確保 - 下流実装から保護するためsealed traitsを使用 - 構造体はプライベートフィールドを持つべき - 関数は引数を検証すべき - すべてのパブリック型は`Debug`を実装する必要がある ## テストと文書化 - `#[cfg(test)]`モジュールと`#[test]`アノテーションを使用して包括的な単体テストを記述する。 - テストするコードと並行してテストモジュールを使用する(`mod tests { ... }`)。 - 説明的なファイル名で`tests/`ディレクトリに統合テストを記述する。 - 各関数、構造体、enum、複雑なロジックに明確で簡潔なコメントを記述する。 - 関数には説明的な名前を付け、包括的な文書を含める。 - [API Guidelines](https://rust-lang.github.io/api-guidelines/)に従ってrustdoc(`///`コメント)ですべてのパブリックAPIを文書化する。 - `#[doc(hidden)]`を使用してパブリック文書から実装詳細を隠す。 - エラー条件、パニックシナリオ、安全性の考慮事項を文書化する。 - 例では非推奨の`try!`マクロや`unwrap()`ではなく`?`演算子を使用すべき。 ## プロジェクト構成 - `Cargo.toml`でセマンティックバージョニングを使用する。 - 包括的なメタデータを含める:`description`、`license`、`repository`、`keywords`、`categories`。 - オプション機能にはフィーチャーフラグを使用する。 - `mod.rs`または名前付きファイルを使用してコードをモジュールに整理する。 - `main.rs`または`lib.rs`を最小限に保つ - ロジックをモジュールに移動する。 ## 品質チェックリスト Rustコードを公開またはレビューする前に確認: ### 核心要件 - [ ] **命名**: RFC 430命名規則に従っている - [ ] **トレイト**: 適切な場所で`Debug`、`Clone`、`PartialEq`を実装 - [ ] **エラーハンドリング**: `Result`を使用し意味のあるエラー型を提供 - [ ] **文書化**: すべてのパブリックアイテムに例付きのrustdocコメント - [ ] **テスト**: エッジケースを含む包括的なテストカバレッジ ### 安全性と品質 - [ ] **安全性**: 不要な`unsafe`コードなし、適切なエラーハンドリング - [ ] **パフォーマンス**: イテレーターの効率的使用、最小限のアロケーション - [ ] **API設計**: 関数は予測可能、柔軟、型安全 - [ ] **将来性確保**: 構造体内のプライベートフィールド、適切な場所でのsealed traits - [ ] **ツール**: コードが`cargo fmt`、`cargo clippy`、`cargo test`を通過