Essential Go  Edit on GitHub      File Issue

Channels and select

A channel is a thread-safe queue of values of a given type.

A primary use for channels is to communicate between goroutines.

For that reason we talk about sending values to a channel (ch <- value) and receving values from a channel (value <- ch).

Basic of channels:

func genInts(chInts chan int) {
	chInts <- rand.Intn(1000)
}

func main() {
	chInts := make(chan int)
	for i := 0; i < 2; i++ {
		go genInts(chInts)
	}
	n := <-chInts
	fmt.Printf("n: %d\n", n)

	select {
	case n := <-chInts:
		fmt.Printf("n: %d\n", n)
	}
}
n: 81
n: 887

A zero value of a channel is nil so the first thing to do is to create a channel with make(chan ${type}).

Send operator chan <- value enqueues value at the end.

If channel is full, <- will block.

Send on a nil channel blocks forever.

Retrieve statement value = <- chan picks up the value from the front of the queue.

If channel is empty, retrieve will block.

Another way to retrieve a value form channel is to use select statement.

Using select allows to wait on multiple channels, do a non-blocking wait and implement timeouts.

Yet another is to use range.

Channels have a fixed capacity.

Channel created with make(chan bool) is called unbuffered channel. Send on unbuffered channel blocks until a corresponding receive.

Channel created with make(chan int, 3) is a channel of integers with capacity of 3. It’s called a buffered channel.

The first 3 sends will finish immediately, the 4th will block until a value is recieved from a channel.

You can close a channel with close(chan).

Closing channel twice panics.

Sending to closed channel panics.

A receive from closed channels returns zero value immediately.

A closed channel finishes range over a channel.

  ↑ ↓ to navigate     ↵ to select     Esc to close