go channel close之后读写的问题
- go channel close之后读写的问题
- 代码演示
- 无缓冲读写
- 有缓存读写
- 优雅的range
- 解释
- 补充:如何限制channel的读写
go channel close之后读写的问题
代码演示
无缓冲读写
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16package 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 }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
150 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
有缓存读写
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21package 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关闭,值为类型零值") } } }
复制代码
1
2
3
4
5
6
7
8成功读,value= 1 channal关闭,值为类型零值 channal关闭,值为类型零值 channal关闭,值为类型零值 channal关闭,值为类型零值 进程 已完成,退出代码为 0
优雅的range
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package 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
2
3
4
51 退出range了 进程 已完成,退出代码为 0
解释
对于已经close的channel来说,可读不可写,一写就panic。
而读呢,如果channel还有数据,那么先读数据,如果channel里面已经没有数据了,还去读channel,那么此时读出来的是类型零值,对于v, ok := <-ch
这种双返回值的ok来说,ok被赋值为false。
如何优雅的读呢?用range,range会自动赋值,并且在关闭channel后自动退出,这样就无需v, ok := <-ch | if ok...
这种形式了
补充:如何限制channel的读写
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14package 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内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复