Mianqin Yao
Mianqin Yao

Reputation: 27

Go interface comparison is confusing

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
}

Upvotes: 1

Views: 528

Answers (2)

Burak Serdar
Burak Serdar

Reputation: 51657

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.

Upvotes: 2

icza
icza

Reputation: 418745

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: why struct arrays comparing has different result

Upvotes: 5

Related Questions