【发布时间】:2017-12-11 17:41:28
【问题描述】:
我正在尝试在 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
谁能帮我解决这个问题?
编辑:添加了一些额外的文件来说明问题。另外,我不明白反对票。我有一个诚实的问题。我只应该问对我有意义的问题吗?
【问题讨论】:
-
Go 绝对没有继承的概念(嵌入不是继承),你根本不能在 Go 中做父/子的事情。重新设计。
-
没有继承,但组合确实允许父/子关系;不确定@Volker 在这里得到了什么。无论如何,在您的使用示例中,它仍然没有显示分配给
tree.Root的变量test是如何创建的。应该是tree.Root = n1吧? -
@FelipeRocha 这是一个很好的问题,不要介意反对票。出于某种原因,该站点上的 golang 社区积极地反对问题,通常无论其有效性如何。也许尝试将您的问题简化为单个函数中的独立示例(例如,不需要多个文件)。
-
不幸的是,它已经没有多大意义了;结构如此复杂和复杂,很难快速跟踪执行情况。这就是将其提炼成MCVE 的好处——通常当您删除一些不必要的复杂性时,问题就会显现出来。
标签: go composition behavior-tree