2017-06-13 30 views
0

有人可以提供有关此代码的行为的一些解释: https://play.golang.org/p/_TjQhthHl3转到指针接口不为空

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? 

我发现这个职位Check for nil and nil interface in Go,但我还是不得到它...

+2

另请参阅常见问题解答:https://golang.org/doc/faq#nil_error – JimB

回答

2

error是一个内置的接口,以及*MyError实现该接口。尽管err2的值为零,但当您将其传递给isNil时,该函数将获得非零接口值。该值包含有关类型(*MyError)和值本身的信息,它是一个零指针。

如果您尝试在isNil中打印err,您会发现在第二种情况下,即使err2为零,也会出现“某些错误”。这说明了为什么err在这种情况下不是零(它必须包含类型信息)。

1

从我的理解你的var err2 *MyError定义是生成一个指向结构定义的指针和NOT一个实际的实例化对象。

+0

这并不能解释为什么它不是'nil'。它声明一个指针,并用'nil'值初始化它。 – zerkms

1

在Go中,接口类型由具有2个字段的结构表示:一个表示其实际类型,另一个表示指向该值的指针。

这意味着接口值永远不会等于nil,除非您传递的值实际上是nil值。

相关和相谈甚欢:GopherCon 2016: Francesc Campoy - Understanding nil