我的项目中有以下代码:
mod := srt.PrimaryModule()
if mod != nil {
mods[mod.Name()] = mod
}
当它执行时,我得到:
PANIC: runtime error: invalid memory address or nil pointer dereference
堆栈就在第三行。 (是的,mod
取消引用,地图mods
仅在上面一行创建...)
那么,什么时候nil值不等于nil?为什么?
srt.PrimaryModule()
返回一个接口类型Module
,其中定义的Name()
方法返回string
。
在这种特殊情况下,srt
是键入的StdReflectedType
,这是一个函数PrimaryModule()
返回类型Module
的接口类型。 srt
的实际实现是一个结构,它从其字段中返回未初始化的Module
值。
此外,如果我这样做
reflect.ValueOf(mod)
结果是零反射。值。
来自反射包文档:
ValueOf returns a new Value initialized to the concrete value stored in the interface i. ValueOf(nil) returns the zero Value
这似乎是正确的,除了上一行刚确定mod != nil
。那是什么给出了什么?
我似乎无法在一个最小的例子中重现这一点 - 是否有任何明智的行为可能会导致这些行做到这一点 - 我不理解接口值和nil指针的重要事项吗?
答案 0 :(得分:2)
如果界面中存储了任何具体值,则界面将不是nil
。但是,存储在接口中的具体值可以是nil
指针。
例如,fmt.Println(mod)
输出,具体值是nil
?
if mod != nil {
fmt.Println(mod)
mods[mod.Name()] = mod
}
srt.PrimaryModule()
是否会向nil
返回mod
指针?如果是,mod.Name()
将panic
nil pointer dereference
。
参考文献:
The Go Programming Language Specification:Interface types
Go Data Structures: Interfaces
Why is my nil error value not equal to nil?
此修订版代码的输出是什么?
mod := srt.PrimaryModule()
if mod != nil {
fmt.Printf("%T %v\n", mod, mod)
if mod.(Module) != nil {
fmt.Println(mod.Name())
mods[mod.Name()] = mod
}
}