go - golang中父类实现方法调用子类方法

标签 go composition behavior-tree

我正在尝试在 go 中实现行为树,但我正在努力解决它的组合功能。基本上,我需要在下面实现 Tick() 来调用嵌入的任何地方定义的方法。

这是 behavior.go:

type IBehavior interface {
  Tick() Status
  Update() Status
}

type Behavior struct {
  Status Status
}

func (n *Behavior) Tick() Status {
  fmt.Println("ticking!")
  if n.Status != RUNNING { n.Initialize() }
  status := n.Update()
  if n.Status != RUNNING { n.Terminate(status) }

  return status
}

func (n *Behavior) Update() Status {
  fmt.Println("This update is being called")
  return n.Status
}

下面是嵌入的Behavior结构:

type IBehaviorTree interface {
  IBehavior
}

type BehaviorTree struct {
  Behavior

  Root IBehavior
}

func (n *BehaviorTree) Update() Status {
  fmt.Printf("Tree tick! %#v\n", n.Root)
  return n.Root.Tick()
}

为了让这个例子更有意义,还有一些文件:

type ILeaf interface {
  IBehavior
}

type Leaf struct {
  Behavior
}

还有这个:

type Test struct {
  Leaf

  Status Status
}

func NewTest() *Test {
    return &Test{}
}

func (n Test) Update() Status {
    fmt.Println("Testing!")
    return SUCCESS
}

下面是它的用法示例:

tree := ai.NewBehaviorTree()
test := ai.NewTest()
tree.Root = test

tree.Tick()

我希望通过打印这个树来正常滴答作响:

ticking!
Tree tick!

但我得到的是:

ticking!
This update is being called

谁能帮我解决这个问题?

编辑:添加了一些额外的文件来说明问题。另外,我不明白反对票。我有一个诚实的问题。我应该只问对我来说有意义的问题吗?

最佳答案

您的问题是 Tick() 未在您的 BehaviorTree 结构中定义。因此,当您调用 tree.Tick() 时,没有定义直接方法,因此它会调用嵌入 Behavior< 的提升的 Tick() 方法 结构。 Behavior 结构不知道BehaviorTree 是什么!在 Go 的伪继承嵌入风格中,“子”类型没有它们的概念“ parent ”,也没有对他们的任何引用或访问。调用嵌入方法时使用嵌入类型作为它们的接收者,而不是嵌入结构。

如果您想要预期的行为,您需要在您的 BehaviorTree 类型上定义一个 Tick() 方法,并让该方法调用它自己的 Update () 方法(如果需要,然后调用子 Tick()Update() 方法)。例如:

type BehaviorTree struct {
  Behavior

  Root IBehavior
}

func (n *BehaviorTree) Tick() Status {
    n.Update() // TODO: do you want this status or the Root.Tick() status?
    return n.Root.Tick()
}

func (n *BehaviorTree) Update() Status {
  fmt.Printf("Tree tick! %#v\n", n.Root)
  return nil
}

关于go - golang中父类实现方法调用子类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47758412/

相关文章:

ruby-on-rails - 模型- View - Controller 是否与人工智能和行为树很好地配合?

python - 将声明式 DSL 转换为嵌套函数调用

go - 从 Go 中的 SAML 响应中获取用户名

java - 有没有什么方法可以设计我的 Java 代码,使这两个对象不引用自身?

c++ - C4430 和 C2146 Visual Studio 错误

java - 如何在Java中修改两个类的对象?

artificial-intelligence - 在部分随机但受偏好影响的情况下,确定 NPC 将采取什么行动?

Gob 解码器返回 EOF 错误

go - Printf 中的 %g 不提供固定的小数位,如 %f 或 %e

go - 用反射遍历结构,用反射创建新的指针类型 slice