1 回答

TA贡献1780条经验 获得超5个赞
你的maingoroutine 在没有与 emit goroutine 协调的情况下结束以知道它已经完成。当到达结束时main,程序 - 以及它的所有 goroutines - 都会结束,无论是否有任何 goroutine 仍在处理中,除非你明确地等待它们。
关闭通道有助于将goroutine 的完成情况传达给. 在这种情况下,使用从通道读取的二值响应,如emitmain
word, ok = <-wordChannel
确实将通道的状态(打开或关闭)暴露给main,但您从不使用它来控制 main 的流。此外,您有一个确切的硬编码到 main中的读取次数。因此,即使您使用通道关闭来控制流量,您也永远不会尝试最终读取以查看关闭的通道。
幸运的是,使用 go 的解决方案非常简单。 range在一个 go 通道上 ing 将读取值,直到通道关闭。因此,您可以简化您的代码,删除通道接收的显式数量,并使用通道 close 来表示emit完成,所有这些都使用这个更简洁的版本:
package main
import "fmt"
func emit(c chan string) {
words := []string{"The", "quick", "brown", "fox", "ran", "away"}
for _, word := range words {
fmt.Printf("send %s\n", word)
c <- word
}
fmt.Printf("Close the channel\n")
close(c)
}
func main() {
wordChannel := make(chan string)
go emit(wordChannel)
for word := range wordChannel {
fmt.Printf("receive %s \n", word)
}
}
当我运行它时,我得到了我认为是您想要的输出:
$ go run t.go
send The
send quick
receive The
receive quick
send brown
send fox
receive brown
receive fox
send ran
send away
receive ran
receive away
Close the channel
这个“ rangeover a channel”语法在概念上等同于这样的东西,只是看起来更优雅一点:
func main() {
wordChannel := make(chan string)
go emit(wordChannel)
for {
if word, ok := <-wordChannel; ok {
fmt.Printf("receive %s \n", word)
} else {
break
}
}
}
- 1 回答
- 0 关注
- 93 浏览
添加回答
举报