10
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

GoクイズAdvent Calendar 2020

Day 5

Go Quiz: map

Last updated at Posted at 2020-12-04

以下のコードを実行すると何が出力されるでしょうか?

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. 11
  2. 13
  3. 31
  4. 33
回答と解説 「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)` の結果でわかります。それにも関わらず取り出せない、ブラックホールのような状態になっているわけです。
10
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?