問題
つぎのコードを実行するとどうなるでしょう。
package main
func main() {
hello := func() {
hello := func() {
print("hello")
}
hello()
}
hello()
}
A. hello
と出力される
B. hellohello
と出力される
C. コンパイルエラー
D. 実行時エラー(panic)
解答と解説
ここを開いてください
正解はAです。
4行目の変数hello(以下hello4)と、5行目の変数hello(以下hello5)は異なるスコープで定義されており、つまりは別の変数です。
8行目で呼び出されているのはhello5で、10行目で呼び出されているのはhello4です。
hello4のやっていることを整理すると、以下のようになります。
-
print("hello")
を呼び出す関数を変数hello(hello5)に代入する - 変数hello(hello5)を呼び出す
これを10行目で呼び出しているため、print("hello")
は一度だけ呼び出されるため、 hello
と出力されます。
同名の変数を再度宣言して代入することをシャドーイング(shadowing)と呼ぶそうです(Go固有ではなくプログラミング言語一般の用語)。
Effective GoのChannelsで少しだけ触れられています。
Goは変数名が短いことが多いためか、シャドーイングをよく見かける気がします。
明日へ続く