map的value是不寻址的,无论它是什么类型
对尝试寻址的代码,编译会抛出Cannot take the address of 'm[1]'
如下
type Temp struct {
id int32
}
// 结构体类型的value。这段代码试图修改结构体内的值,接近真实使用场景
func main1() {
m := make(map[int32]Temp)
m[1] = Temp{1}
t := &m[1] // GoLand警告:Cannot take the address of 'm[1]'
t.id = 2
fmt.Println(m[1].id)
}
// 结构体指针类型的value
func main2() {
m := make(map[int32]*Temp)
m[1] = &Temp{1}
t := &m[1] // GoLand警告:Cannot take the address of 'm[1]'
(*t).id = 2
}
// int指针类型的value
func main3() {
m := make(map[int32]*int)
n := 1
m[1] = &n
t := &m[1] // GoLand警告:Cannot take the address of 'm[1]'
fmt.Println(t)
}
为什么无法获取map的value的地址呢?
这是因为map中的值地址在内存中是动态的,一旦发生扩容,key 和 value 的内存位置就会改变,之前保存的地址也就失效了。即便通过一些unsafe的方式获取到了地址,也不能长期持有
想要改变value,只有一种方法:重新为key赋值以替换原有value
(或许有人认为还有一种方法,就是把value声明为指针类型,就可以通过指针修改对应的值了。这是错误的,因为在这种方法中,value的值就是地址,所以并没有修改value的值,只是修改了value的值(地址)指向的值)