问题代码:
Update 2017.2.23 See: https://golang.org/doc/faq#nil_error
package main
import (
"bytes"
"fmt"
"io"
)
func main() {
var buf *bytes.Buffer // 注意此处为指针类型 impl interface io.Writer
fmt.Println(fmt.Sprintf("%V", buf))
test(buf)
}
func test(out io.Writer) {
if out != nil {
out.Write([]byte("done"))
}
}
以上程序的运行一定会引起panic,尽管在 test 函数中进行了 if out != nil 。 原因在于 interface 的 nil 判断的特殊性,因为 interface 的结构包括两部分 type 和 data, 我们定义的 var buf *bytes.Buffer,声明了一个接口包括一个空指针【但是non-nil】 bytes.Buffer类型空指针,该指针的数据为nil,结构大体如下:
var buffer *bytes.Buffer:
type: *bytes.Buffer
data: nil
但是在test函数中的传递的接口类型为 out io.Writer, 因此 if out != nil 中的 nil 结构如下:
type: nil
data: nil
修改方式:
func main() {
var buf io.Writer // *bytes.Buffer // impl interface io.Writer
fmt.Println(fmt.Sprintf("%V", buf))
test(buf)
}
因为 var buf io.Writer这句话将var声明成了一个真正的 nil interface。
type: nil
data: nil