Go 奇怪的零/非零行为

Go 奇怪的零/非零行为,go,Go,我的项目中有以下代码: mod := srt.PrimaryModule() if mod != nil { mods[mod.Name()] = mod } 当它执行时,我得到: PANIC: runtime error: invalid memory address or nil pointer dereference 堆栈就在第三行。(是的,这是moddereference,地图mods仅在上面一行创建…) 那么,

我的项目中有以下代码:

        mod := srt.PrimaryModule()
        if mod != nil {
            mods[mod.Name()] = mod
        }
当它执行时,我得到:

PANIC: runtime error: invalid memory address or nil pointer dereference
堆栈就在第三行。(是的,这是
mod
dereference,地图
mods
仅在上面一行创建…)

那么,什么时候nil值不等于nil?为什么

 srt.PrimaryModule() 
返回一个接口类型,
Module
,其中定义了一个
Name()
方法,返回
string

在这种特殊情况下,
srt
被键入
StdReflectedType
,这是一种接口类型,具有函数
PrimaryModule()
返回类型
Module
srt
的实际实现是一个从其字段返回未初始化的
模块
值的结构

此外,如果我这样做的话

reflect.ValueOf(mod)

结果是reflect.Value为零

从reflect软件包文档中:

 ValueOf returns a new Value initialized to the concrete value stored in the interface i. ValueOf(nil) returns the zero Value
除了前一行刚刚确定的
mod!=无
。那么是什么原因呢


我似乎无法在一个最小的例子中重现这一点-是否有任何合理的行为会导致这些行这样做-我是否不理解有关接口值和零指针的一些重要信息?

如果接口中存储了任何具体值,那么接口将不会是
nil
。但是,存储在接口中的具体值可以是
nil
指针

例如,
fmt.Println(mod)
输出是具体值,
nil

if mod != nil {
    fmt.Println(mod)
    mods[mod.Name()] = mod
}
srt.PrimaryModule()
是否返回指向
mod
nil
指针?如果是这样,
mod.Name()

参考资料:

:


这个代码修订版的输出是什么

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
    }
}

即使mod不是nil,mod.Name()也可能是nil?mod.Name()返回字符串。因此,它不能返回零。还是你指的是功能?如果一个非nil的零值接口可以容纳一个nil实现,如何检查该条件?我不知道go,但我只是怀疑赋值的LHS有问题。也许mods是零。或者mods[mod.Name()]一开始是无效的。请参阅,以了解可能发生的情况的解释。显示srt.PrimaryModule()的代码。“仅当内部值和类型都未设置时,接口值才为nil,(nil,nil)。”啊,太好了。TYVM,这就是我错过的!谢谢,最后一个链接特别有用。有没有一种方法可以在不知道具体类型的情况下显式检查具体值是否为零?似乎很粗略/没有,因为nil是类型化的-但是如果一些reflect包方法可以做到这一点(似乎没有!),那就太好了。我讨厌的解决方法是,如果接收者是nil,那么所有实现类型的Name()方法都用一个“”替换掉,并检查这一点…(InterfaceData(),也许?但它几乎没有文档记录…)(或者,你知道,添加一个func(m*Module)IsValid()bool{return m!=nil}要干净得多。)@BadZen:请看我修改后的答案中的问题。另外,“srt的实际实现是一个从其字段返回未初始化模块值的结构。”你的确切意思是什么?缺少的是一个很好的工作示例:。