0

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

4
  • 1
    What is not working? Well, except for obvious things like calling insert(t.Left, done) to a function that takes three arguments. Commented May 2, 2014 at 5:34
  • And closing done without sending any signal. Commented May 2, 2014 at 5:36
  • typo error i did a checkout so i replicate the error here, and i'm closing the channel because the item already exist so there is no signal of done Commented May 2, 2014 at 6:07
  • You have to initialize your Tree struct first: replace var tree *Tree with tree := new(Tree). Pointers are passed by values, so struct initialization from inside methods won't work as you expect it to: new reference (t = &Tree) won't leave method scope. See the illustration: play.golang.org/p/X33zMW7Nxh Commented May 2, 2014 at 6:51

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.