【问题标题】:How the channels work in this example?在这个例子中通道是如何工作的?
【发布时间】:2014-10-22 08:03:16
【问题描述】:

这是一个素数筛的例子

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

谢谢

【问题讨论】:

标签: go primes channels sieve


【解决方案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
}

【讨论】:

    【解决方案2】:

    您的代码输出是:

    2
    3
    5
    7
    11
    13
    17
    19
    23
    29
    

    所以程序是这样的:

    i=0,

    prime := &lt;-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 := &lt;-ch ,prime= 3, ch ={5} 之后,为什么5ch 中?因为现在ch 是最后一个循环中的ch1 ;

    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,同样的。

    它的输出方式。

    【讨论】:

      猜你喜欢
      • 2021-10-05
      • 2017-11-26
      • 2021-10-14
      • 2021-10-05
      • 1970-01-01
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 2020-07-17
      相关资源
      最近更新 更多