这个例子中的通道是如何工作的?

这是素数筛的一个例子


package main


func Generate(ch chan<- int) {

  for i := 2; ; i++ {

    ch <- i

  }

}


func Filter(in <-chan int, out chan<- int, prime int) {

  for {

    i := <-in

    if i%prime != 0 {

      out <- i

    }

  }

}


func main() {

  ch := make(chan int)

  go Generate(ch)

  for i := 0; i < 10; i++ {

    prime := <-ch

    print(prime, "\n")

    ch1 := make(chan int)

    go Filter(ch, ch1, prime)

    ch = ch1

  }

}

我理解的是这行代码


prime := <-ch

通道正在等待输入并分配给素数。那么,为什么在调用下一条语句时不打印所有数字


print(prime, "\n")

如果我删除最后 3 行


ch1 := make(chan int)

go Filter(ch, ch1, prime)

ch = ch1

那么所有的数字都从 2 到 11 打印出来。这行 ch = ch1 有什么作用?


PIPIONE
浏览 197回答 2
2回答

不负相思意

您的代码的输出是:2357111317192329所以程序是这样的:我=0,之后prime := <-ch,素数=2,ch={3};之后go Filter(ch, ch1, prime),标记为Filter0,在函数中Filter0channelin将是 3,4,5,6 ... 并且 channelout将是 3,5,7 ...;之后ch = ch1,所以 ch = {3},即 3,5,7。我=1,之后prime := <-ch,素= 3,CH = {5},为什么会出现5在ch“因为现在?ch是ch1在最后一环;之后go Filter(ch, ch1, prime),标记为Filter1,在函数中Filter1channelin将是 5,7,9,11 ... 并且 channelout将是 5,7,11 ...;之后ch = ch1,所以 ch = {3},即 5,7,11。i=2,相同。那它怎么输出。

波斯汪

并非所有数字都被打印的原因是因为它在循环的每次迭代中都不是同一个通道。它创建一个新通道 ch1 并将值从 ch 过滤到 ch1,然后将 ch 分配给 ch1,以便下一次迭代 ch 是来自前一次迭代(称为 ch1)的新通道,并且那里的值已被过滤器过滤协程。这是另一种编写它的方法,可能对您更有意义:for i := 0; i < 10; i++ {&nbsp; &nbsp; prime := <-ch&nbsp; &nbsp; print(prime, "\n")&nbsp; &nbsp; oldch := ch&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //here oldch references the old channel&nbsp; &nbsp; ch = make(chan int)&nbsp; //and here ch is replaced with a new channel&nbsp; &nbsp; go Filter(oldch, ch, prime) //and here a filter is applied to values from oldch to ch}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go