Pointers 调用struct属性方法时Golang结构指针引用丢失
我试图使用Pointers 调用struct属性方法时Golang结构指针引用丢失,pointers,go,struct,Pointers,Go,Struct,我试图使用结构来管理对树上节点的访问。每当我访问父节点的子节点的方法时,后续调用上的父引用就会丢失(即parent.child.method(child)->[parent been nil]->parent(上一个子节点)。child…等) 这是我的文件中的错误片段 type Node struct { Left *Node Right *Node value int } func (parent *Node) determineSide(child *Node) (
结构来管理对树上节点的访问。每当我访问父节点的子节点的方法时,后续调用上的父引用就会丢失(即parent.child.method(child)->[parent been nil]->parent(上一个子节点)。child…等)
这是我的文件中的错误片段
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
}
好吧,我终于知道你到底在问什么了
New()。调用方得到的只是节点的值副本。因此,您打印的父对象始终是{Left:Right:Value:2}
因此addLeftNode()
和addRightNode()
也是如此
只是用指针,而不是价值来实现你的目标
看
我认为问题出在Visit()
方法上
当你看完左边的孩子后立即返回时,它将永远不会看望右边的孩子
左、右子项不是互斥的,因此第二个if子句不应使用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()
不应该返回任何值 问题源于不正确的类型检查。函数成功地处理了调用,但我使用的方法在确认是否分配了节点时并不准确
// 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))
}
在链接代码中,您的方法返回具体的,即非指针、结构值,并且在代码中没有任何地方返回nil
或将指针设置为nil
。因此,此parent.child.method(child)->[parent变为nil]
不能在提供的代码中发生。请尝试更好地解释您所说的“后续通话中的家长参考信息丢失”是什么意思。还请注意,如果您有一个返回其接收方的方法M
,则调用a.b.M(c)
将返回b
,而不是a
。例如,parent.Left.determineSide(child)
将返回Left
作为父项。嘿,感谢@mkopriva的响应。因此,您评论的最后一部分捕获了预期的行为。将函数视为遍历一系列相互关联的项(即图形、链表等)。正如您可能已经想象的那样,当我们浏览连接的项目时,我们希望在我们正在访问的节点上执行每个检查。例如,如果我们已经检查了A,那么我们要移动到站点B。如果B有一个连接的C,那么我们要检查它。在我的代码中,当我们从A移动到B时,无论出于什么原因,B都是零,然后我们无法检查C。如第一条注释中所述,您的代码似乎没有将任何内容设置为零,因此任何内容都不能自行“变为零”,它必须从一开始就为零。ie B没有变成零,从一开始就是零,不管B是什么。请包括实际打印输出的代码。显示如何使用节点
包。问题是由于类型检查错误引起的。isNode的实现没有正确实现,因此当类型检查无意中返回true时,后续调用将访问一个nil内存地址。嘿@Bob Fred感谢您签出了一些其他代码。很高兴知道这一点,但我认为您可能已经解决了另一个问题。我会尝试重新措辞——我想我提出了一个糟糕的问题。我试图解决的是,为什么在遍历一系列连接的链接结构时,当从a移动到B时,B变为零。我只是想从这一点继续下去-谢谢你帮我解决这个问题:)
// 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))
}