我们说我们有以下内容:
type I interface {
M()
}
func main() {
var i I
i.M()
}
为什么Go不在编译类型中进行一些静态分析来检查接口的底层值是否为nil并抛出编译时错误?相反,我们最终在i.M()
=============================================== ===================
输出:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0xffffffff addr=0x0 pc=0x2004d]
goroutine 1 [running]:
panic(0x13f480, 0x1040a038)
/usr/local/go/src/runtime/panic.go:481 +0x700
main.main()
/tmp/sandbox469152264/main.go:12 +0x4d
答案 0 :(得分:1)
为什么Go不在编译类型中进行一些静态分析来检查接口的基础值是否为nil并抛出编译时错误?
zero value的interface为nil
,在编译时检测不到任何其他零值。
From the FAQ:
在幕后,接口实现为两个元素,一个类型和一个值。
- 该值称为界面的动态值,是一个任意的具体值
- 类型是值的类型。
仅当内部值和类型都未设置
(nil, nil)
时,接口值才为nil 特别是,nil
界面将始终保持nil
类型。
这个thread adds,关于nil值(运行时):
基本答案是,如果您不希望在其上调用方法,则永远不要在界面中存储内容。
语言可能允许它,但这违反了接口的语义。要说明,
nil
值通常不应存储在接口中,除非它是在其指针值方法中明确处理该情况并且没有值接收方法的类型。