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