选择go中的语句和所选案例
我有一个代码,试图理解为什么选择第二个案例而不是第一个 以下是一个例子:选择go中的语句和所选案例,go,Go,我有一个代码,试图理解为什么选择第二个案例而不是第一个 以下是一个例子: package main import ( "fmt" "time" "log" ) func foo1() string { log.Println("foo1 evaluated") return "quick thing" } func foo2(c chan string
package main
import (
"fmt"
"time"
"log"
)
func foo1() string {
log.Println("foo1 evaluated")
return "quick thing"
}
func foo2(c chan string) {
time.Sleep(5 * time.Second)
c <- "sleepy thing"
}
func main() {
c1 := make(chan string)
c2 := make(chan string)
go foo2(c2)
select {
case c1 <- foo1():
fmt.Println("received", <-c1)
case msg := <-c2:
fmt.Println("received", msg)
}
}
我希望第一个案例“更快”,因为我们已经准备好发送到c1,但事实并非如此,第二个案例被选中。您能帮助我理解这个场景吗?频道
c1
的案例将永远不会被选择,因为没有从c1
读取的goroutine。仅当通道准备好读/写时,才会选择该通道。在本例中,c2
已准备好读取,因为有一个goroutine正在等待写入。如果从c1
创建另一个goroutine读取,则c1
和c2
都将就绪,并将选择其中一个
打印消息foo1 evaluated
,因为案例会立即进行评估(即调用foo1),但案例会在值发送到通道之前被阻止。Per(emphasis mine):
“select”语句的执行分为几个步骤:
foo1进行了评估
,因为在选择案例
之前会调用foo1()
。这并不意味着选择了第一个案例-事实上,根据输出,选择了第二个案例,否则就不会打印收到的sleepy thing
无法选择第一个案例,因为
c1
的发送和接收在同一个goroutine(运行select
的goroutine)中,并且没有缓冲。我认为问题更多的是为什么要打印“foo1 evaluated”,这是因为所有案例都会立即进行评估,无论选择哪一个。通道上的发送和接收都是阻塞操作。如果你在一个频道上发送,而没有人接收,程序就会死锁。
2009/11/10 23:00:00 foo1 evaluated
received sleepy thing
Program exited.