Fibonacci in Go using channels

1.6k views Asked by At

I am following the examples on tour.golang.org.

I understand the example mostly, the only issue I have is why does it stop when we pass 0 to quit channel? Regardless of whether 0 was passed to quit, there is always a value for x. So shouldn't select always fall on case 'c <- x' ?

func fibonacci(c chan int, quit chan int) {
    x, y := 0, 1
    for {
        select {
        case c <- x:
            x, y = y, x+y
        case <-quit:
            return
        }
    }
    close(c)
}

func main() {
    c := make(chan int)
    quit := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println(<-c)
        }
        quit <- 0
    }()
    fibonacci(c, quit)
}
1

There are 1 answers

0
thwd On BEST ANSWER

there is always a value for x. So shouldn't select always fall on case 'c <- x' ?

No, because this channel is unbuffered, the send will block until someone can receive from it.

Read about channels on Effective Go:

Receivers always block until there is data to receive. If the channel is unbuffered, the sender blocks until the receiver has received the value. If the channel has a buffer, the sender blocks only until the value has been copied to the buffer; if the buffer is full, this means waiting until some receiver has retrieved a value.

Additionally, if 2 cases in a select statement could proceed, one is picked pseudo-randomly.

If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection. Otherwise, if there is a default case, that case is chosen. If there is no default case, the "select" statement blocks until at least one of the communications can proceed.