Go言語のブロックとスコープ
2026/07/28

ブロック

ブロックは宣言と文のグループです。波括弧{ }で囲みます。関数本体、制御構文の本体、ifの初期化文を含む全体などがブロックを形成します。

スコープ

識別子は宣言されたブロックとその内側のブロックで有効です。内側のブロックで同名を宣言すると、外側の名前はそのブロック内では隠れます。

x := 1
{
    x := 2
    fmt.Println(x) // 2
}
fmt.Println(x) // 1

再宣言と:=

:=は、左辺に少なくとも1つ新しい変数があるときに使います。すでにそのブロックで宣言されている名前には代入され、それ以外は新たに宣言されます。

x, y := 1, 2
x, z := 3, 4 // xは代入、zは新規

ブランク識別子

_はブランク識別子です。主な用途は次の3つです。

  1. 値の破棄: _, err := do()
  2. 副作用のみのimport: import _ "image/png"
  3. コンパイル時の型チェック: var _ io.Reader = (*MyType)(nil)

未使用importはコンパイルエラーです。_でimportすると、パッケージのinitだけが実行され、名前は使いません。

ラベルのスコープ

ラベルは、Outer:のように文の前に付ける名前です。入れ子のループで外側へ抜けるときはbreak Outer、外側ループの次の反復へ進むときはcontinue Outerと書きます。gotoの飛び先にも使います。

Outer:
for i := 0; i < 3; i++ {
    for j := 0; j < 3; j++ {
        if j == 1 {
            continue Outer // 内側を抜け、外側ループの次のiへ
        }
    }
}
i := 0
Again:
    fmt.Println(i)
    i++
    if i < 3 {
        goto Again
    }

ラベルはそれを含む関数内でのみ有効です。別の関数のラベルには飛べません。