我正在尝试使用struct
来管理树上的访问节点。每当我访问父级的子节点的方法时,后续调用中的父级引用都会丢失(即parent.child.method(child) -> [parent becomes nil]-> parent(the previous child).child ... etc
)。
这是我文件中的错误摘要。
type Node struct {
Left *Node
Right *Node
value int
}
func (parent *Node) determineSide(child *Node) (Node, Node) {
if child.Value < parent.Value {
if parent.hasLeftNode() {
return parent.Left.determineSide(child)
}
return parent.addLeftNode(child)
} else if child.Value > parent.Value {
if parent.hasRightNode() {
return parent.Right.determineSide(child)
}
return parent.addRightNode(child)
}
return *child, *parent
}
我试图通过尝试找到一种方法来通知该方法新引用应为parent.Left
来解决此问题。使用*parent.Left
和&parent.Left
之类的东西似乎并不正确。
一个解决方案可能是将这段代码移到struct
之外,并让另一个函数来处理结果以进行快速修复,但是我想了解为什么此方法无法立即使用。此处的思考过程受this.child.determineSide(child)
的影响。
完整代码为here。
修改
这是终端的一些输出,可能会提供更多的上下文。看起来我遇到了导致问题的检查类型问题。
parent &{<nil> <nil> 2}
parent.Left <nil>
parent.LeftNode true
child &{<nil> <nil> 1}
parent <nil>
child &{<nil> <nil> 1}
答案 0 :(得分:1)
好的,我知道你到底要问什么。
New()
方法返回一个值,而不是一个指针,这意味着您以后看不到调用者中的更改。调用者得到的只是Node的值副本。因此,您打印的父级将始终为{Left:<nil> Right:<nil> Value:2}
。
addLeftNode()
和addRightNode()
也是如此。
只使用指针而不是值来实现目标。
我认为这只是问题所在的Visit()
方法。
else if
,而应使用if
。之前:
// Visit will automatically walk through the Child Nodes of the accessed Parent Node.
func (parent *Node) Visit() (Node, int) {
fmt.Println("Node value:", parent.Value)
if parent.hasLeftNode() {
return parent.Left.Visit()
} else if parent.hasRightNode() {
return parent.Right.Visit()
}
return *parent, parent.Value
}
已修改:
// Visit will automatically walk through the Child Nodes of the accessed Parent Node.
func (parent *Node) Visit() (Node, int) {
if parent.hasLeftNode() {
parent.Left.Visit()
}
fmt.Println("Node value:", parent.Value)
if parent.hasRightNode() {
parent.Right.Visit()
}
return *parent, parent.Value
}
另外,对我来说,Visit()
不应返回任何值。
答案 1 :(得分:0)
问题源自错误的类型检查。该函数成功处理了调用,但是我使用的方法在确认是否已分配节点方面并不准确。
// isNode checks whether the provided property is a Node.
func (parent *Node) isNode(property interface{}, typeset interface{}) bool {
fmt.Println(reflect.TypeOf(property) == reflect.TypeOf(typeset))
// this always referred to the address for the base Node struct or similar falsy.
return reflect.TypeOf(property) == reflect.TypeOf(typeset)
}
// hasLeftSide tests whether the Parent Node has a Node assigned to its left side.
func (parent *Node) hasLeftNode() bool {
return parent.Left != nil //parent.isNode(parent.Left, (*Node)(nil))
}
// hasRightSide tests whether the Parent Node has a Node assigned to its right side.
func (parent *Node) hasRightNode() bool {
return parent.Right != nil // parent.isNode(parent.Right, (*Node)(nil))
}