GoでArrayやSliceの各要素に対して、何かしようとするときにfor range
を使いますよね
例えばこんな感じ
words := []string{"hoge", "fuga", "foo", "bar"}
for word := range words {
// do something
}
でも、これだとword
には、hoge
やらfuga
が入らず数値が入ってくる。
for word := range words {
fmt.Println(word)
}
> go run main.go
0
1
2
3
なぜかと言うと、これword
にはインデックス値が入ってきているから。
要素の値を取りたければ、rangeの左辺に変数を2つ置けばOK
for _, word := range words {
fmt.Println(word)
}
> go run main.go
hoge
fuga
foo
bar
冷静に考えれば当たり前のことなんですが、左辺に変数が1つだけでもコンパイル時にエラーにならないから、気付きづらい。他の言語で言うところのforeach感覚で書いてると良くやってしまう。
で、なぜこうなるかというと、range
が返す2番目の値はオプショナルだから。
さらに言うと、1番目と2番目それぞれに入ってくる値がそれぞれ何なのかは、range
の対象が何か?で変わってくるので要注意です。
詳しくはgithubのwiki、Range#Referenceを見ると良いと思います。
オプショナルだからとか言わず、いっそコンパイルで警告してくれたらなーとか、個人的には思ったりしたんですが、慣れの問題なんでしょうね。気をつけよう。