Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type agnostic channels in go

I'm still sort of wrapping my head around interfaces within golang. Is it possible to send multiple different types over a single, "generic" channel?

Here's a very simple example: http://play.golang.org/p/7p2Bd6b0QT.

like image 420
ben lemasurier Avatar asked Feb 28 '14 00:02

ben lemasurier


People also ask

What are Go channels?

In Golang, or Go, channels are a means through which different goroutines communicate. Think of them as pipes through which you can connect with different concurrent goroutines. The communication is bidirectional by default, meaning that you can send and receive values from the same channel.

What are directional channels in Go language?

This means channels can start out bidirectional, but magically become directional simply by assigning a regular channel to a variable of a constrained type. This is very useful for creating receive-only channels that no one can close but you.

Are Go channels FIFO?

Buffered channels in Go are always FIFO. The specification clearly says: Channels act as first-in-first-out queues. If the values coming out of the channel are not FIFO, then this is a bug in the channel implementation.

Do Go channels block?

When we send data into the channel using a GoRoutine, it will be blocked until the data is consumed by another GoRoutine. When we receive data from channel using a GoRoutine, it will be blocked until the data is available in the channel.


1 Answers

Yes, it's possible. For example in your code you could just use:

greet: make(chan pet)

And then you would be able to send seamlessly anything that implements type pet interface.

If you want to send something completely generic you can use a chan interface{} and then use reflect to find out what it is when you receive something.


A dumb - and probably not idiomatic - example:

ch := make(chan interface{})

go func() {
    select {
    case p := <-ch:
        fmt.Printf("Received a %q", reflect.TypeOf(p).Name())
    }
}() 
ch <- "this is it"

As BurntSushi5 points out, a type switch is better:

p := <-ch
switch p := p.(type) {
case string:
    fmt.Printf("Got a string %q", p)
default:
    fmt.Printf("Type of p is %T. Value %v", p, p)
}
like image 185
cnicutar Avatar answered Sep 28 '22 08:09

cnicutar