Why does Go panic when recording to a private channel?
Although you can use the idiom value, ok := <-channel to read from channels, and thus, the result of ok can be tested to get into a closed channel:
// reading from closed channel package main import "fmt" func main() { ch := make(chan int, 1) ch <- 2 close(ch) read(ch) read(ch) read(ch) } func read(ch <-chan int) { i,ok := <- ch if !ok { fmt.Printf("channel is closed\n") return } fmt.Printf("read %d from channel\n", i) }
Output:
read 2 from channel channel is closed channel is closed
Launch "reading from the closed channel" on the Playground
Recording to a possibly closed channel is more confusing because Go will panic if you just try to record when the channel is closed:
//writing to closed channel package main import ( "fmt" ) func main() { output := make(chan int, 1) // create channel write(output, 2) close(output) // close channel write(output, 3) write(output, 4) } // how to write on possibly closed channel func write(out chan int, i int) (err error) { defer func() { // recover from panic caused by writing to a closed channel if r := recover(); r != nil { err = fmt.Errorf("%v", r) fmt.Printf("write: error writing %d on channel: %v\n", i, err) return } fmt.Printf("write: wrote %d on channel\n", i) }() out <- i // write on possibly closed channel return err }
Output:
write: wrote 2 on channel write: error writing 3 on channel: send on closed channel write: error writing 4 on channel: send on closed channel
Launch a “private channel entry” on the Playground
As far as I know, there is no simpler idiom for recording into a possibly closed channel without panic. Why not? What is the reason for this asymmetric behavior between reading and writing?
concurrency go panic goroutine channel
Everton
source share