我们近些天一直在看go
协程,关于协程基础和协程间通信,请看之前的博文
初探理解
select
什么是select选择器
什么是select选择器
select
选择器和go
中switch
很相似,只不过select
能够处理的对象是chan
,那,我们为什么需要select
呢,如果我们有多个chan
在处理的时候,select
可以帮助我们选择符合要求的chan
,如果都满足要求,那就回随机选择一个返回。
语法对比一下select和switch
我们对比一下switch
和 select
语法
对于switch
而言,当多个case
满足条件的时候,它会顺序执行,不做介入的情况下,执行完一个case
后则退出switch
, 而select
则不同,当case
条件满足的时候,它会随机执行case
,具体我们看看案例。
switch 案例
switch
我们执行下看下结果
我们通过之前学习的结果可得,若case
匹配成功,则会走响应的分支,无法匹配成功,则会走到default
分支中。
select案例
反观select
呢,我们写个例子看下
我们定义了2个无缓冲管道,一个是bool
类型的,一个是int
类型的,紧接着我们开启一个协程,中间接入了一个select
,分别对boolChan
和intChan
取值,最后我们等待3秒往boolChan
发送true
,又3秒,我们向intChan
发送3,我们执行下,看下结果
这里简单介绍一下select
机制,若在select
中没有default
分支,那么当没有case
条件满足时,它会等待,等待所检测的管道有数据进来,若有default
的时候,若执行当下select
语句时,若不匹配任何case
,则会执行default
。
我们再反过来看代码,我们由于没有在select
中default
分支,所以该语句会等,等某一个case
条件匹配时,那正好,我们往boolChan
发送了一个true
,满足了该case
,所以会执行“接收到bool chan 的值” , 好,执行完后,select
就执行完毕了,我们再向intChan
发送数字3,但是此时我们没有代码去做管道读取,所以会引发deadlock panic
小demo
通过上述案例,我们知晓了select
在没有default
分支的情况下,只会有一个case
被满足,否则会一直等待,所以我们可以根据此案例,写一个发送撤回器。
即,我们写一个小demo
,该demo
会输出一个信息,我们若在10秒内不干预,则发送,否则撤销发送,
其中核心点,表示select
了,我们在其中写入2个case
- cancel bool
- time.after
time.After
会在多少时间后返回一个<-chan Time
, 而cancel
则需要我们自行输入,这意味着,若我们不介入撤销发送,则消息在规定的时间后会发送成功。
好,我们执行下代码
举一反三,我们甚至于利用select
可以编写一个服务器心跳包。
总结
我们了解了什么是select
,其实从某种意义来说,它和linux select
多路复用有点异曲同工之妙,总的来讲,我们在设计的时候若不加入default
分支,那么select
会一直等待,等待某个case
条件满足,满足后,执行分支,退出select
,注意,当有多个case
满足条件的时候,它会随机选择一个执行,而非顺序执行哦。