在golang

时间:2017-12-11 17:41:28

标签: go composition

我正在尝试在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

有人可以帮我解决这个问题吗?

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

2 个答案:

答案 0 :(得分:2)

此处的问题是您的BehaviorTree结构未定义Tick()。因此,当您致电tree.Tick()时,没有定义直接方法,因此它会调用嵌入式Tick()结构的提升Behavior方法。那个Behavior struct 不知道BehaviorTree是什么!在Go的嵌入式伪继承风格中,“子”类型没有他们"父母的概念# 34;,也没有任何参考或访问它们。使用嵌入类型作为接收器调用嵌入式方法,而不是嵌入结构。

如果您需要预期的行为,则需要在Tick()类型上定义BehaviorTree方法,并使用该方法调用自己的Update()方法(然后调用sub { {1}}或Tick()方法(如果您愿意)。例如:

Update()

答案 1 :(得分:0)

正如Volker所说

  

Go绝对没有继承的概念(嵌入不是继承),你根本不能在Go中做父/子的东西。重新设计

据我所知,你想要的是一个使用接口多次执行相同任务的功能。

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

当然,Initialize必须在界面中。

相关问题