在go中,当键不存在时,映射的值为零。
我在下面有一个简短的代码片段:
playground
package main
import (
"sync"
)
func main() {
var mm map[int]sync.Mutex
var m sync.Mutex
mm[1].Lock() // not work due to cannot call pointer method on mm[1] and cannot take the address of mm[1]
m.Lock() // work normal
}
上面的mm[1]
和m
有什么区别?我用反射来检查,但看不到它们之间的区别。关于导致差异的任何线索?
最佳答案
问题不在于映射的零值,而是方法调用期间的可寻址性。
互斥锁上的Lock方法具有一个指针接收器:
func (*Mutex) Lock
给定变量m sync.Mutex
,根据spec,使用指针接收器在其上调用方法将自动变为&m.Lock()
:如果x的方法集(的类型)有效,则方法调用x.m()是有效的
包含m并且参数列表可以分配给参数列表
的米如果x是可寻址的并且&x的方法集包含m,则x.m()为
(&x).m()的简写
其中的重要部分是addressable要求。变量
m
是可寻址的,但映射查找的返回值不是。这意味着编译器将不会尝试调用&mm[1].Lock()
。当您尝试编译示例时,这些错误可以在返回的错误消息中看到:
./prog.go:11:7: cannot call pointer method on mm[1]
./prog.go:11:7: cannot take the address of mm[1]
关于go - go map值和nil之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63109932/