Go语言编程读书笔记:Go channel(2)

时间:2023-03-08 21:31:53
Go语言编程读书笔记:Go channel(2)

单向channel

概念

单向channel是只能用于发送或者接收数据,channel本身必然是同时支持读写,否则根本没法用。假如一个channel只能读,那么肯定只会是空的,因为你没有机会向里面写数据。如果一个channel只允许写,即使写进去了,也没有丝毫意义,因为没有机会读取里面的数据。所以所谓的单向channel的概念,其实只是对channel的一种使用限制。

我们在将一个channel变量传递到一个函数时,可以通过将其指定为单向channel变量,从而限制该函数中可以对此channel的操作,比如只能往这个channel写,或者只能从这个channel读

定义

单向channel变量的声明非常简单,如下:

var ch1 chan int      //ch1是一个正常的channel

var ch2 chan<- float64  //ch2是单向channel,只用于写float64数据

var ch3 <-chan  int    //ch3是单向channel,只用于读int数据

这里面记channel的性质,看定义时箭头指向的方向即可,箭头指向channel,即数据流入channel,即只写不读,箭头从channel出来,即数据流出channel,即只读不写。

初始化

channel是一个原生类型,因此不仅支持被传递,还支持类型转换。只有在介绍了单向channel的概念后,读者才会明白类型转换对于channel的意义:就是在单向channel和双向channel之间进行转换。

ch4 := make(chan int)

ch5 := <-chan int(ch4)    //ch5是一个单向读取channel

ch6 := chan<- int(ch4)    //ch6是一个单向写入channel

channel示例

package main

import "fmt"

func counter(out chan<- int){
//单向用于写int数据
for x := 0; x<100; x++{
out <- x
}
close(out)
} func squarer(out chan<- int, in <-chan int){
//out:单向写int数据
//in: 单向读int数据
//从in中读取数据,写入到out
for v := range in {
out <- v * v
}
close(out)
} func printer(in <-chan int) {
for v := range in {
fmt.Println(v)
}
} func main(){
naturals := make(chan int)
squares := make(chan int) go counter(naturals)
go squarer(squares,naturals)
printer(squares)
}

  

关闭channel

直接使用Go语言内置的close()函数即可关闭:

close(ch)

在介绍了如何关闭channel之后,我们就多了一个问题:如何判断一个channel是否已经被关闭?我们在读取的时候使用多重返回值的方式:

x,ok := <-ch

如果ok的返回值是false,就表示channel已经被关闭