英文:
Go pointer to interface is not null
问题
有人能解释一下这段代码的行为吗: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?
我在这个帖子中找到了一些信息:https://stackoverflow.com/questions/13476349/check-for-nil-and-nil-interface-in-go,但我还是不太明白...
英文:
Can someone provide some explanation about this code behaviour:
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?")
}
}
Output is:
[OK] err is nil ...
[OK] ... still nil
[OK] err2 is nil ...
[KO] .. why err2 not nil?
I found this post https://stackoverflow.com/questions/13476349/check-for-nil-and-nil-interface-in-go but I still don't get it...
答案1
得分: 2
error
是一个内置接口,*MyError
实现了该接口。即使err2
的值为nil,当你将其传递给isNil
函数时,该函数得到的是一个非nil的接口值。该值包含有关类型(*MyError
)和值本身(一个nil指针)的信息。
如果你尝试在isNil
中打印err
,你会发现在第二种情况下,即使err2
为nil,你仍然会得到"some error"。这说明了为什么在这种情况下err
不是nil(它必须包含类型信息)。
英文:
error
is a built-in interface, and *MyError
implements that interface. Even though the value of err2
is nil, when you pass it to isNil
, the function gets a non-nil interface value. That value contains information about the type (*MyError
) and the value itself, which is a nil pointer.
If you try printing err
in isNil
, you'll see that in the second case, you get "some error" even though err2
is nil. This demonstrates why err
is not nil in that case (it has to contain the type information).
答案2
得分: 1
根据我的理解,你的var err2 *MyError
定义生成的是指向结构体定义的指针,而不是一个实际实例化的对象。
英文:
From my understanding your var err2 *MyError
definition is generating a pointer to the struct definition and NOT an actual instantiated object.
答案3
得分: 1
在Go语言中,接口类型由一个包含两个字段的结构表示:一个字段表示其实际类型,另一个字段是指向该值的指针。
这意味着,除非你传递的值实际上是nil
值,否则接口值永远不会等于nil
。
相关而且不错的讨论:GopherCon 2016: Francesc Campoy - 理解nil
英文:
In Go interface types are represented by a structure with 2 fields: one denotes its actual type and the other is a pointer to the value.
It means that an interface value is never equal to nil
unless the value you passed is actually a nil
value.
Relevant and good talk: GopherCon 2016: Francesc Campoy - Understanding nil
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论