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

go语言 channel 中,如果通道关闭,会读到那些数据?热乎面试题_数据

  1. 已缓冲的数据仍然可以被读取:如果通道关闭前有数据被发送到缓冲区中,这些数据仍然可以被正常读取,直到缓冲区被清空。
  2. 读取空的已关闭通道:当通道中没有数据可读时,读取操作会立即返回通道类型的零值,并且第二个返回值(表示通道是否开放)为 false。
  3. 零值与通道状态:通过第二个返回值可以区分是从开放的通道读取到零值,还是从关闭的通道读取到零值。

关闭通道后读取《值 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)
	}
}