Similar to slices and maps, channels can be ranged over.
foritem:=rangech{// item is the next value received from the channel}
This example will receive values over the channel (blocking at each iteration if nothing new is there) and will exit only when the channel is closed.
Assignment
It's that time again, Textio is hiring and we've been assigned to do the interview. The Fibonacci sequence is Textio's interview problem of choice. We've been tasked with building a small toy program we can use in the interview.
Complete the concurrentFib function. It should:
Create a new channel of ints
Call fibonacci concurrently
Use a range loop to read from the channel and append the values to a slice
Return the slice
exercise.go
packagemainfuncconcurrentFib(nint)[]int{// ?}// don't touch below this linefuncfibonacci(nint,chchanint){x,y:=0,1fori:=0;i<n;i++{ch<-xx,y=y,x+y}close(ch)}
Solution
The range loop on a channel keeps receiving until the channel is closed.
fibonacci() is responsible for calling close(ch) after sending n values, so the range loop terminates cleanly.
Because concurrentFib reads from the channel, the sender won’t deadlock on ch <- x (it’ll block until you receive, which is fine).
package main
func concurrentFib(n int) []int {
// Create new channel of ints
intChannel := make(chan int)
// Call fibonacci concurrently
go fibonacci(n, intChannel)
// Create slice to store values from channel
result := []int{}
// Use range loop to read from channel and append to slice
for item := range intChannel {
result = append(result, item)
}
return result
}
// don't touch below this line
func fibonacci(n int, ch chan int) {
x, y := 0, 1
for i := 0; i < n; i++ {
ch <- x
x, y = y, x+y
}
close(ch)
}