2 回答
TA贡献1859条经验 获得超6个赞
for ... range仅当从通道接收到所有值并且通道已关闭时,通道上的操作才会终止。
在您的示例中,您希望在延迟函数中关闭通道,但这只会在main()返回时运行。但main()只有在循环结束时才会返回。这就是死锁的原因。循环for等待通道关闭,关闭通道等待for循环结束。
当您使用循环从通道接收恰好 5 个值时,它会起作用,因为启动的 Goroutine 会在其上发送 5 个值。该循环不会等待通道关闭,因此循环可以结束,函数也可以结束main()。
这就是为什么发送者应该关闭通道(而不是接收者),问题就立即解决:
func sendValues(myIntChannel chan int) {
for i := 0; i < 5; i++ {
myIntChannel <- i //sending value
}
close(myIntChannel)
}
func main() {
myIntChannel := make(chan int)
go sendValues(myIntChannel)
for value := range myIntChannel {
fmt.Println(value) //receiving value
}
}
输出(在Go Playground上尝试):
0
1
2
3
4
TA贡献1795条经验 获得超7个赞
用稍微不同的术语来解释它,您的代码的作用是:
func main() {
...
while myIntChannel is not closed {
...
}
close myIntChannel
}
现在您可以看到僵局从何而来。
虽然上面的答案是有效的,但如果您更喜欢使用,您也可以尝试这个defer:
func sendValues(myIntChannel chan int) {
defer close(myIntChannel)
for i := 0; i < 5; i++ {
myIntChannel <- i //sending value
}
}
func main() {
myIntChannel := make(chan int)
go sendValues(myIntChannel)
for value := range myIntChannel {
fmt.Println(value) //receiving value
}
}
- 2 回答
- 0 关注
- 151 浏览
添加回答
举报