如何在将它们转换为界面后检查指针

时间:2018-04-20 15:34:42

标签: go

如何比较变成接口的指针?

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))
}

返回:

0xXYZXYZ
0xXYZXYZ
true

true
false

0xXYZXYZ表示内存方向相同,但最后一次调用返回false时应返回true

1 个答案:

答案 0 :(得分:2)

这不是“指针和接口”问题,它是“匿名组合不是继承”的问题。尝试以OOP方式使用go几乎总是错误的。

当您致电container.Check(content)时,由于类型Container没有Check()方法,因此会将其委托给BaseContainer匿名嵌入类型的Check()方法。

但是嵌入式结构上的方法没有父结构字段或父结构本身的任何可见性 - 所以你实际上是在对匿名BelongsTo()嵌入式结构进行检查(调用BaseContainer)不是外容器。这非常正确地返回false。

这是通过界面完成的事实对此没有任何区别。

如果您确实想要以这种方式编写代码,则必须在BaseContainer类型中添加一个指向外部容器的字段:

type BaseContainer struct {
  parent ContainerInterface
}

必须在创建父结构时初始化,然后适合使用它的方法。 (虽然最好只是为了避免OO风格:))