In the previous article you saw how to use range on data structures including slices and arrays. The range keyword can also be used on a channel.

By doing so, it will iterate over every item thats send on the channel. You can iterate on both buffered and unbuffered channels, but buffered channels need to be closed before iterating over them.

Range

Iterate over buffered channel

The range keyword can be used on a buffered channel. Suppose you make a channel of size 5 with make(chan int, 5). Then store a few numbers into it channel <- 5, channel <- 3 etc.

You can then iterate over every item that was sent into the channel with the range keyword.


package main

import "fmt"

func main() {
    channel := make(chan int, 5)
    channel <- 5
    channel <- 3
    channel <- 9
    close(channel)

    for element := range channel {
        fmt.Println(element)
    }
}
    $ go run example.go
    5
    3
    9

The channel is closed with close(channel) before iteration it. That’s why it will terminate after 3 items.

Iterate over channel

You can use the range statement even with unbuffered channels. Say you create a goroutine f(c chan int), which pushes the current second into the channel each second.

First create a channel, say of integers: channel := make(chan int).

Then create the goroutine:


func f(c chan int) {
    for {
        c <- time.Now().Second()
        time.Sleep(time.Second)
    }
}

Then start the goroutine with go f(channel). Every second there is a number pushed into the channel.

You can iterate over this channels with the range keyword:


for element := range channel {
    fmt.Println(element)
}