Go语言单向通道——通道中的单行道

   Go语言的类型系统提供了单方向的channel类型,顾名思义,单向channel只用于发送或者接受数据。channel本身必然是同时支持读写否则根本没法用。假如一个 channel 真的只能读,那么肯定只会是空的,因为你没机会往里面写数据。同理,如果一个 channel 只允许写,即使写进去了,也没有丝毫意义,因为没有机会读取里面的数据。所谓的单向 channel 概念,其实只是对 channel 的一种使用限制。

  • 单向通道的声明格式

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

  单向channel变量的声明非常简单,只能发送的通道类型为chan<-,只能接收的通道类型为<-chan,格式如下:   

    var 通道实例 chan<- 元素类型    // 只能发送通道

    var 通道实例 <-chan 元素类型    // 只能接收通道

单向通道的使用例子

例子代码如下:

  1. ch := make(chan int)
  2. // 声明一个只能发送的通道类型, 并赋值为ch
  3. var chSendOnly chan<- int = ch
  4. //声明一个只能接收的通道类型, 并赋值为ch
  5. var chRecvOnly <-chan int = ch

   上面的例子中,chSendOnly 只能发送数据,如果尝试接收数据,将会出现如下报错:

invalid operation: <-chSendOnly (receive from send-only type chan<- int)

同理,chRecvOnly也不能发送的

当然,使用make创建通道时,也可以创建一个只发送或读取的通道:

 ch :=make(<-chan int)

 var chReadOnly <-chan int = ch

<-chReadOnly

上面代码编译正常,运行也是正常。但是,一个不能填充数据(发送)只能读取的通道是毫无意义的。

  • time包中的单向通道

time包中的计时器会返回一个timer实例,代码如下:

timer:=time.NewTimer(time.Second)

timer的Timer类型定义如下:

  type Timer Struct{

   c<-chan Time

  r runtimeTimer

}

第 2 行中 C 通道的类型就是一种只能接收的单向通道。如果此处不进行通道方向约束,一旦外部向通道发送数据,将会造成其他使用到计时器的地方逻辑产生混乱。因此,单向通道有利于代码接口的严谨性。

  • 关闭 channel

关闭channel非常简单,直接使用Go语言内置的close()函数即可:

close(ch)

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

X.ok:=<-ch

这个用法与 map 中的按键获取 value 的过程比较类似,只需要看第二个 bool 返回值即可,如果返回值是 false 则表示 ch 已经被关闭。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值