只读与只写管道
只读: <-chan [type]
只写:chan<- [type]
// 只读
func onlyRead(readChan <-chan int) {
for {
if v, ok := <-readChan; ok {
fmt.Println("值:", v)
}
}
//readChan <- 123 // Invalid operation: readChan<- 123 (send to the receive-only type <-chan int)
}
// 只写
func onlyWrite(writeChan chan<- int) {
for i := 0; i < 6; i++ {
writeChan <- i
}
//<-writeChan // Invalid operation: <-writeChan (receive from the send-only type chan<- int)
close(writeChan)
}
close关闭管道的优化手段
在前面的案例中,我们可以发现我们在创建管道之后,我们先是往里面添加数据,然后再取数据,同时在将数据加入完毕之后,就要将管道关闭,不允许再添加数据,但是有的时候,我们不能准确的把握什么时候去关闭这个管道,就像我们之前在处理主线程和协程执行时间不一致时使用sleep来阻塞主线程。在案例中,我们可以发现我们在处理exitChan管道时,其实没有去特意关闭它,而是通过固定的遍历次数来结束遍历。主要是因为这里不清楚什么时候去关闭管道。
使用select
select语句 就是用来监听和channel有关的IO操作,当IO操作发生时,触发相应的case动作。有了 select语句,可以实现 main主线程 与 goroutine线程 之间的互动。
select {
case <-ch1 : // 检测有没有数据可读
// 一旦成功读取到数据,则进行该case处理语句
case ch2 <- 1 : // 检测有没有数据可写
// 一旦成功向ch2写入数据,则进行该case处理语句
default:
// 如果以上都没有符合条件,那么进入default处理流程
}
使用select实现管道遍历
在之前的案例中,我们可以再遍历exitChan时,使用select去遍历;当遍历的时候不再匹配任何一个case时,此时就应该进入default,执行相关的退出遍历的操作,那么这里的退出遍历,我们可以采用什么方式呢?大家可以先思考一下:
EXIT:
for {
select {
case v := <-exitChan :
fmt.Println("遍历一次exitChan", v)
default :
break EXIT
// goto EXIT2
}
}
// EXIT2
参考:golang跳出for select 循环,需要break配合标签才行
参考:go中select语句
最后
最近学习的时间比较有限,整理的笔记会相对少一些,感觉有点想一点了解一个go的小知识。最近写的都会比较少,主要是专业课考试,所以要花些时间来复习功课。