select的应用场景
多个通道在接收数据的时候,如果没有数据接收,就会发生阻塞,导致其余通道无法接收。
为了实现同时监控多个通道并且从多个通道接收值的需求,同时避免使用循环提高效率,Go
内置了select
关键字来同时响应多个通道的操作。
select的使用
Go语言中的select使用了类似switch的语句,他有一系列的case分支和一个默认分支。每个case对应一个通道的通信过程。select会一直等待,直到某个case通信操作完成时,就会执行case分支对应的语句。
语法如下:
select {
case <-chan1:
//如果chan1接收到数据,则进行该case处理语句
case chan2<-1:
//如果chan2写入数据成功,则进入此case处理语句
default:
//如果上面的都没执行成功,则进入default
}
- 使用示例:
import (
"fmt"
"time"
)
func chan1Test(ch chan string) {
time.Sleep(time.Second*3)
ch<-"chan1Test"
}
func chan2Test(ch chan string) {
time.Sleep(time.Second*2)
ch<-"chan2Test"
}
func main() {
chan1 :=make(chan string)
chan2 :=make(chan string)
go chan1Test(chan1)
go chan2Test(chan2)
//防止main goroutine提前执行完成返回值,而fun1 fun2还没执行
time.Sleep(time.Second*5)
//select监控
select {
case s1:=<-chan1:
fmt.Println("s1=",s1)
case s2:=<-chan2:
fmt.Println("s2=",s2)
default:
fmt.Println("没有接收到数据!")
}
}
上例中select同时监听了多个channel,当有多个channel同时准备好了的时候就会随机选择一个进行执行。这里将打印
(修改time.Sleep(time.Second*3)
可测试不同的结果(一个channel准备好,或者是两个channel同时准备好随机执行其中一个))