一个例子
package main
import (
"bytes"
"io"
)
func main() {
var buf *bytes.Buffer
var out io.Writer = buf
if out != nil {
out.Write([]byte("hello world!\n"))
}
}
运行后报错
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x105f716]
goroutine 1 [running]:
bytes.(*Buffer).Write(0x0, 0xc000014090, 0xd, 0xd, 0x0, 0x1069860, 0xc00005e058)
/usr/local/go/src/bytes/buffer.go:169 +0x26
main.main()
/Users/root/workspcae/interface/interface.go:40 +0x7a
exit status 2
主要原因是 if out != nil
这个判断为true,但是out实际的可写入指针为nil
一个接口类型的值,包括动态类型
和动态值
两个部分。在把一个变量隐式的转换为接口值时,我们要注意该变量的值是否为nil。如之前的例子,var buf *bytes.Buffer
,buf的值为nil,但是隐式转换var out io.Writer = buf
后,out的动态类型为*bytes.Buffer
,动态值为nil
,而接口类型的非空判断,必须动态类型和动态值都为nil。这就导致了上述空指针的panic