package main
import (
"log"
"time"
)
var intBufChan = make(chan int, 2)
func main() {
select {
case <-time.After(time.Second):
log.Printf("select case 1\n")
case getIntBufChan() <- getInt(2):
log.Printf("select case 2\n")
}
}
func getInt(i int) int {
log.Printf("get int sleep 2s...\n")
time.Sleep(2 * time.Second)
log.Printf("get int %d\n", i)
return i
}
func getIntBufChan() chan int {
log.Printf("get int buf chan\n")
return intBufChan
}
在上面的代码中,是一定会打印出select case 1吗?不一定,其实是两个case都有可能执行,原因是在select的在对chan进行通信操作之前,会对case的表达式进行一次求值运算,其结果将作为接收或发送操作的通道,以及相应待发送的值。
所以这段代码的执行顺序:
第一种结果选择 case 1,执行顺序为:time.After(time.Second) → getIntBufChan() → getInt(2) → time.Sleep(2 * time.Second) → fmt.Printf("select case 1\n")
第二种结果选择 case 2,执行顺序为:time.After(time.Second) → getIntBufChan() → getInt(2) → time.Sleep(2 * time.Second) → fmt.Printf("select case 2\n")
不管怎么样,都要等getInt()函数执行完后,select才会开始对通道的通信进行操作!而getInt()函数执行完,两个case的通道都是ready的,所以结果是随机的。