Go接口比较令人困惑。

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

Go interface comparison is confusing

问题

为什么全局变量a1不等于局部变量a2,但a2等于a3和a4?

对我来说,这太令人困惑了。a1、a2和a3都是通过调用getInterface方法进行评估的,但是当比较它们时,结果却不同。

谢谢所有看到这个问题的人。


import "fmt"

var a1 aInterface = getInterface()

type aInterface interface {
	fun1()
}

type aInterfaceImpl struct{}

func (p *aInterfaceImpl) fun1() {
	return
}

func getInterface() aInterface {
	return new(aInterfaceImpl)
}

func main() {
	var a2 aInterface = getInterface()
	var a3 aInterface = getInterface()
	var a4 aInterface = new(aInterfaceImpl)
	fmt.Printf("a1 == a2, %+v\n", a1 == a2) // a1 == a2, false
	fmt.Printf("a2 == a3, %+v\n", a2 == a3) // a2 == a3, true
	fmt.Printf("a2 == a4, %+v\n", a2 == a4) // a2 == a4, true
}
英文:

why global variable a1 is not equal to local variable a2, but a2 is equal to a3 and a4

It is so confusing for me, a1, a2, a3 are all evaluated by calling the method getInterface, but when compare them, it get different result.

Thank you, everybody who see the question.


import "fmt"

var a1 aInterface = getInterface()

type aInterface interface {
	fun1()
}

type aInterfaceImpl struct{}

func (p *aInterfaceImpl) fun1() {
	return
}

func getInterface() aInterface {
	return new(aInterfaceImpl)
}

func main() {
	var a2 aInterface = getInterface()
	var a3 aInterface = getInterface()
	var a4 aInterface = new(aInterfaceImpl)
	fmt.Printf("a1 == a2, %+v\n", a1 == a2) // a1 == a2, false
	fmt.Printf("a2 == a3, %+v\n", a2 == a3) // a2 == a3, true
	fmt.Printf("a2 == a4, %+v\n", a2 == a4) // a2 == a4, true
}

答案1

得分: 4

规范:比较运算符:

> 接口值是可比较的。如果两个接口值具有相同的动态类型和相等的动态值,或者两者都具有值nil,则它们是相等的。

在你的例子中,a1a2a3a4都是接口值,它们都保存具体类型*aInterfaceImpl的值,所以归结为指针比较:

> 指针值是可比较的。如果两个指针值指向同一个变量,或者两者都具有值nil,则它们是相等的。指向不同的零大小变量的指针可能相等,也可能不相等。

由于aInterfaceImpl的大小为零(它是一个空的结构体类型),根据规范,你不能对它们的地址的相等性有任何期望。它们可能具有相同的地址,也可能具有不同的地址,两种情况都是有效的。

参考链接:https://stackoverflow.com/questions/52421103/why-struct-arrays-comparing-has-different-result/52421277#52421277

英文:

Spec: Comparison operators:

> Interface values are comparable. Two interface values are equal if they have identical dynamic types and equal dynamic values or if both have value nil.

In your example a1, a2, a3 and a4 are all interface values, they all hold values of concrete type *aInterfaceImpl, so it comes down to pointer comparison:

> Pointer values are comparable. Two pointer values are equal if they point to the same variable or if both have value nil. Pointers to distinct zero-size variables may or may not be equal.

Since size of aInterfaceImpl is zero (it's an empty struct type), as per the spec, you cannot expect anything about the equality of their addresses. They may or may not have the same address, both are valid.

See related: https://stackoverflow.com/questions/52421103/why-struct-arrays-comparing-has-different-result/52421277#52421277

答案2

得分: 2

根据语言规范,多个零大小结构的实例可以具有相同的内存位置。因此,a1a2a3都有可能被分配到相同的内存位置。

定义:

type aInterfaceImpl struct {
   i int
}

而且这三个接口变量将是不同的。

英文:

According to the language specification, multiple instances of a zero-size structure can have the same memory location. Because of this, it is possible that all of a1, a2, and a3 can be allocated to have the same memory location.

Define:

type aInterfaceImpl struct {
   i int
}

and all three interface variables will be distinct.

huangapple
  • 本文由 发表于 2021年7月30日 21:52:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/68592091.html
匿名

发表评论

匿名网友

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

确定