在golang中,什么类型才可以作为map key? 在golang官方博客中找到以下说明:
As mentioned earlier, map keys may be of any type that is comparable. The language spec defines this precisely, but in short, comparable types are boolean, numeric, string, pointer, channel, and interface types, and structs or arrays that contain only those types. Notably absent from the list are slices, maps, and functions; these types cannot be compared using ==, and may not be used as map keys.
map key 必须是可比较的类型,语言规范中定义了可比较的类型:boolean, numeric, string, pointer, channel, interface, 以及仅包含这些类型的struct和array 。不能作为map key的类型有:slice,map, function。
在这里看出,array具有可比较性,可以作为map key,而slice不具有可比较性,所以不能作为map key。那这又是为什么?
- array
a0 := [3]int{1,2,3}
a1 := a0
a1[0] = 0
array是值类型,不同的array不会相互影响。对a1修改不会影响到a0。
- slice
s0 := []int{1,2,3}
s1 := s0
s1[0] = 0
slice指向底层的array,两个不同的slice可能指向同一个底层array。对s1修改会影响到s0,
对于array,只有元素层面的相等性。对于slice,却不止一种方式去定义相等性。一是元素层面的相等,二是指向底层的相同array的相等。进一步,在map中插入元素,没必要复制slice底层所指向的array,这样的操作很昂贵。
m := make(map[[]int]bool)
s0 := []int{6, 7, 8}
s1 := []int{6, 7, 8}
s2 := s0
m[s0] = true
s2[0] = 9
println(m[s0])
println(m[s1])
println(m[s2])
对于这段代码,不同的开发人员,会有不同的解释。为了避免困惑,golang就禁止slice作为map key。