You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法理解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,以及对应的取消函数cancel
  • defer 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 02:58:02