以下のコードを実行すると何が出力されるでしょうか?
package main
import (
"fmt"
"math"
)
func main() {
a := map[float64]int{}
a[math.Acos(8)] = 1
a[math.Acos(8)] = 2
a[math.Acos(8)] = 3
i := 0
for range a {
i++
}
fmt.Println(i)
fmt.Println(len(a))
}
-
1
と 1
-
1
と 3
-
3
と 1
-
3
と 3
回答と解説
「4. `3` と `3`」が正解です。`math.Acos(8)` の結果は NaN (Not a Number) です。 `NaN` は特殊な浮動小数点の値で、どの値と `==` で比較しても、たとえ NaN 同士での比較でも、 false になります。 map のキーに NaN を指定すると、その値は過去に指定されたどのキーとも違う扱いになるので、毎度新しい値として代入されます。よって 3 回 NaN をキーにして値を代入した map は for-range ループは 3 回回りますし、 `len` 関数に対しても 3 を返します。よってどちらも `3` が表示されます。ちなみに、キーを NaN にした値は取り出せなくなります。たとえば一通り代入が終わったあとで `v, ok := a[math.Acos(8)]` とやっても、 `v` と `ok` は `0` と `false` になります。しかしながら蓄えた値は確かに存在していて、 `len` 関数の結果や `fmt.Printf("%v\n", a)` の結果でわかります。それにも関わらず取り出せない、ブラックホールのような状態になっているわけです。