awesome-copilot/instructions/rust.instructions_ja.md

9.3 KiB
Raw Blame History

description applyTo
Rustプログラミング言語のコーディング規約とベストプラクティス **/*.rs

Rustコーディング規約とベストプラクティス

Rustコードを記述する際は慣用的なRustプラクティスとコミュニティ標準に従ってください。

これらの指針はThe Rust BookRust API GuidelinesRFC 430 naming conventions、およびusers.rust-lang.orgの広範なRustコミュニティに基づいています。

全般指針

  • 常に可読性、安全性、保守性を優先する。
  • 強い型付けを使用し、メモリ安全性のためRustの所有権システムを活用する。
  • 複雑な関数をより小さく管理しやすい関数に分割する。
  • アルゴリズム関連コードについては、使用したアプローチの説明を含める。
  • 保守性の高い実践に沿ってコードを記述し、なぜその設計決定をしたのかの理由をコメントに含める。
  • Result<T, E>を使用してエラーを適切に処理し、意味のあるエラーメッセージを提供する。
  • 外部依存関係については、その使用方法と目的を文書に記載する。
  • RFC 430に従った一貫した命名規則を使用する。
  • 借用チェッカーのルールに従った慣用的、安全、効率的なRustコードを記述する。
  • コードが警告なしでコンパイルされることを確保する。

従うべきパターン

  • ロジックをカプセル化するためモジュール(mod)とパブリックインターフェース(pub)を使用する。
  • ?match、またはif letを使用してエラーを適切に処理する。
  • シリアライゼーションにはserde、カスタムエラーにはthiserrorまたはanyhowを使用する。
  • サービスや外部依存関係を抽象化するためトレイトを実装する。
  • async/awaittokioまたはasync-stdを使用して非同期コードを構造化する。
  • 型安全性のためフラグや状態よりもenumを優先する。
  • 複雑なオブジェクト作成にはビルダーを使用する。
  • テスト可能性と再利用のためバイナリコードとライブラリコードを分離(main.rs vs lib.rs)。
  • データ並列性とCPU集約的タスクにはrayonを使用する。
  • インデックスベースのループよりも、しばしばより高速で安全なイテレーターを使用する。
  • 所有権が不要な場合、関数パラメーターにはStringではなく&strを使用する。
  • 不要なアロケーションを避けるため、借用とゼロコピー操作を優先する。

所有権、借用、ライフタイム

  • 所有権転送が必要でない限り、クローンよりも借用(&T)を優先する。
  • 借用したデータを変更する必要がある場合は&mut Tを使用する。
  • コンパイラーが推論できない場合にライフタイムを明示的に注釈する。
  • 単一スレッドの参照カウンティングにはRc<T>、スレッドセーフな参照カウンティングにはArc<T>を使用する。
  • 単一スレッドコンテキストでの内部可変性にはRefCell<T>、マルチスレッドコンテキストにはMutex<T>またはRwLock<T>を使用する。

避けるべきパターン

  • 絶対に必要でない限りunwrap()expect()を使用しない—適切なエラーハンドリングを優先する。
  • ライブラリコードでパニックを避ける—代わりにResultを返す。
  • グローバルな可変状態に依存しない—依存性注入またはスレッドセーフなコンテナを使用する。
  • 深くネストしたロジックを避ける—関数またはコンビネータでリファクタリングする。
  • 警告を無視しない—CI中はエラーとして扱う。
  • 必要で完全に文書化されていない限りunsafeを避ける。
  • clone()を過度に使用しない、所有権転送が不要な場合はクローンではなく借用を使用する。
  • 早すぎるcollect()を避ける、実際にコレクションが必要になるまでイテレーターを遅延保持する。
  • 不要なアロケーションを避ける—借用とゼロコピー操作を優先する。

コードスタイルとフォーマット

  • Rustスタイルガイドに従い、自動フォーマットにはrustfmtを使用する。
  • 可能な場合は行を100文字未満に保つ。
  • 関数と構造体の文書は///を使用してアイテムの直前に配置する。
  • cargo clippyを使用して一般的な間違いをキャッチし、ベストプラクティスを強制する。

エラーハンドリング

  • 回復可能なエラーにはResult<T, E>、回復不可能なエラーにのみpanic!を使用する。
  • エラー伝播にはunwrap()expect()よりも?演算子を優先する。
  • thiserrorを使用してカスタムエラー型を作成するか、std::error::Errorを実装する。
  • 存在するかもしれないししないかもしれない値にはOption<T>を使用する。
  • 意味のあるエラーメッセージとコンテキストを提供する。
  • エラー型は意味があり適切に動作する(標準トレイトを実装)べきである。
  • 関数の引数を検証し、無効な入力に対して適切なエラーを返す。

API設計ガイドライン

共通トレイトの実装

適切な場合は共通トレイトを積極的に実装:

  • CopyCloneEqPartialEqOrdPartialOrdHashDebugDisplayDefault
  • 標準変換トレイトを使用:FromAsRefAsMut
  • コレクションはFromIteratorExtendを実装すべき
  • 注意:SendSyncは安全な場合にコンパイラーによって自動実装される;unsafeコードを使用する場合を除き手動実装を避ける

型安全性と予測可能性

  • 静的区別を提供するためnewtypeを使用
  • 引数は型を通じて意味を伝えるべき;汎用的なboolパラメーターよりも特定の型を優先
  • 真にオプションな値には適切にOption<T>を使用
  • 明確なレシーバーを持つ関数はメソッドであるべき
  • スマートポインターのみがDerefDerefMutを実装すべき

将来性の確保

  • 下流実装から保護するためsealed traitsを使用
  • 構造体はプライベートフィールドを持つべき
  • 関数は引数を検証すべき
  • すべてのパブリック型はDebugを実装する必要がある

テストと文書化

  • #[cfg(test)]モジュールと#[test]アノテーションを使用して包括的な単体テストを記述する。
  • テストするコードと並行してテストモジュールを使用する(mod tests { ... })。
  • 説明的なファイル名でtests/ディレクトリに統合テストを記述する。
  • 各関数、構造体、enum、複雑なロジックに明確で簡潔なコメントを記述する。
  • 関数には説明的な名前を付け、包括的な文書を含める。
  • API Guidelinesに従ってrustdoc///コメントですべてのパブリックAPIを文書化する。
  • #[doc(hidden)]を使用してパブリック文書から実装詳細を隠す。
  • エラー条件、パニックシナリオ、安全性の考慮事項を文書化する。
  • 例では非推奨のtry!マクロやunwrap()ではなく?演算子を使用すべき。

プロジェクト構成

  • Cargo.tomlでセマンティックバージョニングを使用する。
  • 包括的なメタデータを含める:descriptionlicenserepositorykeywordscategories
  • オプション機能にはフィーチャーフラグを使用する。
  • mod.rsまたは名前付きファイルを使用してコードをモジュールに整理する。
  • main.rsまたはlib.rsを最小限に保つ - ロジックをモジュールに移動する。

品質チェックリスト

Rustコードを公開またはレビューする前に確認

核心要件

  • 命名: RFC 430命名規則に従っている
  • トレイト: 適切な場所でDebugClonePartialEqを実装
  • エラーハンドリング: Result<T, E>を使用し意味のあるエラー型を提供
  • 文書化: すべてのパブリックアイテムに例付きのrustdocコメント
  • テスト: エッジケースを含む包括的なテストカバレッジ

安全性と品質

  • 安全性: 不要なunsafeコードなし、適切なエラーハンドリング
  • パフォーマンス: イテレーターの効率的使用、最小限のアロケーション
  • API設計: 関数は予測可能、柔軟、型安全
  • 将来性確保: 構造体内のプライベートフィールド、適切な場所でのsealed traits
  • ツール: コードがcargo fmtcargo clippycargo testを通過