go-style-core について
go-style-coreは、読みやすいGoコードを書くための優先順位付きガイドです。スタイルの統一や保守性を重視する開発者向けに、フォーマット、制御フロー、戻り値の慣習を扱います。
主な機能
- 01優先順位に沿ったスタイル原則
- 02gofmtと意味に沿った改行の指針
- 03ネストや不要な分岐を減らす方法
- 04裸のreturnの適用範囲
活用シーン
- 01読みやすいGoコードの作成
- 02フォーマットと制御フローのレビュー
- 03スタイル原則間の判断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cxuu/ golang-skills --skill go-style-coreインストール後、Claude Code で/go-style-coreを入力して読み込まれたか確認します。
同梱ファイルreferences/FORMATTING.mdreferences/PRINCIPLES.md
詳細
Go スタイルの基本原則
リソースの参照先
references/PRINCIPLES.md- 明確さ、シンプルさ、簡潔さ、保守性、一貫性の間で判断に迷ったときに読みます。references/FORMATTING.md- gofmt、改行、空白、コメント、セミコロンを扱うときに読みます。
スタイル原則(優先順位順)
読みやすい Go コードを書くときは、重要度の高い順に次の原則を適用します。
優先順位
- 明確さ — 読者は余計な背景情報なしにコードを理解できますか?
- シンプルさ — 目的を達成する最もシンプルな方法ですか?
- 簡潔さ — すべての行に意味がありますか?
- 保守性 — 後から簡単に変更できますか?
- 一貫性 — 周囲のコードやプロジェクトの規約に沿っていますか?
フォーマット
例外なく gofmt を実行してください。厳密な行長制限はありませんが、Uber は 99 文字を目安としています。行の長さではなく意味のまとまりで改行し、単に折り返すのではなくリファクタリングしてください。
ネストを減らす
まずエラーケースや特別な条件を処理します。早期リターンするか、ループを継続して、「通常の処理経路」のインデントを浅く保ちます。
// Bad: Deeply nested
for _, v := range data {
if v.F1 == 1 {
v = process(v)
if err := v.Call(); err == nil {
v.Send()
} else {
return err
}
} else {
log.Printf("Invalid v: %v", v)
}
}
// Good: Flat structure with early returns
for _, v := range data {
if v.F1 != 1 {
log.Printf("Invalid v: %v", v)
continue
}
v = process(v)
if err := v.Call(); err != nil {
return err
}
v.Send()
}
不要な else
if の両方の分岐で変数に値を設定する場合は、デフォルト値を設定してから上書きするパターンを使います。
// Bad: Setting in both branches
var a int
if b {
a = 100
} else {
a = 10
}
// Good: Default + override
a := 10
if b {
a = 100
}
Naked return
引数なしの return ステートメントは、名前付き戻り値を返します。
これは「naked return」と呼ばれます。
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return // returns x, y
}
Naked return のガイドライン
- 短い関数では問題ありません:数行程度の関数では、naked return を使ってもかまいません
- 中規模以上の関数では明示します:関数が中規模になったら、わかりやすさのために戻り値を明示してください
- naked return のためだけに戻り値に名前を付けないでください:1、2 行を節約することより、ドキュメントの明確さが常に重要です
// Good: Small function, naked return is clear
func minMax(a, b int) (min, max int) {
if a < b {
min, max = a, b
} else {
min, max = b, a
}
return
}
// Good: Larger function, explicit return
func processData(data []byte) (result []byte, err error) {
result = make([]byte, 0, len(data))
for _, b := range data {
if b == 0 {
return nil, errors.New("null byte in data")
}
result = append(result, transform(b))
}
return result, nil // explicit: clearer in longer functions
}
名前付き戻り値パラメーターについては、go-documentation を参照してください。
セミコロン
Go の字句解析器は、行の最後のトークンが識別子、リテラル、または次のいずれかの場合、その行の後にセミコロンを自動的に挿入します:break continue fallthrough return ++ -- ) }。
つまり、開始波括弧は制御構造と同じ行に置く必要があります。
// Good: brace on same line
if i < f() {
g()
}
// Bad: brace on next line — lexer inserts semicolon after f()
if i < f() // wrong!
{ // wrong!
g()
}
慣用的な Go で明示的なセミコロンを使うのは、for ループの節と、1 行に複数の文を記述する際の区切りだけです。
クイックリファレンス
| 原則 | 主な問い |
|---|---|
| 明確さ | 読者は何をするコードか、なぜそうするのかを理解できますか? |
| シンプルさ | 最もシンプルな方法ですか? |
| 簡潔さ | 情報とノイズの比率は高いですか? |
| 保守性 | 後から安全に変更できますか? |
| 一貫性 | 周囲のコードに沿っていますか? |
関連スキル
- 命名規則:MixedCaps を適用するとき、識別子名を選ぶとき、または命名について議論するときは、go-naming を参照してください
- エラーフロー:エラー優先のガード節を構成するとき、または早期リターンでネストを減らすときは、go-error-handling を参照してください
- ドキュメント:ドキュメントコメント、名前付き戻り値パラメーター、またはパッケージレベルのドキュメントを書くときは、go-documentation を参照してください
- リンティングの適用:golangci-lint でスタイルチェックを自動化するとき、または CI を設定するときは、go-linting を参照してください
- コードレビュー:体系的なコードレビューでスタイル原則を適用するときは、go-code-review を参照してください
- ロギングのスタイル:ロギングの慣行を見直すとき、log と slog のどちらを使うか選ぶとき、またはログ出力を構成するときは、go-logging を参照してください