go - 从 go 通道流中读取
问题描述
我试图理解从通道通道读取的以下代码。我在思考这个想法时遇到了一些困难。
bridge := func(done <-chan interface{}, chanStream <-chan <-chan interface{}) <-chan interface{} {
outStream := make(chan interface{})
go func() {
defer close(outStream)
for {
var stream <-chan interface{}
select {
case <-done:
return
case maybeSteram, ok := <-chanStream:
if ok == false {
return
}
stream = maybeSteram
}
for c := range orDone(done, stream) {
select {
case outStream <- c:
case <-done: // Why we are selection from the done channel here?
}
}
}
}()
return outStream
}
orDone
功能:
orDone := func(done <-chan interface{}, inStream <-chan interface{}) <-chan interface{} {
outStream := make(chan interface{})
go func() {
defer close(outStream)
for {
select {
case <-done:
return
case v, ok := <-inStream:
if ok == false {
return
}
select {
case outStream <- v:
case <-done: // Again why we are only reading from this channel? Shouldn't we return from here?
// Why we are not retuening from here?
}
}
}
}()
return outStream
}
正如评论中提到的,我需要一些帮助来理解我们为什么选择for c := range orDone(donem, stream)
. 谁能解释这里发生了什么?
提前致谢。
编辑
我从书中拿了代码concurrency in go
。完整的代码可以在这里找到:https ://github.com/kat-co/concurrency-in-go-src/blob/master/concurrency-patterns-in-go/the-bridge-channel/fig-bridge-频道.go
解决方案
在这两种情况下,选择都是为了避免阻塞——如果读取器没有从我们的输出通道读取,写入可能会阻塞(甚至可能永远阻塞),但是我们希望 goroutine 在done
通道关闭时终止,而无需等待还要别的吗。通过使用select
,它将等到任何事情发生,然后继续,而不是在检查之前无限期地等待写入完成done
。
至于另一个问题,“我们为什么不回到这里?”:嗯,我们可以。但我们不必这样做,因为关闭的通道一旦关闭就永远保持可读(产生无限数量的零值)。所以在那些“底层”什么都不做也没关系selects
;如果done
实际上是关闭的,我们将回到循环的顶部并点击case <-done: return
那里。我想这是风格问题。我可能会自己编写return
,但此示例的作者可能希望避免在两个地方处理相同的情况。只要它只是return
它并不重要,但如果你想对它做一些额外的操作done
,如果底部选择返回,则必须在两个地方更新该行为,但如果没有,则只在一个地方更新。
推荐阅读
- javascript - 为特定的 JS 文件挂钩 Javascript Onload
- python - 自定义张量流模型的 OOP 版本如何工作
- couchbase - N1QL 中的 REGEXP_CONTAINS 和 REGEXP_LIKE 有什么区别?
- python - Python - 计算所需的自然数个数
- tensorflow - 可视化增强的火车图像 [tensorflow object detection api]
- python - Python:为什么即使没有指示,列表值也会改变?
- python-3.x - 在列表理解中引发异常:语法无效
- html - 如何使用 flex 在父 div 内的 2 个兄弟 div 旁边设置 1 个 div?
- azure - 无法坚持使用 SSL 应用程序网关重定向的自定义域
- python - 如何使用 python 为原始音频信号添加不同级别的音频分贝(dB)噪声?