ローカル変数のスコープ

関数は変数のスコープを作るので、引数や関数内で宣言された変数はその関数内だけで有効なローカル変数になる。
ほかにも {} でブロックを作ってやると、そのブロックは新しいスコープを作ってブロック内で宣言された変数はブロック内だけで有効になる。例えば、次の例がわかりやすいだろう。

package main

import "fmt"

func main() {
    x := 1
    {
        y := 2
        {
            z := 3
            fmt.Println(x)
            fmt.Println(y)
            fmt.Println(z)
        }
        fmt.Println(x)
        fmt.Println(y)
    // fmt.Println(z) z はスコープ外(コンパイルエラー)
    }
    fmt.Println(x)
    // fmt.Println(y) y はスコープ外(コンパイルエラー)
    // fmt.Println(z) z はスコープ外(コンパイルエラー)
}

注意が必要なのは、if 文なども新しいスコープを作るので、次の例はエラーになってしまう。

package main

import "fmt"

func main() {
    a := 10

    if a > 5 {
        b := "Yes"
    } else {
        b := "No"
    }

    fmt.Println(b)
}
^o^ > go run var_local2.go
# command-line-arguments
.\var_local2.go:14: undefined: b

b を出力しようとしているところで、b が定義されていないと怒られている。これを避けるためには、先に b を宣言しておく。

package main

import "fmt"

func main() {
    a := 10
    var b string

    if a > 5 {
        b = "Yes"
    } else {
        b = "No"
    }

    fmt.Println(b)
}
^o^ > go run var_local3.go
Yes