select特点
当 select 中的其他条件分支都没有准备好的时候,default 分支会被执行。
每个case语句里必须是一个IO操作,确切的说,应该是一个面向channel的IO操作。
实例1
测试当 select 中的其他条件分支都没有准备好的时候,default 分支会被执行。
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(1e8) //定时1s
boom := time.After(5e8) //定时5s
for {
select {
case <-tick:
fmt.Println("tick.")
case <-boom:
fmt.Println("BOOM!")
return
default:
fmt.Println(" .")
time.Sleep(5e7) //定时500ms
}
}
}
实例2
测试没有default分支时select,每个case都是io操作,相当于一个while循环
ch1 := make (chan int, 1)
ch2 := make (chan int, 1)
...
select {
case <-ch1:
fmt.Println("ch1 pop one element")
case <-ch2:
fmt.Println("ch2 pop one element")
}
实例3
【使用 select 实现 timeout 机制】
当超时时间到的时候,case2 会操作成功。所以 select 语句则会退出。而不是一直阻塞在 ch 的读取操作上。从而实现了对 ch 读取操作的超时设置。
timeout := make (chan bool, 1)
go func() {
time.Sleep(1e9) // sleep one second
timeout <- true
}()
ch := make (chan int)
select {
case <- ch:
case <- timeout:
fmt.Println("timeout!")
}
实例4
我们可以使用 select 语句来检测 chan 是否已经满了。
因为 ch 插入 1 的时候已经满了,当 ch 要插入 2 的时候,发现 ch 已经满了(case1 阻塞住),则 select 执行 default 语句。这样就可以实现对 channel 是否已满的检测,而不是一直等待。
ch := make (chan int, 1)
ch <- 1
select {
case ch <- 2:
default:
fmt.Println("channel is full !")
}
网友评论