零指针嵌入错误

yan*_*ory 1 null go

当我尝试打印带有未初始化嵌入错误的指针时,为什么会出现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)
}
Run Code Online (Sandbox Code Playgroud)

结果是

2009/11/10 23:00:00 %!v(PANIC=runtime error: invalid memory address or nil pointer dereference)
2009/11/10 23:00:00 foobar
Run Code Online (Sandbox Code Playgroud)

https://play.golang.org/p/fBuN0XonX9v

这在今天的一次采访中提出,面试官和受访者都无法理解.

Cer*_*món 7

规范说:

给定结构类型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)是装饰的恐慌值.