シャドウイング(隠蔽)とは、内部のスコープで変数が外部のスコープにある同じ名前の変数を隠す("隠蔽する")ことです。Goでは、特にブロック内(if、for、switchなど)での変数宣言の構文 := による特徴のために、それが可能です。
x := 5 if true { x := 10 // このxは新しい変数で、このif内でのみ有効です fmt.Println(x) // 10 } fmt.Println(x) // 5、10ではありません
これは時には便利ですが、再宣言された変数が外部の変数と同じでないことを忘れると、よくエラーを引き起こします。
質問: "次のコードは何を出力しますか?"
x := 7 if true { x, y := 1, 2 fmt.Println(x, y) } fmt.Println(x)
回答:
if内では新しい変数xとyが宣言され、それらはifブロック内でのみ有効です。xは依然として外部変数であり、その値は変わりません。結論:
1 2
7
エピソード
シャドウイングによるリソースリーク: ファイル処理中にエラー変数を隠蔽する典型的なエラー。
f, err := os.Open("file.txt") if err != nil { return err } if err := f.Close(); err != nil { return err } // これは新しい変数errです!
:=演算子はブロック内でのみ新しい変数errを作成し、外部のerr変数は変更されません。外部の変数でエラー処理が期待されると、エラー情報が失われます。
エピソード
構造体のシャドウイング — 見えないバグ: 入れ子のブロック内で、開発者が同じ名前の構造体を再定義しました。その結果、ロジックの一部が内部バージョンで動作し、他の部分が外部バージョンで動作し、奇妙なバグやデータ損失を引き起こしました。
エピソード
シャドウイングによるループの計算破損:
自動化された申請処理システムにおいて、カウンターを増やすために := を使用し、ループ内に新しい変数が作成され増加したため、外部カウンターは変更されず、システムが申請を正しくカウントできず、重要な統計が過小評価されました。