Channels offer synchronized communication

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

sushi conveyor belt

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

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.

ch := make(chan string)
go func() {
    ch <- "Hello!"

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.


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() {
	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.

Share this page: