调用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}

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.

Problem originated from incorrect type checking. The function successfully handled the call, but the method I was using wasn't accurate in confirming whether a node was assigned.

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