Reputation: 5286
How can I compare pointers that were turned into interfaces?
package main
import (
"fmt"
)
type ContainerInterface interface {
Check(ContentInterface) bool
}
type ContentInterface interface {
BelongsTo(ContainerInterface) bool
}
type BaseContainer struct {}
func (container *BaseContainer) Check(content ContentInterface) bool {
return content.BelongsTo(container)
}
// The following are on a different package
type Container struct {
BaseContainer
}
func (container *Container) GetContent() Content {
return Content{container}
}
type Content struct {
container *Container
}
func (content Content) BelongsTo(container ContainerInterface) bool {
return container == content.container
}
func main() {
container := &Container{}
content := container.GetContent()
fmt.Printf("%p\n%p\n%v\n", container, content.container, container == content.container)
fmt.Println()
fmt.Println(content.BelongsTo(container))
fmt.Println(container.Check(content))
}
This returns:
0xXYZXYZ
0xXYZXYZ
true
true
false
0xXYZXYZ
represents the same memory direction, but the last call is returning false
when it should return true
Upvotes: 0
Views: 69
Reputation: 515
This isn't a "pointers and interfaces" problem it is a "anonymous composition is not inheritance" problem. It's almost always a mistake to try to use go in an OOP kind of way.
When you call container.Check(content)
, because type Container
doesn't have a Check()
method it gets delegated to the BaseContainer
anonymous embbedded type's Check()
method.
But methods on embedded structs don't have any visibility of the field of the parent struct or the parent struct itself - so you are actually checking (calling BelongsTo()
) against the anonymous BaseContainer
embedded struct not the outer container. This quite correctly returns false.
The fact that this is being done through an interface makes absolutely no difference to this.
If you really did want to code in this way you would have to put a field in the BaseContainer type that pointed to the outer container:
type BaseContainer struct {
parent ContainerInterface
}
which would have to be initialised on creation of the parent struct and then the methods adapted to use this. (Although better just to avoid OO style altogether :) )
Upvotes: 2