Channels offer synchronized communication
A channel is a mechanism for goroutines to synchronize execution and communicate by passing values.

A new channel value can be made using the built-in function make
.
// unbuffered channel of ints ic := make(chan int) // buffered channel with room for 10 strings sc := make(chan string, 10)
To send a value on a channel, use <-
as a binary operator. To receive a value on a channel, use it as a unary operator.
ic <- 3 // Send 3 on the channel. n := <-sc // Receive a string from the channel.
The <-
operator specifies the channel direction, send or receive. If no direction is given, the channel is bi-directional.
chan Sushi // can be used to send and receive values of type Sushi chan<- string // can only be used to send strings <-chan int // can only be used to receive ints
Buffered and unbuffered channels
- If the capacity of a channel is zero or absent, the channel is unbuffered and the sender blocks until the receiver has received the value.
- If the channel has a buffer, the sender blocks only until the value has been copied to the buffer; if the buffer is full, this means waiting until some receiver has retrieved a value.
- Receivers always block until there is data to receive.
- Sending or receiving from a
nil
channel blocks forever.
Closing a channel
The close
function records that no more values will be sent on a channel. Note that it is only necessary to close a channel if a receiver is looking for a close.
- After calling
close
, and after any previously sent values have been received, receive operations will return a zero value without blocking. - A multi-valued receive operation additionally returns an indication of whether the channel is closed.
- Sending to or closing a closed channel causes a run-time panic. Closing a nil channel also causes a run-time panic.
ch := make(chan string) go func() { ch <- "Hello!" close(ch) }() fmt.Println(<-ch) // Print "Hello!". fmt.Println(<-ch) // Print the zero value "" without blocking. fmt.Println(<-ch) // Once again print "". v, ok := <-ch // v is "", ok is false. // Receive values from ch until closed. for v := range ch { fmt.Println(v) // Will not be executed. }
Example
In the following example we let the Publish
function return a channel, which is used to broadcast a message when the text has been published.
// Publish prints text to stdout after the given time has expired. // It closes the wait channel when the text has been published. func Publish(text string, delay time.Duration) (wait <-chan struct{}) { ch := make(chan struct{}) go func() { time.Sleep(delay) fmt.Println(text) close(ch) }() return ch }
Note that we use a channel of empty structs to indicate that the channel will only be used for signalling, not for passing data. This is how you might use the function.
wait := Publish("important news", 2 * time.Minute) // Do some more work. <-wait // Block until the text has been published.