为什么我从关闭的通道接收值?

我正在调查渠道行为,我对他们的行为感到很困惑。规范说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.但是,即使到那时通道已关闭,我似乎仍然获得范围语句中的值。这是为什么?


package main


import "fmt"

import "sync"

import "time"


func main() {

    iCh := make(chan int, 99)

    var wg sync.WaitGroup

    go func() {

        for i := 0; i < 5; i++ {

            wg.Add(1)

            go func(i int) {

                defer wg.Done()

                iCh <- i

            }(i)


        }

        wg.Wait()

        close(iCh)

    }()

    time.Sleep(5 * time.Second)

    print("the channel should be closed by now\n")

    for i := range iCh {

        fmt.Printf("%v\n", i)

    }

    print("done")

}

编辑:似乎如果我close在通道范围之前移动语句,它将永远关闭它。所以我想知道为什么它也不适用于“time.Sleep”技巧。到那个时候(5 秒)所有的 go 例程都应该已经完成并且通道关闭了,不是吗?


白衣染霜花
浏览 198回答 1
1回答

慕侠2389804

Go 编程语言规范关闭对于通道 c,内置函数 close(c) 记录不会在通道上发送更多值。在调用 close 之后,并且在接收到任何先前发送的值之后,接收操作将在不阻塞的情况下返回通道类型的零值。在通道缓冲区中有 5 个先前发送的值,然后是关闭。例如,package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync"&nbsp; &nbsp; "time")func main() {&nbsp; &nbsp; iCh := make(chan int, 99)&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; for i := 0; i < 5; i++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; go func(i int) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iCh <- i&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }(i)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; &nbsp; &nbsp; close(iCh)&nbsp; &nbsp; }()&nbsp; &nbsp; time.Sleep(5 * time.Second)&nbsp; &nbsp; fmt.Println("previously sent values", len(iCh))&nbsp; &nbsp; for i := range iCh {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("%v\n", i)&nbsp; &nbsp; }&nbsp; &nbsp; print("the channel should be closed by now\n")&nbsp; &nbsp; print("done")}输出:previously sent values 501234the channel should be closed by nowdone
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go