在频道中选择

时间:2016-06-07 22:59:05

标签: go

以下是select的一个示例代码。我不明白为什么第二个选择没有执行第一个案例?输出似乎是:

messages := make(chan string)
signals := make(chan bool)

// Here's a non-blocking receive. If a value is
// available on `messages` then `select` will take
// the `<-messages` `case` with that value. If not
// it will immediately take the `default` case.
select {
case msg := <-messages:
    fmt.Println("received message", msg)
default:
    fmt.Println("no message received")
}

// A non-blocking send works similarly.
msg := "hi"
select {
case messages <- msg:
    fmt.Println("sent message", msg)
default:
    fmt.Println("no message sent")
}

// We can use multiple `case`s above the `default`
// clause to implement a multi-way non-blocking
// select. Here we attempt non-blocking receives
// on both `messages` and `signals`.
select {
case msg := <-messages:
    fmt.Println("received message", msg)
case sig := <-signals:
    fmt.Println("received signal", sig)
default:
    fmt.Println("no activity")
}

运行代码后,输出:

no message received
no message sent
no activity

更新:我知道为什么第二个选择现在变为默认值。第三个呢?

1 个答案:

答案 0 :(得分:3)

messages是无缓冲的,没有其他Go例程被阻止等待收到某些内容。由于发送操作将被阻止,因此执行default情况。

将此与buffered channelwhen another Go routine is blocked reading on the channel的行为进行比较。

来自language specification

  
      
  1. 如果一个或多个通信可以继续,则可以通过统一的伪随机选择来选择可以继续的单个通信。否则,如果存在默认情况,则选择该情况。
  2.