我是靠谱客的博主 老实吐司,最近开发中收集的这篇文章主要介绍go channel close之后读写的问题go channel close之后读写的问题,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
go channel close之后读写的问题
- go channel close之后读写的问题
- 代码演示
- 无缓冲读写
- 有缓存读写
- 优雅的range
- 解释
- 补充:如何限制channel的读写
go channel close之后读写的问题
代码演示
无缓冲读写
package main
import "fmt"
func main() {
Test1()
}
func Test1() {
ch := make(chan int)
close(ch)
for i := 0; i < 5; i++ {
fmt.Println(<-ch)
}
ch <- 1
}
0
0
0
0
0
panic: send on closed channel
goroutine 1 [running]:
main.Test1()
C:/Users/68725/Desktop/leetcode/main.go:14 +0xb7
main.main()
C:/Users/68725/Desktop/leetcode/main.go:6 +0x17
进程 已完成,退出代码为 2
有缓存读写
package main
import "fmt"
func main() {
Test2()
}
func Test2() {
ch := make(chan int, 1)
ch <- 1
close(ch)
for i := 0; i < 5; i++ {
v, ok := <-ch
if ok {
fmt.Println("成功读,value=", v)
} else {
fmt.Println("channal关闭,值为类型零值")
}
}
}
成功读,value= 1
channal关闭,值为类型零值
channal关闭,值为类型零值
channal关闭,值为类型零值
channal关闭,值为类型零值
进程 已完成,退出代码为 0
优雅的range
package main
import "fmt"
func main() {
Test3()
}
func Test3() {
ch := make(chan int, 1)
ch <- 1
close(ch)
for v := range ch {
fmt.Println(v)
}
fmt.Println("退出range了")
}
1
退出range了
进程 已完成,退出代码为 0
解释
对于已经close的channel来说,可读不可写,一写就panic。
而读呢,如果channel还有数据,那么先读数据,如果channel里面已经没有数据了,还去读channel,那么此时读出来的是类型零值,对于v, ok := <-ch
这种双返回值的ok来说,ok被赋值为false。
如何优雅的读呢?用range,range会自动赋值,并且在关闭channel后自动退出,这样就无需v, ok := <-ch | if ok...
这种形式了
补充:如何限制channel的读写
package main
func main() {
ch := make(chan int, 1)
ReadCh(ch)
WriteCh(ch)
}
func ReadCh(ch <-chan int) {
<-ch
}
func WriteCh(ch chan<- int) {
ch <- 1
}
在ReadCh函数中,把形参限制为只读,在WriteCh函数中,把形参限制为只写,那么代码就只能在ReadCh中写<- ch
语句,如果写ch<-
就会报错
WriteCh同理
最后
以上就是老实吐司为你收集整理的go channel close之后读写的问题go channel close之后读写的问题的全部内容,希望文章能够帮你解决go channel close之后读写的问题go channel close之后读写的问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复