gpt4 book ai didi

go - 从 go channel 流中读取

转载 作者:数据小太阳 更新时间:2023-10-29 03:32:14 28 4
gpt4 key购买 nike

我试图理解以下从一个 channel 中读取的代码片段。我在思考这个想法时遇到了一些困难。

    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-channel.go

最佳答案

在这两种情况下,选择都是为了避免阻塞——如果读取器没有从我们的输出 channel 读取,写入可能会阻塞(甚至永远阻塞),但我们希望 goroutine 在 done 时终止。 channel 已关闭,无需等待任何其他内容。通过使用 select , 它会等到 任一个 发生,然后继续,而不是在检查 done 之前无限期地等待写入完成.

至于另一个问题,“我们为什么不返回这里?”:好吧,我们可以。但是我们不必,因为关闭的 channel 一旦关闭就永远保持可读(产生无限数量的零值)。所以在那些“底部”什么都不做是可以的selects ;如果done实际上是关闭的,我们将回到循环的顶部并点击 case <-done: return那里。我想这是一个风格问题。我可能会写 return我自己,但是这个示例的作者可能想避免在两个地方处理相同的情况。只要是return就可以了这并不重要,但如果您想对 done 执行一些附加操作,如果底部选择返回,则必须在两个地方更新该行为,但如果没有返回,则只能在一个地方更新。

关于go - 从 go channel 流中读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57344095/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com