Goroutine Puzzle #1

Kuan
1 min readMar 8, 2018

--

I came across this “puzzle” when I was studying termbox-go source code and I can’t wrap my head around it. So I wrote a very simple package to test it out. Run it in your head first before you scroll further for answer and my naive reasoning.

package mainimport "fmt"func foo(c chan int) {
a := 0
for {
select {
case c <- a:
a = <-c
fmt.Println("foo received", a)
}
}
}
func main() {
c := make(chan int)
go foo(c)
loop:
for {
select {
case r := <-c:
fmt.Println("main received", r)
c <- (r + 1)
if r == 3 {
break loop
}
}
}
<-c
}

Please forgive this noob if you found this is too easy. I am not yet clock > 3 hours coding in GO yet, bear with me. So the answer is…

main received 0
foo received 1
main received 1
foo received 2
main received 2
foo received 3
main received 3
foo received 4

It was not obvious to me at the start when I was looking at the foo's select. I thought case c <- a will be selected, based on the wrong assumption that c channel is “empty” now and I can send 1 value inside. I pondered, searched, put more printf and finally this answer from StackOverflow enlightened me. In short…

sends do not complete until there is a receiver to accept the value.

Love GO.

--

--