-
读已关闭的channel
读已经关闭的channel无影响。
如果在关闭前,通道内部有元素,会正确读到元素的值;如果关闭前通道无元素,则会读取到通道内元素类型对应的零值。
若遍历通道,如果通道未关闭,读完元素后,会报死锁的错误。
fatal error: all goroutines are asleep - deadlock!
-
写已关闭的通道
会引发panic: send on closed channel
-
关闭已关闭的通道
会引发panic: close of closed channel
总结:对于一个已初始化,但并未关闭的通道来说,收发操作一定不会引发 panic。但是通道一旦关闭,再对它进行发送操作,就会引发 panic。如果我们试图关闭一个已经关闭了的通道,也会引发 panic。
ChatGPT答案:
对已经关闭的 channel 进行读取操作会返回一个零值和一个表示 channel 是否关闭的标志位。
对已经关闭的 channel 进行写入操作会导致 panic 异常。因此在进行 channel 操作时,我们应该先检查 channel 是否已经关闭,避免 panic 异常的发生。可以通过在读取操作后检查标志位来判断 channel 是否已经关闭,如果已经关闭,应该停止对 channel 的读取操作。
同时,在写入操作之前,也应该检查 channel 是否已经关闭,避免写入操作导致 panic 异常的发生。
下面是一个简单的示例,展示如何在进行 channel 操作时检查 channel 是否已经关闭:
package main
import (
"fmt"
)
func main() {
ch := make(chan int)
go func() {
for i := 1; i <= 5; i++ {
ch <- i
}
close(ch)
}()
for {
if val, ok := <-ch; ok {
fmt.Println(val)
} else {
fmt.Println("Channel closed.")
break
}
}
// 尝试向已经关闭的 channel 写入数据,会导致 panic 异常
// ch <- 6
}
在上面的示例中,我们创建了一个无缓冲的 channel `ch`,在一个 goroutine 中向其中写入了 1 到 5 的数值,并在写入完成后关闭了 channel。在主 goroutine 中,我们通过 for 循环进行了读取操作,通过读取操作返回的标志位判断 channel 是否已经关闭,如果已经关闭则退出循环。同时,在代码的最后,我们注释了尝试向关闭的 channel 写入数据的代码,避免了 panic 异常的发生。
你们觉得哪个回答比较好?