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 關注
- 222 瀏覽
添加回答
舉報