上QQ阅读APP看书,第一时间看更新
5.2.2 channel接收数据
在了解了如何向channel写入数据后,下面来看如何从channel处接收数据。上一节向channel写入数据时使用的是c<-,而从channel读取数据则正好反过来,使用的是<-c。
还是通过示例代码来看一下:
book/ch05/5.2/read/main.go
1. package main
2.
3. import (
4. "fmt"
5. "time"
6. )
7.
8. func main() {
9. c := make(chan int)
10. go writeChan(c,666)
11. time.Sleep(1*time.Second)
12. fmt.Println("Read:",<-c)
13. if _,ok := <-c;ok{
14. fmt.Println("Channel is Open")
15. }else {
16. fmt.Println("Channel is closed")
17. }
18. }
19.
20. func writeChan(c chan int,x int) {
21. fmt.Println("Start:",x)
22. c <- x
23. close(c)
24. fmt.Println("End:",x)
25. }
第20行至第25行,像读取channel的例子一样,也写了writeChan函数,毕竟要测试读,首先要写。
第9行至第11行,也和上一个示例代码一样,定义一个channel,然后传入writeChan函数,并启动一个goroutine来运行这个函数,并且在第11行让主goroutine休眠。
第12行至第17行是这个示例和上一个示例的不同之处。在第12行,先使用<-c读取了通道c的数据,第13行至第17行则是再次读取c,并查看通道c是否被关闭。上一示例有相应解释,一旦写入数据通道就会阻塞,而被读取之后就会继续,正好下一行就是第23行关闭通道。
多运行几次,结果大多如下:
Start: 666 Read: 666 End: 666 Channel is closed
不过也出现了如下这种情况:
Start: 666 Read: 666 Channel is closed
这是因为主goroutine关闭的时候,writeChan函数的goroutine还没来得及执行第24行,可见这样写还是不够严谨。
注意
通过close函数关闭channel不是必须的,只有在需要通知其他的数据读取通道数据已经写入完成时,才必须关闭。不主动关闭的通道,垃圾回收器会自动回收。而文件操作的close函数则是必须有的,请读者区分开。