在这个例子中,渠道如何运作?

时间:2014-08-28 12:42:26

标签: go primes channels sieve

这是素数筛的一个例子

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?

由于

2 个答案:

答案 0 :(得分:3)

您的代码的输出是:

2
3
5
7
11
13
17
19
23
29

所以程序是这样的:

i = 0,

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

go Filter(ch, ch1, prime)之后,标记为Filter0,功能Filter0频道in将为3,4,5,6 ...并且频道out将是3,5,7 ......;

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

i = 1,

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

go Filter(ch, ch1, prime)之后,标记为Filter1,功能Filter1频道in将为5,7,9,11 ...和频道out将是5,7,11 ......;

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

i = 2,相同。

它是如何输出的。

答案 1 :(得分: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
}