go runtime_error ai_generated true

恐慌:从已关闭的通道接收(在range中)

panic: receive from closed channel (in range)

ID: go/goroutine-range-over-closed-channel

其他格式: JSON · Markdown 中文 · English
80%修复率
84%置信度
0证据数
2024-06-18首次发现

版本兼容性

版本状态引入弃用备注
1.0 active
1.20 active

根因分析

在通道关闭后使用range迭代;range会接收零值直到通道耗尽。

English

Iterating over a channel with range after it has been closed; range receives zero values until channel is drained.

generic

解决方案

  1. 95% 成功率 Use for with ok pattern instead of range
    for {
        val, ok := <-ch
        if !ok {
            break
        }
        // process val
    }
  2. 90% 成功率 Ensure channel is closed only after all sends are done
    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            ch <- i
        }()
    }
    wg.Wait()
    close(ch)
    for val := range ch {
        // process
    }

无效尝试

常见但无效的做法:

  1. Using recover() to catch panic from zero value 90% 失败

    Range over closed channel doesn't panic; it returns zero values, which may cause logic errors.

  2. Checking channel length before range 80% 失败

    len(ch) doesn't indicate closed state; closed channel can have buffered data.