《GO语言高级编程》设计中案例,仅作为笔记进行收藏。
package main
import (
"context"
"fmt"
)
// 返回生成自然数序列的管道:2,3,4……
func GenerateNatural(ctx context.Context) chan int {
ch := make(chan int)
go func() {
for i := 2; ; i++ {
// fmt.Printf("GenerateNatural:%v\n", i)
select {
case <-ctx.Done():
return
case ch <- i:
}
}
}()
return ch
}
// 管道过滤器:删除能被素数正常的数
func PrimeFileter(ctx context.Context, in <-chan int, prime int) chan int {
out := make(chan int)
go func() {
for {
// fmt.Printf("PrimeFileter-prime:%v\n", prime)
if i := <-in; i%prime != 0 {
// fmt.Printf("PrimeFileter-if:%v\n", i)
select {
case <-ctx.Done():
return
case out <- i:
}
}
// fmt.Printf("PrimeFileter-for:%v\n", <-in)
}
}()
return out
}
func main() {
// 通过 Context 控制后台 Goroutine状态
ctx, cancel := context.WithCancel(context.Background())
// 自然数序列:2,3,4,……
ch := GenerateNatural(ctx)
for i := 0; i < 10; i++ {
// 新出现的素数
prime := <-ch
fmt.Printf("%v:%v\n", i+1, prime)
// 基于新素数构造的过滤器
// 如果未产生新的素数,则通道 ch 为 nil;如果通道 ch 为 nil,则 GenerateNatural 生成新的自然数,发送给ch,则PrimeFileter 过滤,直到通道不为nil
ch = PrimeFileter(ctx, ch, prime)
}
cancel()
}
GenerateNatural 函数内部启动⼀个Goroutine⽣产序列,返回对应的管道。
PrimeFilter 函数内部启动⼀个Goroutine将输入序列中是素数倍数的数提出,并返回新的序列,是⼀个新的
管道。
GenerateNatural 生产,PrimeFilter 过滤。逐步提取出素数。