首页 > 解决方案 > 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,但事实并非如此,并且选择了第二种情况。你能帮我理解这个场景吗?

标签: go

解决方案


永远不会选择通道的案例c1,因为没有从c1. 只有当它准备好读/写时才会选择一个通道。在这种情况下,c2它已准备好被读取,因为有一个 goroutine 等待写入它。如果您创建另一个从 读取的 goroutine c1,那么 c1c2都将准备就绪,并且将选择其中一个。

消息foo1 evaluated打印出来,因为 case 被立即评估(即 foo1 被调用),但是在将值发送到通道之前,case 被阻塞了。


推荐阅读