The following code produces an unexpected runtime error:
package main
import (
"fmt"
"sync"
)
func receiver(bChan <-chan int, wg *sync.WaitGroup) {
for val := range <-bChan {
fmt.Println("received", val)
}
wg.Done()
}
func main() {
wg := &sync.WaitGroup{}
bChan := make(chan int, 2)
bChan <- 1
bChan <- 2
wg.Add(1)
go receiver(bChan, wg)
bChan <- 3
bChan <- 4
close(bChan)
wg.Wait()
}
output:
received 0
fatal error: all goroutines are asleep - deadlock!
goroutine 1 \[chan send\]:
I did fix it after realizing I wrote the for loop wrong. When I Change for val := range <-bChan to for val := range bChan it runs as expected.
Why is there a deadlock? And also why is "received 0" printed?
range <-bChanis equivalent torange 1because 1 is the first value sent on the channel. This simply loops once and the loop value is zero.range <-bChanmeans you receive from the chan, and then range over the value that was received. It evaluates torange 1— the first value you sent into the channel.range Nmeans "iterate from 0 to N excluded", hence 0.<-bChanfirst, so I getfor val := range 1 {...}, "received 0" is printed and the loop ends. The main routine sends another valuebChan <- 3which is fine, but when it tries tobChan <- 4the channel is full (its capacity is 2, 2 and 3 are in it) so it blocks and I get a deadlock.