先思考下,go语言 channel 中,如果通道关闭,会读到那些数据?

- 已缓冲的数据仍然可以被读取:如果通道关闭前有数据被发送到缓冲区中,这些数据仍然可以被正常读取,直到缓冲区被清空。
- 读取空的已关闭通道:当通道中没有数据可读时,读取操作会立即返回通道类型的零值,并且第二个返回值(表示通道是否开放)为 false。
- 零值与通道状态:通过第二个返回值可以区分是从开放的通道读取到零值,还是从关闭的通道读取到零值。
关闭通道后读取《值 or 指针》:
- 值通道:读取到该类型的零值(如空结构体)
- 指针通道:读取到 nil 指针
示例代码:
package main
import (
"fmt"
)
func main() {
// 创建一个带缓冲的通道
ch := make(chan int, 3)
// 发送数据到通道
ch <- 1
ch <- 2
ch <- 3
// 关闭通道
close(ch)
// 读取已关闭通道中的数据
for i := 0; i < 5; i++ {
val, ok := <-ch
if ok {
fmt.Printf("读取到值: %d\n", val)
} else {
fmt.Printf("通道已关闭,读取到零值: %d\n", val)
}
}
// 使用 range 读取已关闭的通道
fmt.Println("\n使用 range 读取:")
ch2 := make(chan int, 2)
ch2 <- 10
ch2 <- 20
close(ch2)
// range 会自动检测通道关闭,并在通道关闭且没有更多值时退出循环
for v := range ch2 {
fmt.Printf("range 读取到值: %d\n", v)
}
}
















