🎓 A1Learner
🔍
0 of 34 lessons completed

Go Channels in Depth

A channel is a typed path that passes values between goroutines. A channel also has a length and a capacity, and it can be closed when no more values will arrive.

Length and capacity of a buffered channel

len gives the values waiting in a channel. cap gives the total room in its buffer.

package main

import "fmt"

func main() {
	ch := make(chan int, 3)
	ch <- 10
	ch <- 20
	fmt.Println(len(ch), cap(ch))
}

Close ends a range

close marks a channel as finished. A range loop reads the values until the channel closes and empties.

package main

import "fmt"

func main() {
	ch := make(chan int, 3)
	ch <- 10
	ch <- 20
	ch <- 30
	close(ch)
	for value := range ch {
		fmt.Println(value)
	}
}

Directional channels limit the flow

A chan<- parameter allows sending only. A <-chan parameter allows receiving only.

package main

import "fmt"

func send(out chan<- string) {
	out <- "ready"
}

func show(in <-chan string) {
	fmt.Println(<-in)
}

func main() {
	ch := make(chan string, 1)
	send(ch)
	show(ch)
}

A receive from a closed channel

A receive gives a second value that reports whether the channel is open. The second value is false once a closed channel has emptied.

package main

import "fmt"

func main() {
	ch := make(chan int)
	close(ch)
	value, ok := <-ch
	fmt.Println(value, ok)
}

Example

package main

import "fmt"

func produce(out chan<- int) {
	for number := 1; number <= 4; number++ {
		out <- number * 10
	}
	close(out)
}

func main() {
	ch := make(chan int)
	go produce(ch)
	sum := 0
	for value := range ch {
		sum += value
	}
	fmt.Println("Sum:", sum)
}

Key points

  • Values move along a channel from the goroutine that sends to the goroutine that receives.
  • len reports how many values wait in a channel.
  • cap reports how much room a buffered channel has in total.
  • Use close to mark a channel as finished.
  • A range loop over a channel stops when the channel closes and empties.
  • A chan<- channel allows sending only.
  • A <-chan channel allows receiving only.

In this example, produce runs as a goroutine and sends 10, 20, 30, and 40 into the channel. It then closes the channel. Main ranges over the channel and adds each value to sum. The range ends when the channel closes and empties, and the sum prints as 100.

Note

Only the sending side should close a channel.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Go Playground

Exercise

What does a receive from a closed and empty channel give?