首页 > 解决方案 > 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

标签: gochannel

解决方案


Go 编程语言规范

在调用 close 之后,并且在接收到任何先前发送的值之后,接收操作将返回通道类型的零值,而不会阻塞。多值接收操作返回接收到的值以及通道是否关闭的指示。


您正在计算零值。

例如,

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)
}

游乐场: https: //play.golang.org/p/tPRkqXrAFno

输出:

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

Go 编程语言规范

对于语句

对于带有范围子句的语句

对于通道,产生的迭代值是通道上发送的连续值,直到通道关闭。如果通道为 nil,则范围表达式将永远阻塞。

Close 对于带有范围子句的 for 语句很有用。


推荐阅读