有谁知道为什么map可以用作值接收器,但是在使用切片时只需要使用指针接收器? 为什么地图在方法调用后会发生变化?
地图示例:
package main
import (
"fmt"
)
type hashMap map[string]int
func (s hashMap) Add(k string, v int) {
s[k] = v
}
func main() {
var s hashMap
s = make(hashMap, 0)
fmt.Println(s)
s.Add("abc", 15)
fmt.Println(s)
}
输出:
map[] map[abc:15]
切片示例:
package main
import (
"fmt"
)
type slice []int
func (s *slice) Add(v int) {
(*s) = append(*s, v)
}
func main() {
var s slice
s = make(slice, 0)
fmt.Println(s)
s.Add(15)
fmt.Println(s)
}
输出:
[] [15]
答案 0 :(得分:7)
make之后的map变量是指向地图标题的指针:*hmap
。地图指针按值
// A header for a Go map.
type hmap struct {
// Note: the format of the Hmap is encoded in ../../cmd/internal/gc/reflect.go and
// ../reflect/type.go. Don't change this structure without also changing that code!
count int // # live cells == size of map. Must be first (used by len() builtin)
flags uint8
B uint8 // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
hash0 uint32 // hash seed
buckets unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
nevacuate uintptr // progress counter for evacuation (buckets less than this have been evacuated)
extra *mapextra // optional fields
}
切片变量是结构:slice
。 slice结构按值传递。
type slice struct {
array unsafe.Pointer
len int
cap int
}
答案 1 :(得分:0)
映射是接收者类型,而结构是值类型,值类型。因此,当您使用地图调用时,函数调用后值会发生变化。