drwo32555 2018-12-29 08:03
浏览 111
已采纳

调用struct属性方法时Golang struct指针引用丢失

I'm attempting to use a struct to manage accessing nodes on a tree. Whenever I access the method of the parent's child node, the parent reference on the subsequent call gets lost (i.e. parent.child.method(child) -> [parent becomes nil]-> parent(the previous child).child ... etc).

Here is the error snippet from my file.

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
 }

I attempted to solve this by trying to find a way to inform the method that the new reference should be parent.Left. Things like using *parent.Left and &parent.Left didn't seem to be correct.

A solution may might be to move this code outside of the struct and have another function handle the outcome for a quick fix, but I'd like to understand why this isn't working out of the box. Thought process here is influenced by using this.child.determineSide(child).

Full code is here.

Edit

Here is some output from the terminal that might give even further context. Looks like I'm having a check type issue leading to the problem.

parent &{<nil> <nil> 2}
parent.Left <nil>
parent.LeftNode true
child &{<nil> <nil> 1}
parent <nil>
child &{<nil> <nil> 1}
  • 写回答

2条回答 默认 最新

  • dongtong848825 2018-12-29 08:33
    关注

    Okay, I know what u'r exactly asking finally.

    New() methods returns a value, not a pointer, which means u can't see later change in caller. What the caller got is only a value copy of the Node. So the parent what u print will always be {Left:<nil> Right:<nil> Value:2}.

    So the same with addLeftNode() and addRightNode().

    Just use pointer, not value to achieve your goal.

    See pointers_vs_values


    I think it's just the Visit() method where the problem is.

    1. It will never visit right child when u immediately return after visited left child.
    2. The left and right child are not mutually exclusive, so the second if-clause should not use else if, which would be if.
    3. The visiting order also has problem.

    Before:

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

    Modified:

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

    Additionally, as to me, Visit() shouldn't return any values.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 安装svn网络有问题怎么办
  • ¥15 Python爬取指定微博话题下的内容,保存为txt
  • ¥15 vue2登录调用后端接口如何实现
  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥15 latex怎么处理论文引理引用参考文献