go
runtime_error
ai_generated
true
panic: close of closed channel (in for range)
ID: go/goroutine-for-range-channel-close
80%Fix Rate
85%Confidence
0Evidence
2024-12-08First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 1.20 | active | — | — | — |
| 1.21 | active | — | — | — |
Root Cause
Closing a channel that is being ranged over by another goroutine, causing a panic when the range attempts to read from the closed channel.
generic中文
关闭正在被另一个协程 range 的通道,导致 range 尝试从已关闭通道读取时引发恐慌。
Workarounds
-
100% success Use a separate goroutine to close the channel after all sends are done.
ch := make(chan int) go func() { for i := 0; i < 10; i++ { ch <- i } close(ch) }() for v := range ch { fmt.Println(v) } -
95% success Use a sync.WaitGroup to coordinate closure.
var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() for i := 0; i < 10; i++ { ch <- i } }() go func() { wg.Wait() close(ch) }() for v := range ch { fmt.Println(v) }
Dead Ends
Common approaches that don't work:
-
Closing the channel inside the range loop.
80% fail
Range loop continues until channel is closed, but closing inside causes panic on next iteration.
-
Using a defer close in the sender goroutine that ranges.
70% fail
If the sender is also the range receiver, closing inside the loop is problematic.