在一个 select 案例中从一个通道读取并写入另一个通道

Read from one channel and write to another within one select-case

考虑这个 Go 代码,它将立即调用 worker.DoWork(),然后每分钟调用一次:

triggerChan := make(chan time.Time, 1)
triggerChan <- time.Now() // We don't want to wait a minute for the first call of worker.DoWork() to happen.
ticker := time.NewTicker(time.Minute)
defer ticker.Stop()
for {
    select {
    case triggerChan <- <-ticker.C:
    case <-triggerChan:
        worker.DoWork()
    }
}

在第一个 select 之前将值写入 triggerChan 以将其定向到 case <-triggerChan 以便立即调用 worker.DoWork()。但是,如果 ticker.C 已经有一个可用值(如果我们使用 time.Microsecond 而不是 time.Minute 之类的东西并不是那么不可能),会发生什么?运行时是否会看到 triggerChan <- <-ticker.C 会阻塞,或者它会愉快地软锁定而不知道 <-ticker.C 的结果正在尝试做什么?它是否意识到这种“从频道到频道”的情况?

select 根据 triggerChan 的状态决定,但是它首先计算发送操作的右侧表达式。 所以在进入时,它将等到 <-ticker.C returns。然后它会从通道中读取第一个值,然后写入它...