英文:
How the channels work in this example?
问题
这是一个质数筛选的示例代码。
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
这个通道正在等待输入,并将其赋值给 prime。那么为什么在调用下一条语句
print(prime, "\n")
时并没有打印出所有的数字呢?
如果我删除最后三行代码:
ch1 := make(chan int)
go Filter(ch, ch1, prime)
ch = ch1
那么从2到11的所有数字都会被打印出来。那么这行代码 ch = ch1
是做什么用的呢?
谢谢。
英文:
This is is an example of prime number 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
}
}
What I understand is this line of code
prime := <-ch
the channel is waiting for an input and assigns to prime. So, why all the numbers are not printed when the next statement is called
print(prime, "\n")
If I remove these last 3 lines
ch1 := make(chan int)
go Filter(ch, ch1, prime)
ch = ch1
then all numbers are printed from 2 to 11. What does this line do ch = ch1?
Thanks
答案1
得分: 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},为什么 ch
中有 5
?因为现在的 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,同理。
这就是输出的过程。
英文:
Your code's output is :
2
3
5
7
11
13
17
19
23
29
So the procedure is like this :
i=0,
after prime := <-ch
, prime=2, ch = {3};
after go Filter(ch, ch1, prime)
, mark as Filter0
,in function Filter0
channel in
will be 3,4,5,6 ... and channel out
will be 3,5,7 ...;
After ch = ch1
, So ch = {3}, which will be 3,5,7.
i=1,
after prime := <-ch
,prime= 3, ch ={5},why is there 5
in ch
?'Cause now ch
is the ch1
in last loop ;
after go Filter(ch, ch1, prime)
, mark as Filter1
,in function Filter1
channel in
will be 5,7,9,11 ... and channel out
will be 5,7,11 ...;
After ch = ch1
, So ch = {3}, which will be 5,7,11.
i=2, the same .
That how it output.
答案2
得分: 1
不打印所有数字的原因是因为在循环的每次迭代中,通道不是相同的。它创建了一个新的通道ch1,并将ch中的值过滤到ch1中,然后将ch赋值给ch1,以便下一次迭代中的ch是上一次迭代的新通道(即ch1),并且那里的值已经被Filter goroutine过滤。
以下是另一种可能更容易理解的写法:
for i := 0; i < 10; i++ {
prime := <-ch
print(prime, "\n")
oldch := ch // 这里oldch引用了旧的通道
ch = make(chan int) // 这里用新的通道替换了ch
go Filter(oldch, ch, prime) // 这里将oldch中的值通过过滤器应用到ch中
}
英文:
The reason not all numbers are printed is because it's not the same channel in each iteration of the loop. It creates a new channel ch1 and filters values from ch into ch1 and then it assigns ch to ch1 so that the next iteration ch is the new channel from the previous iteration (there known as ch1) and the values there have been filtered by the Filter goroutine.
Here is another way to write it that may make more sense to you:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论