标签(空格分隔): kotlin
fun numbersFrom(context: CoroutineContext, start: Int) = produce(context) {
var x = start
while (true) send(x++) // 从start开始的无限整数流
}
fun filter(context: CoroutineContext, numbers: ReceiveChannel, prime: Int) = produce(context) {
for (x in numbers) if (x % prime != 0) send(x)
}
fun main(args: Array) = runBlocking {
var cur = numbersFrom(coroutineContext, 2)
for (i in 1..10) {
val prime = cur.receive()
println(prime)
cur = filter(coroutineContext, cur, prime)
}
coroutineContext.cancelChildren() // 取消所有的子协程,从而让主线程退出
}
粗解:
numbersFrom(2) -> filter(2) -> filter(3) -> filter(5) -> filter(7) ...
filter(3, filter(2, numbers))
https://www.jianshu.com/p/3ffc11978602
http://www.voidcn.com/article/p-cvjkgewg-bxv.html
细解:
首先他的思想就是有一个数据流:
[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],他首先用2进行过滤,能被2整除的都去除,
这样就剩下了[3,5,7,9,11,13,15,17,19],然后用3进行过滤【此处遗留3】,
剩下了[5,7,11,13,15,17,19],然后用5进行过滤【此处遗留5】,
剩下了[7,11,13,17,19],此时用7进行过滤【此处遗留7】,
剩下了[11,13,17,19],然后用11进行过滤【此处遗留11】,
剩下了[13,17,19],然后用13进行过滤【此处遗留13】,
剩下了[17,19],然后用17进行过滤【此处遗留17】,
剩下了[19],然后用17进行过滤【此处遗留17】
剩下了[]
上面是处理的思想;
**[此处可忽略不看]**具体的操作:首先产生了一个通道数据流numberFrom,发出了数字2,数据流挂起,2被接收,通道数据流numberFrom发出了数字3,又挂起;此时同时打印出了2,然后进入filter(cur,2),在这里面,从cur通道里面取出3,判断之后send(3)挂起,此时numberFrom发出4后挂起,而filter(cur,2)也返回一个通道数据流cur2[针对素数2],然后receive[3],此时cur过滤掉4,打印3,然后filter(cur2,3)开始跑起来,但是目前数据流是空的;
接着看,此时cur通道处理4,直接移除,此时numberFrom发出5后挂起,filter(cur,2)从中取出5,判断send(5)后挂起,[同时numberFrom发出6后挂起,filter(cur,2)直接过滤掉,numberFrom发出7后挂起,filter(cur,2)send(7)后挂起,filter(cur2,3)send(7)后挂起,同时filter(cur3,5)数据流生成,也是空的,此时收到了7,然后send(7)后挂起,又到了一轮的receive],filter(cur2,3)拿到5,send(5)之后挂起,第三轮开启,receive(5)之后打印
上面很乱的,因为把很多同时做的事情不好同时表述:
一次整理:
上面的细推如果看懂了,那就基本理解了整个的处理思想和流程,大道化简
cur=numberFrom() -> cur2=filter(context,cur,2) -> cur3=filter(context,cur2,3) -> cur5=filter(context,cur3,5) -> cur7=filter(context,cur5,7)....
//再化简
cur=numberFrom() -> cur2=filter(cur,2) -> cur3=filter(cur2,3) -> cur5=filter(cur3,5) -> cur7=filter(cur5,7)....
//再化简
filter(7,filter(5,filter(3, filter(2, numberFrom))))....