我需要帮助才能理解为什么以下代码不起作用。我正在构建一个管道,并试图让一个步骤同步来自两个源通道的值。我的源代码/生产者代码看起来像下面(在我的实际代码中,我从文件中读取文本)。这些来源已经过排序,但不保证两个来源都有价值。
func Source() <-chan int{
out := make(chan int, 5)
go func() {
defer reader.Close()
out <- 1
out <- 2
out <- 3
out <- 4
out <- 5
out <- 7
close(out)
}()
return out
}
,同步代码如下所示:
func Sync(a, b <-chan int) <-chan int {
out := make(chan int)
go func() {
av, ak:= <-a
bv, bk:= <-b
for ak || bk {
if !ak || av < bv {
out <- bv
bv, bk = <-b
continue
}
if !bk|| bv > av {
out <- av
av, ak = <-a
continue
}
out <- av
av, ak = <-a
bv, bk = <-b
}
close(out)
}()
return out
}
我的程序看起来像这样:
func main() {
os := Source()
ns := Source()
for val := range Sync(ns, os) {
fmt.Printf("[SYNCED] %v \n", val)
}
}
预期的行为是我的两个源缓冲值到通道中,我的同步首先从第一个源读取值。然后从第二个。比较它们,如果它们相等则继续在两个通道中的下一个。如果不同,我们将发送后面的值并将其替换为新的值并再次进行相同的比较。
发生的事情是,看起来同步代码对值运行了好几次,我会多次得到[SYNCED] 1这样的东西。为什么呢?
请帮我解决这个问题!
答案 0 :(得分:2)
关于http://play.golang.org/p/uhd3EWrwEo和http://play.golang.org/p/Dqq7-cPaFq -
实际上,int的代码也会因类似的测试用例而失败:
os := Source([]int{1, 2, 3})
ns := Source([]int{1, 3, 4})
将整数版本置于无限循环中。
这是因为选中!aok || avalue > bvalue
时,如果aok
为真(某些元素仍在a
中)并且bok
为false,则不会考虑(b
中没有更多元素),然后avalue > ""
始终为真。所以它试图从b
中获取另一个项目(这是空的)并进入无限循环。固定代码:http://play.golang.org/p/vYhuOZxRMl