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))
    }