有人可以提供有关此代码行为的一些解释: Check for nil and nil interface in Go
package main
import (
"fmt"
)
type MyError struct{}
func (e *MyError) Error() string {
return "some error"
}
func main() {
var err error
if err == nil {
fmt.Println("[OK] err is nil ...")
}else{
fmt.Println("[KO] err is NOT nil...")
}
isNil(err)
var err2 *MyError
if err2 == nil {
fmt.Println("[OK] err2 is nil ...")
}else{
fmt.Println("[KO] err2 is NOT nil...")
}
isNil(err2)
}
func isNil(err error){
if err == nil {
fmt.Println("[OK] ... still nil")
}else{
fmt.Println("[KO] .. why not nil?")
}
}
输出是:
[OK] err is nil ...
[OK] ... still nil
[OK] err2 is nil ...
[KO] .. why err2 not nil?
我发现这篇文章{{3}},但我仍然没有得到它......
答案 0 :(得分:2)
error
是一个内置接口,*MyError
实现了该接口。即使err2
的值为nil,当您将其传递给isNil
时,该函数也会获得非零接口值。该值包含有关类型(*MyError
)和值本身的信息,这是一个零指针。
如果你尝试在err
中打印isNil
,你会发现在第二种情况下,你会得到一些错误"即使err2
为零。这说明了err
在这种情况下不是nil的原因(它必须包含类型信息)。
答案 1 :(得分:1)
根据我的理解,你的var err2 *MyError
定义正在生成一个指向结构定义的指针,而不是一个实际的实例化对象。
答案 2 :(得分:1)
在Go中,接口类型由具有2个字段的结构表示:一个表示其实际类型,另一个是指向该值的指针。
这意味着接口值永远不会等于nil
,除非您传递的值实际上是nil
值。