https://play.golang.org/p/5A-dnZVy2aA
func closeChannel(stream chan int) {
fmt.Println("closing the channel")
close(stream)
}
func main() {
chanOwner := func() <-chan int {
resultStream := make(chan int, 5)
go func() {
defer closeChannel(resultStream)
for i := 0; i <= 5; i {
resultStream <- i
}
}()
return resultStream
}
resultStream := chanOwner()
for result := range resultStream { //this blocks until the channel is closed
fmt.Printf("Received: %d\n", result)
}
fmt.Println("done receiving")
}
Output of program
closing the channel
Received: 0
Received: 1
Received: 2
Received: 3
Received: 4
Received: 5
done receiving
why is the closing the channel
statement printed before any Received
in the above program. since the channel is buffered with a capacity of 5, and we are inserting 6 elements into it, I was expecting it to block at the resultStream <- i
before a value was read and cleared up space in the buffer.
CodePudding user response:
The generator goroutine fills the channel to its capacity and blocks. The receiver for loops receives the first item from the channel, which enables the generator goroutine again. The generator goroutine runs to completion before the receiver for-loop can print the Received
message, printing the closing the channel
message. Then the receiver loop receives all remaining messages.