Goにおける変数のスコープとシャドーウィングのクイズです。
本当に基本的な内容なのでGoを触っていたら楽楽全問正解できるはず!
実務的ではない、というか実務でこの状況に遭遇するのはまずい気がします。
問題は以下を省略してメイン関数だけ書いてます。
package main
import "fmt"
前提確認
var n = 0
func main() {
fmt.Println(n)
}
出力は?
これがわからなければ基本からやり直そう解答(折りたたみ)
0
第一問
var n = 0
func main() {
n := 1
fmt.Println(n)
}
出力は?
まあこうなるよね。解答(折りたたみ)
1
第二問
var n = 0
func main() {
n := 1
fmt.Println(n)
printN()
}
func printN() {
fmt.Println(n)
}
出力は?
main関数内のnはグローバル変数のnとは別の変数になります。スコープはメイン関数だけなので、printN関数の中ではグローバル変数が参照されます。 というわけで一行目が1で二行目が0。解答(折りたたみ)
1
0
第三問
func main() {
n := 1
{
fmt.Println(n)
}
}
出力は?
中括弧のブロックはメイン関数の中なのでメイン関数で定義されたnを参照します。解答(折りたたみ)
1
第四問
func main() {
n := 1
{
n := 2
fmt.Println(n)
}
fmt.Println(n)
}
出力は?
シンプルなシャドーウィングです。解答(折りたたみ)
2
1
中括弧で囲われたブロック内ではnは2、main関数ではnは1。
第五問
func main() {
n := 1
for n := n + 1; n < n+2; n++ {
fmt.Println(n)
}
}
出力は?
(実行しないでください)
2以上の整数をえんえんと出力し続けます。解答(折りたたみ)
2
3
4
...
for文の条件式のうち、n := n + 1 //左がforのスコープ、右がmainスコープ
n < n + 2 //両方forのスコープ
n++ //forのスコープ
n < n + 2
は常に真なのでずっと出力が続きます。
最終問題
func main() {
n := 1
if n := n + 1; true {
fmt.Println(n)
n = n + 1
fmt.Println(n)
}
fmt.Println(n)
}
出力は?
軽く引っ掛けっぽい問題です。解答(折りたたみ)
2
3
1
if文の中のnは、if文だけのスコープになります。
それ故、5行目で書き換えてもmainスコープのnには影響を与えません。
終わりに
以上、いかがだったでしょうか?
ごくごく基本的なものだけ集めてみました。
真面目な話をすると、理由なく同じ変数名を別のスコープで使うのは可読性を下げるのでやめたほうがよいでしょう。
ありがとうございました!