2

在某些情况下您需要关闭频道,而在某些情况下则不需要。

http://play.golang.org/p/piJHpZ2-aU

queue := make(chan string, 2)
queue <- "one"
queue <- "two"
close(queue)

for elem := range queue {
    fmt.Println(elem)
}

我在这里

fatal error: all goroutines are asleep - deadlock!

而此代码的关闭是可选的

http://play.golang.org/p/Os4T_rq0_B

jobs := make(chan int, 5)
done := make(chan bool)

go func() {
    for {
        j, more := <-jobs
        if more {
            fmt.Println("received job", j)
        } else {
            fmt.Println("received all jobs")
            done <- true
            return
        }
    }
}()

for j := 1; j <= 3; j++ {
    jobs <- j
    fmt.Println("sent job", j)
}
close(jobs)
fmt.Println("sent all jobs")

<-done
// close(done)
4

1 回答 1

6

range第一个示例,由于使用了关键字,需要关闭通道。当 range 与通道一起使用时,它将继续尝试从通道读取,直到通道关闭。

来自http://golang.org/ref/spec#For_statements

[当使用rangefor] ...channels 时,产生的迭代值是在通道上发送的连续值,直到通道关闭。如果通道为 nil,则范围表达式将永远阻塞。

这意味着您必须关闭通道才能退出循环。

在第二个示例中,您使用的是接收运算符<-。该运算符将阻塞,直到可以将一个项目拉出通道。由于通道中有一个项目等待交付,因此它将立即产生。在这种情况下,关闭是可选的,因为在那之后通道上没有其他阻塞操作,所以保持“打开”同样高兴。

有关更多详细信息,请参阅频道部分...

于 2013-11-02T21:07:32.287 回答