我看到无缓冲通道的工作方式不一致 - 这要么是 Go 中的不一致,要么是我对 Go 的理解......
这是一个带有输出的简单示例。“不一致”与“制作频道”行有关。
package main
import (
"fmt"
)
func send(sendto chan string) {
fmt.Println("send 1")
sendto <- "Hello"
fmt.Println("send 2")
sendto <- "World"
fmt.Println("send 3")
sendto <- ""
fmt.Println("send() exit")
}
func main() {
//hole := make(chan string)
//hole := make(chan string, 0)
hole := make(chan string, 1)
go send(hole)
fmt.Println("main loop")
carryon := true
for carryon {
msg := <- hole
if msg == "" {
carryon = false
} else {
fmt.Println(" recd ", msg)
}
}
}
当我按上述方式运行时,输出与预期一致(对于缓冲区大小为 2 也与预期一致)。即通道有一个缓冲区为 1,它保存一个值 - 在下一次尝试写入时,有一个上下文切换到 main 以允许它使用第一个值。
main loop
send 1
send 2
recd Hello
send 3
recd World
send() exit
然后,当我将 make 频道行更改为:
hole := make(chan string, 0)
输出是:
main loop
send 1
send 2
recd Hello
recd World
send 3
send() exit
我原以为send 2
and therecd Hello
会反过来……
我得到相同的输出hole := make(chan string)
我检查了规范,它说
容量(以元素数量计)设置通道中缓冲区的大小。如果容量为零或不存在,则通道是无缓冲的,并且只有在发送方和接收方都准备好时通信才会成功。否则,如果缓冲区未满(发送)或非空(接收),则通道被缓冲并且通信成功而不会阻塞。
请有人解释一下
- 为什么我的期望是错误的 - 请善待
- 或者 Go 是否真的错了
谢谢