1

这是素数筛的一个例子

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 做什么?

谢谢

4

2 回答 2

3

您的代码输出是:

2
3
5
7
11
13
17
19
23
29

所以程序是这样的:

我=0,

之后prime := <-ch,素数=2,ch = {3};

之后go Filter(ch, ch1, prime),标记为Filter0,in 函数Filter0通道in将为 3,4,5,6 ...,通道out将为 3,5,7 ...;

之后ch = ch1,所以 ch = {3},这将是 3,5,7。

我=1,

prime := <-ch,prime= 3, ch ={5} 之后,为什么在里面5ch因为现在chch1最后一个循环;

之后go Filter(ch, ch1, prime),标记为Filter1,in function Filter1channelin将是 5,7,9,11 ... 并且 channelout将是 5,7,11 ...;

之后ch = ch1,所以 ch = {3},这将是 5,7,11。

i=2,同样。

那它是如何输出的。

于 2014-08-29T08:14:52.297 回答
1

并非所有数字都被打印的原因是因为它在循环的每次迭代中都不是同一个通道。它创建一个新通道 ch1 并将 ch 中的值过滤到 ch1 中,然后将 ch 分配给 ch1,以便下一次迭代 ch 是上一次迭代的新通道(称为 ch1),并且那里的值已被过滤器过滤协程。

这是另一种编写方式,可能对您更有意义:

for i := 0; i < 10; i++ {
    prime := <-ch
    print(prime, "\n")
    oldch := ch          //here oldch references the old channel
    ch = make(chan int)  //and here ch is replaced with a new channel
    go Filter(oldch, ch, prime) //and here a filter is applied to values from oldch to ch
}
于 2014-08-28T14:14:55.787 回答