这个满足错误接口的结构的nil实例未显示为nil

时间:2015-02-20 04:10:02

标签: go

这对某人来说应该是个好主意。为什么我没有得到我期望的结果(“错误不是零”)?

http://play.golang.org/p/s8CWQxobVL

type Goof struct {}

func (goof *Goof) Error() string {
    return fmt.Sprintf("I'm a goof")
}

func TestError(err error) {
    if err == nil {
        fmt.Println("Error is nil")
    } else {
        fmt.Println("Error is not nil")
    }
}

func main() {
    var g *Goof // nil
    TestError(g) // expect "Error is nil"
}

1 个答案:

答案 0 :(得分:8)

事实证明,a Frequently Asked Question about Go,简短的回答是界面比较比较了类型和值,(*Goof)(nil)error(nil)有不同的类型。

由于if err != nil是标准的,因此您需要一个可以使用它的返回值。您可以声明var err error而不是var g *Gooferr的零值方便error(nil)

或者,如果您的func返回errorreturn nil将返回您想要的内容。

有关更多背景信息,请参阅常见问题解答的答案:

  

在幕后,接口实现为两个元素,一个类型和一个值。该值称为接口的动态值,是一个任意的具体值,类型是值的类型。对于int3,接口值示意性地包含(int, 3)

     

仅当内部值和类型都未设置nil时,接口值才为(nil, nil)。特别是,nil接口始终保持nil类型。如果我们在接口值中存储类型为*int的指针,则无论指针的值如何,内部类型都将为*int(*int, nil)。因此,即使内部指针为nil,这样的接口值也将是非nil

==严格检查类型是否相同,而不是类型(*Goof)实现接口(error)。查看the original了解更多信息。

如果有助于澄清,这不仅发生在nil:在this example中,xy变量背后的数据显然是{{1} },但他们有不同的类型。当您将3x放入y时,它们会比较为不相等:

interface{}