sescob27
sescob27

Reputation: 677

Golang Pointers as method param

I am working with golang's pointers the way I did with c++, but it seems not to work, which would be the right way to do it? or what am I doing wrong?, Thanks.

ftw I'm doing AsyncBinaryTrees.

type Obj interface {
    Compare(node Obj) int
}

type Tree struct {
    Item        Obj
    Rigth, Left *Tree
    height      int16
}

func Insert(t *Tree, item Obj) chan struct{} {
    done := make(chan struct{}, 1)
    go insert(t, item, done)
    return done
}

func insert(t *Tree, item Obj, done chan struct{}) {
    if t == nil {
        t = &Tree{Item: nil, Rigth: nil, Left: nil, height: 0}
        var signal struct{}
        done <- signal
        close(done)
    } else {
        if t.Item.Compare(item) == 1 { //Left
            insert(t.Left, item, done)
        } else if t.Item.Compare(item) == -1 { //Rigth
            insert(t.Right, item, done)
        } else {
            close(done)
            panic
        }
    }
}

//=== testing

func assertSignal(ch_signal chan struct{}, t *testing.T) {
    _, done := <-ch_signal
    if !done {
        t.Error("Error: it should send a signal of empty struct")
    }
}

func TestInsertion(t *testing.T) {
    var tree *Tree
    ch_signal := Insert(tree, newObjInt())
    fmt.PrintLn(t)             //=> <nil>
    assertSignal(ch_signal, t) //=>PASS
    ch_signal = Insert(tree, newObjInt())
    fmt.PrintLn(t)             //=> <nil>
    assertSignal(ch_signal, t) //=>PASS
    ch_signal = Insert(tree, newObjInt())
    fmt.PrintLn(t)             //=> <nil>
    assertSignal(ch_signal, t) //=>PASS
    ch_signal = Insert(tree, newObjInt())
    assertSignal(ch_signal, t) //=>PASS
}

nil

nil

nil

TEST PASS

Upvotes: 0

Views: 447

Answers (1)

James Henstridge
James Henstridge

Reputation: 43949

In your insert function you have:

func insert(t *Tree, item Obj, done chan struct{}) {
    if t == nil {
        t = &Tree{Item: nil, Rigth: nil, Left: nil, height: 0}
    ...
}

This updates the local variable t, but will not change the variable passed in the calling scope since Go passes function parameters by value. So when you make the following call:

insert(t.Left, item, done)

if t.Left is nil, its value will not be changed by the function call. If you do want it to update the variable, you'll need to define the function argument as t **Tree, change references to set *t instead, and change the call to:

insert(&t.Left, item, done)

There is no equivalent to C++'s syntax for passing function arguments by reference: instead you need to be explicit when passing pointers.

Upvotes: 3

Related Questions