go-declarations について
変数、定数、型の宣言と初期化を扱う Go 開発者向けスキルです。スコープ、リテラル、ゼロ値、宣言時のよくある問題について実践的な指針を示します。
主な機能
- 01var と := の使い分け
- 02関連する宣言のグループ化
- 03変数スコープとシャドーイングの管理
- 04構造体とマップの初期化
- 05複合リテラルと生文字列の書式
活用シーン
- 01ローカル変数とパッケージ変数の宣言方法を選択
- 02iota による列挙型風の定数設計
- 03構造体とマップの初期化を確認
- 04組み込み識別子の意図しないシャドーイングを防止
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cxuu/ golang-skills --skill go-declarationsインストール後、Claude Code で/go-declarationsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/INITIALIZATION.mdIOTA.mdLITERALS.mdSCOPE.mdSHADOWING.mdSTRUCTS.md詳細
Go の宣言と初期化
互換性:例では、Go 1.18 以降が必要な
anyを使用する場合があります。
リソースの振り分け
references/SCOPE.md-var、:=、if-init、変数のスコープを狭める方法を選ぶ際に参照します。references/IOTA.md- 定数や列挙型のような値を設計する際に参照します。references/INITIALIZATION.md- 構造体、マップ、ゼロ値、ポインターを初期化する際に参照します。references/LITERALS.md- 複合リテラルの書式や、フィールド名を指定する場合のトレードオフを確認する際に参照します。references/STRUCTS.md- 構造体を設計または初期化する際に参照します。references/SHADOWING.md- 宣言によって組み込み識別子や外側の変数がシャドーイングされる可能性がある場合に参照します。
クイックリファレンス:var と := の使い分け
| コンテキスト | 使用するもの | 例 |
|---|---|---|
| トップレベル | var(常に) | var _s = F() |
| 値を伴うローカル変数 | := | s := "foo" |
| ゼロ値のローカル変数(意図的な場合) | var | var filtered []int |
| 式と型が異なる場合 | 型を指定した var | var _e error = F() |
関連する宣言をグループ化する
関連する var、const、type は、かっこで囲んだブロックにまとめます。関連のない宣言は、別々のブロックに分けます。
// Bad
const a = 1
const b = 2
// Good
const (
a = 1
b = 2
)
関数内では、関連がなくても隣接する変数宣言をまとめます。
var (
caller = c.name
format = "json"
timeout = 5 * time.Second
)
定数と iota
列挙型はゼロ値が無効または未設定を表すよう、1 から始めます。
const (
Add Operation = iota + 1
Subtract
Multiply
)
デフォルトの動作が望ましい場合(例:LogToStdout)は、ゼロから始めます。
変数のスコープ
結果をエラーチェックでしか使用しない場合は、if-init を使ってスコープを制限します。
if err := os.WriteFile(name, data, 0644); err != nil {
return err
}
スコープを狭めることでネストが深くなる場合や、結果を if の外でも使用する場合は、スコープを狭めないでください。その関数内でしか使わない定数は、関数内に移動します。
構造体の初期化
- 常にフィールド名を使用します(
go vetによってチェックされます)。例外:フィールド数が 3 以下のテストテーブル。 - ゼロ値のフィールドは省略します — Go にデフォルト値を設定させます。
- ゼロ値の構造体には
varを使用します:user := User{}ではなくvar user User new(T)よりも&T{}を使用します:sptr := &T{Name: "bar"}
複合リテラルの書式
外部パッケージの型にはフィールド名を使用します。閉じかっこのインデントは、開始行に合わせます。スライス/マップのリテラルでは型名の繰り返しを省略します(gofmt -s)。
マップの初期化
| 状況 | 使用するもの | 例 |
|---|---|---|
| 後から値を追加する空のマップ | make(map[K]V) | m := make(map[string]int) |
| nil で宣言する場合 | var | var m map[string]int |
| 初期化時に固定のエントリーを指定する場合 | リテラル | m := map[string]int{"a": 1} |
make() を使うと、初期化済みの空のマップと nil のマップを視覚的に区別できます。件数がわかっている場合は、サイズのヒントを指定します。
生文字列リテラル
手動で文字をエスケープせずに済むよう、バッククォート文字列を使用します。
// Bad
wantError := "unknown name:\"test\""
// Good
wantError := `unknown name:"test"`
正規表現、SQL、JSON、複数行のテキストに最適です。
interface{} より any を優先する
Go 1.18 以降では、新しいコードすべてで interface{} の代わりに any を使用します。
組み込みの名前のシャドーイングを避ける
事前宣言済み識別子(error、string、len、cap、append、
copy、new、make、close、delete、panic、recover、any、true、
false、nil、iota)を名前として使用しないでください。検出には go vet を使用します。
// Bad — shadows the builtin
var error string
// Good
var errorMessage string
関連するスキル
- 命名規則:変数名や定数名を選ぶ場合、またはスコープに応じて名前の長さを決める場合は、go-naming を参照してください
- データ構造:
newとmakeのどちらを使うか選ぶ場合、またはスライスやマップを初期化する場合は、go-data-structures を参照してください - 制御フローのスコープ:if-init や
:=による再宣言を使う場合、または変数のシャドーイングを避ける場合は、go-control-flow を参照してください - 容量のヒント:サイズがわかっているマップやスライスを事前に確保する場合は、go-performance を参照してください