关于chan的用法困惑

lorenwe · · 1675 次点击
jan-bar
想要拥有,必定付出。
```go package main import "fmt" func main() { ch := g() for i := 1; i <= 100; i++ { pp := <-ch fmt.Printf("%v:%v\n", i, pp) ch = p(i, ch, pp) } } func g() chan int { ch := make(chan int) go func() { // 本协程只会一致往cnt=1那个接收协程里面写入 for i := 2; ; i++ { ch <- i } }() return ch } func p(cnt int, in <-chan int, p int) chan int { out := make(chan int) go func(cnt int) { // cnt表示哪个go func运行 for { // p 和 cnt有对应关系,详细可以看打印结果 if i := <-in; i%p != 0 { fmt.Printf("cnt:%d,out<-%d,%d %% %d != 0\n", cnt, i, i, p) out <- i // 写入out会作为下一个协程的in } } }(cnt) return out } ``` ### (ps:你不发文本,我懒得敲函数名了,嘿嘿。)仔细研究了一下你这个程序,确实666。因为发送协程一直在g里面写入,接收有很多个协程,每个协程接收的数据是上一个接收协程判断成功后发送的数据,因此那个过滤的func确实能达到过滤的效果。就像一堆小球滚下楼梯,每个楼梯都要判断哪些小球能滚到下个楼梯,一些不满足条件的会在中途某些接收协程里面踢出掉,这些踢出的是不会传到下个接收协程。这种程序一般用于学习吧,理解起来是有点绕。 ### 多说一句,这些中途的chan貌似没办法close掉,而协程一直存在,不会被GC掉,该程序如果不退出那这些chan就要算内存泄漏了。
#5
更多评论
jan-bar
想要拥有,必定付出。
没写过这么666的代码。但我的映像中,切片、map、interfere{}、chan等都是默认为地址,你看chan是需要make出来的,所以可以从这方面研究吧。
#1
一直很困惑 `ch = PrimeFilter(ch, prime) ` 这段代码是怎么运行的
#2