When you declare a map when:
m := make(map[int]int)
The compiler will call runtime.makemap
:
// makemap implements a Go map creation make(map[k]v, hint)
// If the compiler has determined that the map or the first bucket
// can be created on the stack, h and/or bucket may be non-nil.
// If h != nil, the map can be created directly in h.
// If bucket != nil, bucket can be used as the first bucket.
func makemap(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap
So actually it returns a pointer to the hmap.
How to verify it?
func main(){
m := make(map[int]int)
m[1] = 1
fmt.Printf("原始map的内存地址是:%p\n", m)
modify(m)
fmt.Println("map值被修改了,新值为:", m)
}
func modify(m interface{}){
fmt.Printf("函数里接收到map的内存地址是:%p\n", p)
m := p.(map[int]int)
m[1] = 2
}
Output:
原始map的内存地址是:0xc00009e030
函数里接收到map的内存地址是:0xc00009e030
map值被修改了,新值为: map[1:2]
In the main function, m is a pointer variable, its value is saved: 0xc00009e030.
Modify the function, m is a pointer variable, the stored value is: 0xc00009e030.
Description Initializes the map, the return is a pointer variable, between functions, the map delivery address.
map and channel are similar.
So why not * map [key] value of it, this is not more intuitive?
Ian Taylor answered this recently in a golang-nuts 原话是:
In the very early days what we call maps now were written as pointers, so you wrote *map[int]int. We moved away from that when we realized that no one ever wrote
map
without writing\*map
.
Means that, at the beginning is writing * map [key] value, and later found that all the map is used as a pointer, so he abbreviated omitted.