7.2.5 非缓冲的Channel,1. Happens before。第一版,352页,倒数第4行。
“针对非缓冲通道的接收操作会在与之相对应的发送操作完成之前完成。”
上面这一句话不能说完全错误,只是没有把事情说完全了。完整的说法是
“发送语句与接收语句,这两种语句同时执行,非缓冲通道才能成功传递值。先触发的语句会被阻塞,阻塞的语句后结束。”具体的来说,分为两种情况:
1. 触发发送语句,没有接收语句→→→发送语句阻塞,等待接收语句→→→触发接收语句,唤醒发送语句→→→传值成功→→→接收语句结束→→→发送语句结束。
2. 触发接收语句,没有发送语句→→→接收语句阻塞,等待发送语句→→→触发发送语句,唤醒接收语句→→→传值成功→→→发送语句结束→→→接收语句结束。
我把书上P353的代码中,发送语句和接收语句的位置换了一下位置,得到以下代码。也可以这里查看:https://play.golang.org/p/SAOWZqK6LI
``` go
package main
import (
"fmt"
"time"
)
func main() {
unbufChan := make(chan int)
go func() {
fmt.Println("2.Sleep one second before sending..")
time.Sleep(time.Second)
unbufChan <- 1
fmt.Println("3.Sent 1")
}()
fmt.Println("1.Waiting to receive")
num := <-unbufChan
fmt.Printf("4.Received %d n", num)
}
//output
//1.Waiting to receive
//2.Sleep one second before sending..
//3.Sent 1
//4.Received 1
```