golang-style について
golang-styleは、Goコードを書く際の規約をまとめたSkillです。エラー処理、命名、コメント、コード構成、ドキュメントの参照方法を扱います。
主な機能
- 01Goの格言と規約に従う
- 02エラーに適切な文脈を付与
- 03事前宣言識別子の名前利用を回避
- 04コメントと行長のルール
- 05go docでドキュメントを参照
活用シーン
- 01Goプロジェクトのコードスタイル統一
- 02操作の文脈を含むエラー処理
- 03Goの命名やコメントの確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ fredrikaverpil/ dotfiles --skill golang-styleインストール後、Claude Code で/golang-styleを入力して読み込まれたか確認します。
詳細
Go コーディング規約
格言
次の格言に従うよう努めてください。
Go の格言 シンプルに、詩的に、簡潔に メモリを共有して通信するのではなく、通信してメモリを共有しましょう。 並行性は並列性ではありません。 チャネルはオーケストレーションし、ミューテックスはシリアライズします。 インターフェースは大きくなるほど、抽象化として弱くなります。 ゼロ値を有用なものにしましょう。 interface{} は何も語りません。 gofmt のスタイルを気に入る人はいませんが、gofmt を気に入らない人もいません。 少しのコピーは、少しの依存よりも優れています。 Syscall は必ずビルドタグで保護しなければなりません。 Cgo は必ずビルドタグで保護しなければなりません。 Cgo は Go ではありません。 unsafe パッケージには保証がありません。 明快さは巧妙さに勝ります。 リフレクションは決して明快ではありません。 エラーは値です。 エラーをチェックするだけでなく、適切に処理しましょう。 アーキテクチャを設計し、コンポーネントに名前を付け、詳細をドキュメント化しましょう。 ドキュメントはユーザーのためのものです。 panic を使ってはいけません。
Go コードを書く際は、これらの規約に厳密に従ってください。
ハッピーパスコーディング
成功する処理の流れがまっすぐ下へ進むようにコードを構成してください。エラーは すぐに処理し、その後、主なロジックを続けます。
// Correct: happy path flows down.
func ProcessUser(id string) (*User, error) {
user, err := db.GetUser(id)
if err != nil {
return nil, fmt.Errorf("get user %s: %w", id, err)
}
if err := user.Validate(); err != nil {
return nil, fmt.Errorf("validate user %s: %w", id, err)
}
return user, nil
}
// Wrong: main logic nested inside conditions.
func ProcessUser(id string) (*User, error) {
user, err := db.GetUser(id)
if err == nil {
if err := user.Validate(); err == nil {
return user, nil
} else {
return nil, err
}
}
return nil, err
}
エラーのラップ
常に %w を使って、コンテキストを付けてエラーをラップしてください。操作と関連する
識別子を含めます。
// Correct: wrapped with context.
if err != nil {
return fmt.Errorf("create order for customer %s: %w", customerID, err)
}
// Wrong: no context.
if err != nil {
return err
}
センチネルエラー
想定されるエラー条件に対して、パッケージレベルのセンチネルエラーを定義してください。
確認には errors.Is() を使います。
// Define at package level.
var (
ErrNotFound = errors.New("not found")
ErrUnauthorized = errors.New("unauthorized")
ErrInvalidInput = errors.New("invalid input")
)
// Return sentinel errors.
func GetUser(id string) (*User, error) {
user := db.Find(id)
if user == nil {
return nil, ErrNotFound
}
return user, nil
}
// Check with errors.Is().
user, err := GetUser(id)
if errors.Is(err, ErrNotFound) {
// Handle not found case.
}
コメント
すべてのコメントはピリオドで終わらせてください。
// ProcessOrder handles order creation and validation.
func ProcessOrder(o *Order) error {
// Validate the order before processing.
if err := o.Validate(); err != nil {
return err
}
// Continue with order processing.
return nil
}
命名規則
Go の事前宣言済み識別子を変数名やパラメーター名に使わないでください。これらには、 シャドーイング可能でも使うべきではない組み込み関数や定数が含まれます。
// Wrong: shadows built-in identifiers.
func process(new string, len int, make bool) error {
copy := "data"
return nil
}
// Correct: use descriptive names instead.
func process(name string, length int, shouldCreate bool) error {
dataCopy := "data"
return nil
}
避けるべき事前宣言済み識別子:
- 関数:
new、make、len、cap、append、copy、delete、close、panic、recover、print、println、complex、real、imag、clear、min、max - 定数:
true、false、iota、nil - 型:
error、bool、string、int、int8、int16、int32、int64、uint、uint8、uint16、uint32、uint64、uintptr、float32、float64、complex64、complex128、byte、rune、any、comparable
行の長さ
最大行長は 120 文字です。長い行は論理的な区切りで改行してください。
// Correct: break at logical points.
func ProcessOrderWithValidation(
ctx context.Context,
order *Order,
validator OrderValidator,
) (*Result, error) {
return nil, fmt.Errorf(
"process order %s for customer %s: %w",
order.ID,
order.CustomerID,
err,
)
}
ドキュメントの参照
標準ライブラリやパッケージのドキュメントを調べるには、go doc を使ってください。
go doc fmt.Errorf
go doc errors.Is
go doc context
Einride
プロジェクトが Einride 組織に属している場合は、必ずプロジェクト内の、Sage(.sage フォルダー)によって生成された Makefiles を使ってください。