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?