当我尝试打印带有未初始化嵌入错误的指针时,为什么会出现nil指针错误:
package main
import (
"log"
"errors"
)
type Danger struct {
error
}
func main() {
// the nil pointer issue has to do with struct embedding an error value that is nil
d := &Danger{}
log.Println(d)
d = &Danger{errors.New("foobar")}
log.Println(d)
}
结果
2009/11/10 23:00:00 %!v(PANIC=runtime error: invalid memory address or nil pointer dereference)
2009/11/10 23:00:00 foobar
https://play.golang.org/p/fBuN0XonX9v
今天接受采访时,面试官和受访者都无法理解。
答案 0 :(得分:7)
spec说:
给定结构类型S和定义的类型T,提升的方法包含在结构的方法集中,如下所示:
- 如果S包含嵌入字段T,则S和* S的方法集都包括带有接收方T的提升方法。* S的方法集还包括带接收方* T的提升方法。
fmt文档说:
如果操作数实现了错误接口,则将调用Error方法将对象转换为字符串,然后根据动词的需要对其进行格式化(如果有的话)。
由此我们可以得出结论,log.Println(d)
将从error
字段调用提升的Error方法。
如果error
字段为nil
,则呼叫会发生恐慌。
fmt文档还说:
如果错误或字符串方法在打印例程调用时触发了混乱,则fmt软件包会从恐慌中重新格式化错误消息,并通过fmt软件包指示它。
文字%!v(PANIC=runtime error: invalid memory address or nil pointer dereference)
是装饰的恐慌值。