go
runtime_error
ai_generated
true
panic: runtime error: close of nil channel
ID: go/panic-runtime-error-close-of-nil-channel
95%Fix Rate
89%Confidence
1Evidence
2023-01-20First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| go1.20 | active | — | — | — |
| go1.21 | active | — | — | — |
| go1.22 | active | — | — | — |
Root Cause
Attempting to close a channel variable that has not been initialized (nil) using close(ch).
generic中文
尝试使用 close(ch) 关闭一个尚未初始化(空值)的通道变量。
Official Documentation
https://go.dev/ref/spec#CloseWorkarounds
-
95% success Initialize the channel with make() before using: ch := make(chan T); defer close(ch)
Initialize the channel with make() before using: ch := make(chan T); defer close(ch)
-
93% success Guard close with a nil check: if ch != nil { close(ch) } else { /* handle nil case */ }
Guard close with a nil check: if ch != nil { close(ch) } else { /* handle nil case */ } -
90% success Use sync.Once to ensure close is called only once and after initialization: var closeOnce sync.Once; closeOnce.Do(func() { close(ch) })
Use sync.Once to ensure close is called only once and after initialization: var closeOnce sync.Once; closeOnce.Do(func() { close(ch) })
中文步骤
使用 make() 初始化通道后再使用:ch := make(chan T); defer close(ch)
在 close 前进行空值检查:if ch != nil { close(ch) } else { /* 处理空值情况 */ }使用 sync.Once 确保 close 只调用一次且在初始化之后:var closeOnce sync.Once; closeOnce.Do(func() { close(ch) })
Dead Ends
Common approaches that don't work:
-
Wrap close(ch) in a recover() block to catch the panic
70% fail
Recovering doesn't fix the root cause and may mask a logic error
-
Use select with default to check if channel is nil before closing
80% fail
select doesn't detect nil channels at compile time; it's a runtime check that still panics if nil
-
Set ch = make(chan T) before every close call
60% fail
Overwrites the existing channel and may cause goroutine leaks or lost messages