Trần Kim Dự
Trần Kim Dự

Reputation: 6102

Go channel: consume data from channel although not push anything to channel

For example I have this code:

package main

import (
    "fmt"
)

func main() {

    c1 := make(chan interface{})
    close(c1)
    c2 := make(chan interface{})
    close(c2)

    var c1Count, c2Count int
    for i := 1000; i >= 0; i-- {
        select {
        case <-c1:
            c1Count++
        case <-c2:
            c2Count++
        }

    }
    fmt.Printf("c1Count: %d\nc2Count: %d\n  ", c1Count, c2Count)
}

When running, the output will be:

c1Count: 513
c2Count: 488

The thing I don't know is: we create c1 and c2 channel without doing anything. Why in select/case block, c1Count and c2Count can increase value ?

Thanks

Upvotes: 3

Views: 499

Answers (1)

peterSO
peterSO

Reputation: 166765

The Go Programming Language Specification

Close

After calling close, and after any previously sent values have been received, receive operations will return the zero value for the channel's type without blocking. The multi-valued receive operation returns a received value along with an indication of whether the channel is closed.


You are counting zero values.

For example,

package main

import (
    "fmt"
)

func main() {

    c1 := make(chan interface{})
    close(c1)
    c2 := make(chan interface{})
    close(c2)

    var c1Count, c2Count int
    var z1Count, z2Count int
    for i := 1000; i >= 0; i-- {
        select {
        case z1 := <-c1:
            c1Count++
            if z1 == nil {
                z1Count++
            }

        case z2 := <-c2:
            c2Count++
            if z2 == nil {
                z2Count++
            }
        }

    }
    fmt.Printf("c1Count: %d\nc2Count: %d\n", c1Count, c2Count)
    fmt.Printf("z1Count: %d\nz2Count: %d\n", z1Count, z2Count)
}

Playground: https://play.golang.org/p/tPRkqXrAFno

Output:

c1Count: 511
c2Count: 490
z1Count: 511
z2Count: 490

The Go Programming Language Specification

For statements

For statements with range clause

For channels, the iteration values produced are the successive values sent on the channel until the channel is closed. If the channel is nil, the range expression blocks forever.

Close is useful with a for statement with a range clause.

Upvotes: 4

Related Questions