sta*_*wer 0 null pointers interface go
首先让我们考虑以下几点:
func process(body io.Reader) {
fmt.Printf("body == nil ? %+v\n", body == nil)
}
func main() {
var body *bytes.Buffer
fmt.Printf("body == nil ? %+v\n", body == nil)
process(body)
process(nil)
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
body == nil ? true
body == nil ? false // Did you get this right?
body == nil ? true
Run Code Online (Sandbox Code Playgroud)
另一个例子:
type Container struct {
Reader io.Reader
}
func processContainer(container Container) {
fmt.Printf("container.Reader == nil ? %+v\n", container.Reader == nil)
}
func main() {
var body *bytes.Buffer
processContainer(Container{Reader: body})
processContainer(Container{Reader: nil})
}
Run Code Online (Sandbox Code Playgroud)
输出:
container.Reader == nil ? false // Did you get this right?
container.Reader == nil ? true
Run Code Online (Sandbox Code Playgroud)
对此的解释在https://golang.org/doc/faq#nil_error。
一个简单的解决方案是让== nil测试只在接口对象包含nil值时返回 true 。但这会违反 的传递性==,因为它会断言两个具有 nil 值但不同接口类型的对象在==.
但是,我想知道是否应该IsNil()在所有接口类型上都有一个方法来解决这个问题?
另一个例子,来自 Go http 客户端的这一行,可以意外地抓住你:
https://github.com/golang/go/blob/master/src/net/http/client.go#L545
所以如果你这样称呼它
var body *bytes.Buffer
http.NewRequest(method, path, body)
Run Code Online (Sandbox Code Playgroud)
你会得到一个 nil 指针异常,尽管从源代码来看,这不应该发生。
编辑
抱歉,我引用了 Go http 源代码的错误行,现已更正。但这个例子仍然成立。
编辑 2
我已经强调了我的问题,以明确我在问什么。
首先阅读这个相关问题:隐藏 nil 值,理解为什么 golang 在这里失败
您可以nil通过将其与nil.
如果要检查包裹在非nil接口中的值是否为nil,可以使用反射:reflect.Value.IsNil()。
请参阅此修改后的示例:
func process(body io.Reader) {
fmt.Printf("process(): body == nil ? %t\n", body == nil)
if body != nil {
fmt.Println("\tINSIDE IsNil():", reflect.ValueOf(body).IsNil())
}
}
func main() {
var body *bytes.Buffer
fmt.Printf("main(): body == nil ? %t\n", body == nil)
process(body)
process(nil)
process(&bytes.Buffer{})
}
Run Code Online (Sandbox Code Playgroud)
输出(在Go Playground上试试):
main(): body == nil ? true
process(): body == nil ? false
INSIDE IsNil(): true
process(): body == nil ? true
process(): body == nil ? false
INSIDE IsNil(): false
Run Code Online (Sandbox Code Playgroud)
如果你想要一个“统一”的IsNil()函数来判断其中一个是否是nil:
func IsNil(i interface{}) bool {
return i == nil || reflect.ValueOf(i).IsNil()
}
Run Code Online (Sandbox Code Playgroud)