# Range over channels in Go

It’s common to see range clause with array, slice, string or map as an expression’s type:

`m := make(map[string]float64)m["oneone"] = 1.1m["twotwo"] = 2.2for key, value := range m {    fmt.Printf("[%s]: %.1f\n", key, value)}`
`a := [3]int{3, 2, 1}for idx, value := range a {    fmt.Printf("[%d]: %d\n", idx, value)}`
`s := []int{30, 20, 10}for idx, value := range s {    fmt.Printf("[%d]: %d\n", idx, value)}`
`name := "Michał"for idx, code := range name {    fmt.Printf("[%d]: %q\n", idx, code)}`

output:

`[oneone]: 1.1[twotwo]: 2.2[0]: 3[1]: 2[2]: 1[0]: 30[1]: 20[2]: 10[0]: 'M'[1]: 'i'[2]: 'c'[3]: 'h'[4]: 'a'[5]: 'ł'`

What is also possible is to iterate through values sent over a channel. To break such iteration channel needs to be closed explicitly. Otherwise range would block forever in the same way as for nil channel. Let’s see an example:

`package main`
`import "fmt"`
`func FibonacciProducer(ch chan int, count int) {    n2, n1 := 0, 1`
`    for count >= 0 {        ch <- n2        count--        n2, n1 = n1, n2+n1    }    close(ch)}`
`func main() {    ch := make(chan int)    go FibonacciProducer(ch, 10)    idx := 0    for num := range ch {        fmt.Printf("F(%d): \t%d\n", idx, num)        idx++    }}`

output:

`F(0): 0F(1): 1F(2): 1F(3): 2F(4): 3F(5): 5F(6): 8F(7): 13F(8): 21F(9): 34F(10): 55`

Index variable is not allowed when range expression is a channel (source code):

`ch := make(chan int)go FibonacciProducer(ch, 10)for idx, num := range ch {    fmt.Printf("idx: %d F(%d): \t%d\n", idx, num)}`

as it gives `too many variables in range error` while compilation. Spec says about such case explicitly (here):

If the range expression is a channel, at most one iteration variable is permitted, otherwise there may be up to two.

👏👏👏 below to help others discover this story. Please follow me here or on Twitter if you want to get updates about new posts or boost work on future stories.