go - go中的select语句和选定的案例
问题描述
我有一个代码https://play.golang.org/p/y5FGVfXdzC3,并试图理解为什么选择第二种情况而不是第一种。
这是示例:
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)
}
}
输出
2009/11/10 23:00:00 foo1 evaluated
received sleepy thing
Program exited.
我希望第一种情况“更快”,因为我们已经准备好发送到 c1,但事实并非如此,并且选择了第二种情况。你能帮我理解这个场景吗?
解决方案
永远不会选择通道的案例c1
,因为没有从c1
. 只有当它准备好读/写时才会选择一个通道。在这种情况下,c2
它已准备好被读取,因为有一个 goroutine 等待写入它。如果您创建另一个从 读取的 goroutine c1
,那么 c1
和c2
都将准备就绪,并且将选择其中一个。
消息foo1 evaluated
打印出来,因为 case 被立即评估(即 foo1 被调用),但是在将值发送到通道之前,case 被阻塞了。
推荐阅读
- python - 是否可以从本地计算机访问(而不是复制)远程文件?
- node.js - 使用 nginx 代理在非索引路由上快速创建 404 错误,但不在本地
- c - 我在下面所做的编码的“性别”部分应该有什么变化?
- javascript - 从子组件更新状态并返回组件
- django - Django - 无法访问管理员登录页面
- java - Android Studio:带或文本的分隔线
- vhdl - 将双向记录分配给另一个记录的可重用方法
- django - Django urls 处理带有斜线的 slug,例如 /main/subpage
- python - 如何从段列表中返回最大的 x 坐标和最大的 y 坐标?
- javascript - 每次使用 API 调用限制更改状态时如何重新渲染?