指向接口的指针不为空

时间:2017-06-13 21:28:17

标签: go interface

有人可以提供有关此代码行为的一些解释: 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}},但我仍然没有得到它......

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值。

相关和好的谈话:GopherCon 2016: Francesc Campoy - Understanding nil