views:

400

answers:

3

All the examples I've seen so far involve blocking to get the result (via the <-chan operator).

My current approach involves passing a pointer to a struct:

type goresult struct {
    result resultType;
    finished bool;
}

which the goroutine writes upon completion. Then it's a simple matter of checking finished whenever convenient. Do you have better alternatives?

What I'm really aiming for is a Qt-style signal-slot system. I have a hunch the solution will look almost trivial (chans have lots of unexplored potential), but I'm not yet familiar enough with the language to figure it out.

+4  A: 

Select statements allows you to check multiple channels at once, taking a random branch (of the ones where communication is waiting):

func main () {
    for {
    select {
        case w := <- workchan:
            go do_work(w)
        case <- signalchan:
            return
        // default works here if no communication is available
        default:
            // do idle work
    }
    }
}

For all the send and receive expressions in the "select" statement, the channel expressions are evaluated, along with any expressions that appear on the right hand side of send expressions, in top-to-bottom order. If any of the resulting operations can proceed, one is chosen and the corresponding communication and statements are evaluated. Otherwise, if there is a default case, that executes; if not, the statement blocks until one of the communications can complete.

kaizer.se
@Jurily: Are you sure about that? It should be correct, but would look better without the space after `<-`.
kaizer.se
+10  A: 

You can use the "comma, ok" pattern (see their page on "effective go"):

foo     := <- ch; // This blocks.
foo, ok := <- ch; // This returns immediately.
James Antill
+1  A: 

You can also peek at the channel buffer to see if it contains anything by using len:

if len(channel) > 0 {
  // has data to receive
}

This won't touch the channel buffer, unlike foo, gotValue := <- ch which removes a value when gotValue == true.

Bill Casarin