无法理解Go Context包示例,请求拆解代码并解惑
拆解Go标准库Context包示例代码逻辑
核心疑惑先澄清
gen函数仅被调用一次,返回的是单个通道,你看到的1-5是这个通道里连续传递的5个值,不是5个通道。
代码逐段拆解
1. 定义生成器函数gen
gen := func(ctx context.Context) <-chan int { dst := make(chan int) n := 1 go func() { for { select { case <-ctx.Done(): return // 退出goroutine,避免资源泄漏 case dst <- n: n++ } } }() return dst }
gen是一个匿名函数,接收context.Context参数,返回只读的int类型通道- 内部创建无缓冲通道
dst,初始化计数器n=1 - 启动一个后台goroutine,进入无限循环:
- 监听
ctx.Done():当上下文被取消时,这个通道会收到信号,goroutine立即退出,防止泄漏 - 向
dst发送当前的n:发送成功后,n自增,准备下一个值
- 监听
2. 创建可取消的上下文
ctx, cancel := context.WithCancel(context.Background()) defer cancel() // 完成数据消费后触发取消
context.Background()是根上下文,通常作为所有上下文的起点WithCancel基于根上下文生成一个可取消的上下文ctx,以及对应的取消函数canceldefer cancel()确保无论程序正常结束还是异常退出,都会调用取消函数,通知后台goroutine终止
3. 消费通道数据
for n := range gen(ctx) { fmt.Println(n) if n == 5 { break } }
- 调用
gen(ctx)获取通道,然后用for range循环接收通道里的值 - 每次收到值就打印,当值等于5时,
break退出循环 - 循环退出后,
defer的cancel()会执行,触发ctx.Done()信号,后台goroutine收到信号后退出,通道不再发送数据
内容的提问来源于stack exchange,提问作者Avi
相关产品推荐
相关产品推荐

