awesome-copilot/instructions/go.instructions_ja.md

292 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
description: '慣用的なGoプラクティスとコミュニティ標準に従ったGoコード記述の指針'
applyTo: '**/*.go,**/go.mod,**/go.sum'
---
# Go開発指針
Goコードを書く際は慣用的なGoプラクティスとコミュニティ標準に従ってください。これらの指針は[Effective Go](https://go.dev/doc/effective_go)、[Go Code Review Comments](https://go.dev/wiki/CodeReviewComments)、[GoogleのGoスタイルガイド](https://google.github.io/styleguide/go/)に基づいています。
## 全般指針
- シンプルで明確、慣用的なGoコードを記述
- 巧妙さよりも明確性とシンプルさを優先
- 最小驚きの原則に従う
- ハッピーパスを左寄せにする(インデントを最小化)
- ネストを減らすため早期リターンを使用
- ゼロ値を有用にする
- エクスポートされた型、関数、メソッド、パッケージを文書化
- 依存関係管理にはGoモジュールを使用
## 命名規則
### パッケージ
- 小文字の単語でパッケージ名を使用
- アンダースコア、ハイフン、mixedCapsを避ける
- パッケージが何を含むかではなく、何を提供するかを説明する名前を選択
- `util``common``base`などの汎用的な名前を避ける
- パッケージ名は複数形ではなく単数形にする
### 変数と関数
- アンダースコアではなくmixedCapsまたはMixedCapscamelCaseを使用
- 短いが説明的な名前を維持
- 単文字変数は非常に短いスコープ(ループインデックスなど)でのみ使用
- エクスポートされた名前は大文字で始まる
- エクスポートされていない名前は小文字で始まる
- 重複を避ける(例:`http.HTTPServer`を避け、`http.Server`を使用)
### インターフェース
- 可能な場合はインターフェース名に-er接尾辞を使用`Reader``Writer``Formatter`
- 単一メソッドインターフェースはメソッド名で命名(例:`Read``Reader`
- インターフェースは小さく焦点を絞って維持
### 定数
- エクスポートされた定数にはMixedCapsを使用
- エクスポートされていない定数にはmixedCapsを使用
- 関連する定数は`const`ブロックでグループ化
- より良い型安全性のため型付き定数を検討
## コードスタイルとフォーマット
### フォーマット
- コードのフォーマットには常に`gofmt`を使用
- インポートの自動管理には`goimports`を使用
- 行の長さを適度に保つ(厳格な制限はないが、可読性を考慮)
- 論理的なコードグループを分離するため空行を追加
### コメント
- 完全な文でコメントを記述
- 説明される対象の名前で文を開始
- パッケージコメントは「Package [name]」で開始
- ほとんどのコメントには行コメント(`//`)を使用
- ブロックコメント(`/* */`)は控えめに使用、主にパッケージ文書化用
- 何をするかではなく、なぜするかを文書化(何が複雑でない限り)
### エラーハンドリング
- 関数呼び出しの直後にエラーをチェック
- 良い理由がない限り`_`を使ってエラーを無視しない(理由を文書化)
- `fmt.Errorf``%w`動詞を使用してコンテキストでエラーをラップ
- 特定のエラーをチェックする必要がある場合はカスタムエラー型を作成
- エラー戻り値を最後の戻り値として配置
- エラー変数は`err`と命名
- エラーメッセージは小文字で、句読点で終わらない
## アーキテクチャとプロジェクト構造
### パッケージ構成
- 標準Go プロジェクトレイアウト規則に従う
- `main`パッケージは`cmd/`ディレクトリに保持
- 再利用可能なパッケージは`pkg/`または`internal/`に配置
- 外部プロジェクトにインポートされるべきでないパッケージには`internal/`を使用
- 関連機能をパッケージにグループ化
- 循環依存関係を避ける
### 依存関係管理
- Goモジュール`go.mod``go.sum`)を使用
- 依存関係を最小限に保つ
- セキュリティパッチのため定期的に依存関係を更新
- `go mod tidy`を使用して未使用の依存関係をクリーンアップ
- 必要な場合のみ依存関係をベンダー化
## 型安全性と言語機能
### 型定義
- 意味と型安全性を追加するため型を定義
- JSON、XML、データベースマッピングには構造体タグを使用
- 明示的な型変換を優先
- 型アサーションは慎重に使用し、第二戻り値をチェック
### ポインターvs値
- 大きな構造体またはレシーバーを変更する必要がある場合はポインターを使用
- 小さな構造体とイミュータビリティが望ましい場合は値を使用
- 型のメソッドセット内で一貫性を保つ
- ポインターvs値レシーバーを選択する際はゼロ値を考慮
### インターフェースと合成
- インターフェースを受け入れ、具象型を返す
- インターフェースを小さく保つ1〜3メソッドが理想的
- 合成には埋め込みを使用
- 実装される場所ではなく使用される場所の近くでインターフェースを定義
- 必要でない限りインターフェースをエクスポートしない
## 並行性
### ゴルーチン
- ライブラリでゴルーチンを作成しない;呼び出し元に並行性を制御させる
- ゴルーチンがどのように終了するかを常に知る
- ゴルーチンを待つために`sync.WaitGroup`またはチャネルを使用
- クリーンアップを確実に行うことでゴルーチンリークを避ける
### チャネル
- ゴルーチン間の通信にはチャネルを使用
- メモリを共有して通信するのではなく、通信してメモリを共有する
- 受信側ではなく送信側からチャネルを閉じる
- 容量が分かっている場合はバッファードチャネルを使用
- 非ブロッキング操作には`select`を使用
### 同期
- 共有状態の保護には`sync.Mutex`を使用
- クリティカルセクションを小さく保つ
- 多くの読み手がいる場合は`sync.RWMutex`を使用
- 可能な場合はミューテックスよりもチャネルを優先
- 一度だけの初期化には`sync.Once`を使用
## エラーハンドリングパターン
### エラー作成
- シンプルな静的エラーには`errors.New`を使用
- 動的エラーには`fmt.Errorf`を使用
- ドメイン固有のエラーにはカスタムエラー型を作成
- センチネルエラーにはエラー変数をエクスポート
- エラーチェックには`errors.Is``errors.As`を使用
### エラー伝播
- スタックを上に伝播する際にコンテキストを追加
- エラーをログして返す(どちらか一方を選択)
- 適切なレベルでエラーを処理
- より良いデバッグのため構造化エラーの使用を検討
## API設計
### HTTPハンドラー
- シンプルなハンドラーには`http.HandlerFunc`を使用
- 状態が必要なハンドラーには`http.Handler`を実装
- 横断的関心事にはミドルウェアを使用
- 適切なステータスコードとヘッダーを設定
- エラーを適切に処理し、適切なエラーレスポンスを返す
### JSON API
- JSONマーシャリングを制御するため構造体タグを使用
- 入力データを検証
- オプションフィールドにはポインターを使用
- 遅延解析のため`json.RawMessage`の使用を検討
- JSONエラーを適切に処理
## パフォーマンス最適化
### メモリ管理
- ホットパスでのアロケーションを最小化
- 可能な場合はオブジェクトを再利用(`sync.Pool`を検討)
- 小さな構造体には値レシーバーを使用
- サイズが分かっている場合はスライスを事前割り当て
- 不要な文字列変換を避ける
### プロファイリング
- 組み込みプロファイリングツール(`pprof`)を使用
- 重要なコードパスをベンチマーク
- 最適化前にプロファイル
- まずアルゴリズムの改善に焦点を当てる
- ベンチマークには`testing.B`の使用を検討
## テスト
### テスト構成
- テストは同じパッケージに保持(ホワイトボックステスト)
- ブラックボックステストには`_test`パッケージ接尾辞を使用
- テストファイルは`_test.go`接尾辞で命名
- テストファイルはテスト対象コードの隣に配置
### テスト記述
- 複数のテストケースにはテーブル駆動テストを使用
- `Test_functionName_scenario`を使って説明的にテストを命名
- より良い構成のため`t.Run`でサブテストを使用
- 成功ケースとエラーケースの両方をテスト
- `testify`や類似のライブラリは控えめに使用
### テストヘルパー
- ヘルパー関数に`t.Helper()`をマーク
- 複雑なセットアップにはテストフィクスチャを作成
- テストとベンチマークで使用される関数には`testing.TB`インターフェースを使用
- `t.Cleanup()`を使ってリソースをクリーンアップ
## セキュリティベストプラクティス
### 入力検証
- すべての外部入力を検証
- 無効な状態を防ぐため強い型付けを使用
- SQLクエリで使用する前にデータをサニタイズ
- ユーザー入力からのファイルパスに注意
- 異なるコンテキストHTML、SQL、シェルのためデータを検証・エスケープ
### 暗号化
- 標準ライブラリのcryptoパッケージを使用
- 独自の暗号化を実装しない
- 乱数生成にはcrypto/randを使用
- bcryptまたは類似を使用してパスワードを保存
- ネットワーク通信にはTLSを使用
## 文書化
### コード文書化
- すべてのエクスポートされたシンボルを文書化
- シンボル名で文書化を開始
- 有用な場合は文書化に例を使用
- 文書をコードの近くに保持
- コード変更時に文書を更新
### READMEと文書化ファイル
- 明確なセットアップ指示を含める
- 依存関係と要件を文書化
- 使用例を提供
- 設定オプションを文書化
- トラブルシューティングセクションを含める
## ツールと開発ワークフロー
### 必須ツール
- `go fmt`: コードフォーマット
- `go vet`: 疑わしい構造を発見
- `golint`または`golangci-lint`: 追加リンティング
- `go test`: テスト実行
- `go mod`: 依存関係管理
- `go generate`: コード生成
### 開発プラクティス
- コミット前にテストを実行
- フォーマットとリンティングにプリコミットフックを使用
- コミットを焦点を絞ってアトミックに保つ
- 意味のあるコミットメッセージを記述
- コミット前に差分をレビュー
## 避けるべき一般的な落とし穴
- エラーをチェックしない
- 競合状態を無視する
- ゴルーチンリークを作成
- クリーンアップにdeferを使用しない
- マップを同時変更
- nilインターフェースvsポインターを理解していない
- リソース(ファイル、接続)を閉じるのを忘れる
- グローバル変数を不必要に使用
- 空インターフェース(`interface{}`)を過度に使用
- 型のゼロ値を考慮しない