Go指针指向接口不为空。

huangapple go评论63阅读模式
英文:

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

huangapple
  • 本文由 发表于 2017年6月14日 05:28:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/44531857.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定