在C++ STL中,只有empty map, 没有NULL map, 但是, 在go中,既有empty map, 又有nil map. 为什么要怎么搞? 在我看来, 完全没有必要搞个nil map, 所有的map应该都是直接自动初始化为empty map. 既然go设计者这个搞了, 自然有他们的理由, 我不认同, 但没有什么卵用。
来看看go圣经怎么说:The zero value for a map type is nil, that is, a reference to no hash table at all. 这个nil map是不能添加元素的, 必须进行初始化才可以。 既然如此, 何不默认初始化为empty map呢? 不解!
对C++的NULL进行操作,总是让人提醒吊胆, 那么在nil map上操作, 会怎样呢? 继续看go圣经: Most operations on maps, including lookup, delete, len, and range loops, are safe to perform on a nil map reference, since it behaves like an emtpy map. But storing to a nil map cause a panic.
最后来看:
package main
import (
"fmt"
)
func main(){
var a []int
if a == nil {
fmt.Println("it is nil, 1")
}else{
fmt.Println("it not not nil, 1")
}
fmt.Println("slice len1 is", len(a))
a = make([]int, 0) // 不必要
if a == nil {
fmt.Println("it is nil, 2")
}else{
fmt.Println("it not not nil, 2")
}
fmt.Println("slice len2 is", len(a))
a = append(a, 1)
var m map[int]int
if m == nil {
fmt.Println("it is nil, 3")
}else{
fmt.Println("it not not nil, 3")
}
fmt.Println("map len3 is", len(m))
m = make(map[int]int, 0) // 必要,否则panic
if m == nil {
fmt.Println("it is nil, 4")
}else{
fmt.Println("it not not nil, 4")
}
fmt.Println("map len4 is", len(m))
m[1] = 10
fmt.Println(a, m)
}
结果:
it is nil, 1
slice len1 is 0
it not not nil, 2
slice len2 is 0
it is nil, 3
map len3 is 0
it not not nil, 4
map len4 is 0
[1] map[1:10]
由此可见:
对于nil slice而言, 爱咋地咋地, append和len都可以.
对于nil map而言, 不能直接赋值, 但仍可以用len. 真是个鸡肋。
对于empty slice而言, 爱咋地咋地, append和len都可以.
对于empty map而言, 爱咋地咋地, append和len都可以.