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

Go代码中BRANCH1在LINE2与LINE3间执行是否会触发panic?

问题分析:Go代码是否会在特定场景下触发panic

先看给出的Go代码:

func main() {
    rand.Seed(time.Now().Unix())
    ctx, cancelFunc := context.WithCancel(context.Background())
    anies := make(chan any)
    go doSomething(ctx, anies)
    intn := rand.Intn(2)
    if intn == 0 { //BRANCH1
        cancelFunc()
        close(anies) 
    }
    time.Sleep(time.Second)
}

func doSomething(ctx context.Context, anies chan any) {
    for {
         if ctx.Err() == nil { //LINE2
            anies <- 1 //LINE3
        }
    }
}

当BRANCH1分支在LINE2与LINE3的执行间隙触发时,一定会发生panic,原因如下:

  • doSomething执行到LINE2时,判断ctx.Err() == nil成立,说明此时context还未被取消。
  • 就在LINE2判断完成、LINE3执行前的间隙,BRANCH1触发:先调用cancelFunc()让context进入取消状态,接着调用close(anies)关闭通道。
  • 之后doSomething继续执行LINE3的anies <- 1,此时通道已经被关闭,而Go语言中往已关闭的通道发送数据会直接触发panic,错误信息为send on closed channel。

另外补充:即便context已经被取消,doSomething的循环不会停止,它只是在每次循环开头判断ctx.Err(),但如果已经通过判断才遇到通道关闭,依然会触发panic。

内容的提问来源于stack exchange,提问作者GumbertGumbert

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:01:29