-4

I am trying to implement a tree in Go.

type BinaryNode struct {
    left  *BinaryNode
    right *BinaryNode
    data  int
}

type BinaryTree struct {
    root *BinaryNode
}

Now to insert elements , I have an insert func,

func (t *BinaryNode) insertNode(d int) {
    fmt.Printf("%+v\n", t)
    if t == nil {
        t = &BinaryNode{
            data:  d,
            left:  nil,
            right: nil,
        }
        fmt.Printf("%+v inside insert\n", t)
    } else {
        if d <= t.data {
            t.left.insertNode(d)
        } else {
            t.right.insertNode(d)
        }
    }
}

If the pointer is nil, create a new node, if not look for left or right, according to the data. In my main function , i am trying simple few steps :

func main() {
    tree1 := &BinaryTree{
        root: nil,
    }
    tree1.root.insertNode(3)
    fmt.Printf("%+v\n", tree1.root)
}

What i expect to see is a tree with root value 3. but i do not see any. Instead I get:

<nil>
&{left:<nil> right:<nil> data:3} inside insert
<nil>

From what I have understood, if the struct pointer is used for methods, a copy is not made. In that case, the modification should persist.

What have I missed here?

JimB
  • 104,193
  • 13
  • 262
  • 255
Brotchu
  • 115
  • 1
  • 8
  • 3
    You can't do that. You have to come up with another design for what you're trying to accomplish. `t = &BinaryNode{` updates the `t` variable inside the method, and since `t` inside the method is a copy of the receiver outside the method, the caller won't see the change. If you wanted to update the data that `t` points to you would have to do `*t = BinaryNode{...` but doing `*t` when `t` is `nil` will cause a runtime panic, so, you need another design. – mkopriva Feb 09 '21 at 17:22
  • 3
    You have to either pass a `**BinaryNode` and modify the pointed value, or return the new `*BinaryNode`. See possible duplicate: [Can the pointer in a struct pointer method be reassigned to another instance?](https://stackoverflow.com/questions/35421495/can-the-pointer-in-a-struct-pointer-method-be-reassigned-to-another-instance/35426997#35426997) – icza Feb 09 '21 at 17:27
  • Ah, so , even if the method is called using a pointer as `(t *BinaryNode) insertNode` , t will be a copy ? I was under the assumption that , in this case it will not be so. – Brotchu Feb 09 '21 at 17:32
  • 3
    Yes, it is a copy of the pointer, and a pointer is just a value pointing to another value. – mkopriva Feb 09 '21 at 17:35
  • 1
    Everything in Go is passed by copy always. – Volker Feb 09 '21 at 19:49

1 Answers1

1

this is i thing a simplest solution you can do, i hope its self explanatory

type Bin struct {
    left, right *Bin
    value       int
}

func New(value int) *Bin {
    return &Bin{value: value}
}

func (b *Bin) Insert(value int) {
    if value <= b.value {
        if b.left == nil {
            b.left = New(value)
        } else {
            b.left.Insert(value)
        }
    } else {
        if b.right == nil {
            b.right = New(value)
        } else {
            b.right.Insert(value)
        }
    }
}
Jakub Dóka
  • 2,477
  • 1
  • 7
  • 12
  • yes. My assumption was directly modifying the Bin pointer will persist after the function call. But it is a copy pointing to the same struct. I have tried this, and it works. – Brotchu Feb 12 '21 at 05:46