Go 知识点(07)— 对已经关闭通道进行读写

本文详细探讨了对已关闭通道进行写操作引发的 panic 错误,以及在不同情况下关闭通道的读操作结果。包括空通道读取零值、有数据通道的最后一次读取,以及总结了通道操作的基本原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天我们来看下对已经关闭通道进行读写会发生什么情况。

1. 对已关闭通道进行写操作

看下面代码会输出什么结果?

func main() {
	ch := make(chan string, 1)
	close(ch)
	ch <- "hello, world"
	fmt.Println(<-ch)
}

输出结果为:

panic: send on closed channel

这个结果无论对于非缓冲通道还是缓冲通道都是一样的,即对已经关闭的通道进行写操作,会触发 panic

2. 对已关闭通道进行读操作

对已经关闭的 channel 进行读操作要分为两种情况:

  • 已关闭的 channel 没有数据;
  • 已关闭的 channel 仍然有数据;

2.1 已关闭的 channel 没有数据

看下面代码

func main() {
	ch := make(chan int, 1)
	close(ch)
	// 第一次从通道中获取数据
	value, ok := <-ch
	fmt.Println(value) // 0
	fmt.Println(ok)    //  false
	// 第二次从通道中获取数据
	fmt.Printf("<-ch is %v\n", <-ch) // <-ch is 0
	fmt.Println(ok)                  //  false
}

从上面代码结果我们可以得出结论,对于已经关闭的 channel ,如果通道内已经没有数据,那么可以不限次数的进行读取操作,但是读到的值是该 channel 类型的零值,也就是上面代码中 int 的零值 0。

如果该通道被声明为 string 类型,那么其零值就为空字符串 ""

而从通道返回的第二个值,也就是标志位 ok,则会一直为 false

2.2 已关闭的 channel 仍然有数据

查看下面代码输出结果

func main() {
	ch := make(chan int, 3)
	ch <- 1
	close(ch)
	// 第一次从通道中获取数据
	value, ok := <-ch
	fmt.Println("第一次从通道中获取数据 value", value) //  1
	fmt.Println("第一次从通道中获取数据 ok", ok)       //  true
	// 第二次从通道中获取数据
	value, ok = <-ch
	fmt.Println("第二次从通道中获取数据 value", value) //  0
	fmt.Println("第二次从通道中获取数据 ok", ok)       //  false
}

对于这种情况,从通道里面仍然可以获取到之前存储的数据,同时第二个返回值 ok 的值为 true, 表示通道里面是有数据的。

但是当通道里面的值被取完时,就和上面 2.1 小节的结果一样了。

3. 对通道操作的总结

总结
通道状态

通道状态

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wohu007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值