select
一.简介
select是Go语言特有的操作,使用select我们可以同时在多个channel上进行发送/接收操作.select的用法与switch语言非常类似,由select开始一个新的选择块,每个选择条件由
case语句来描述。与switch语句可以选择任何可使用相等比较的条件相比,select有比较多的限制,其中最大的一条限制就是每个case语句里必须是一个IO操作,大致的结构如下:
select { case <-chan1: // 如果chan1成功读到数据,则进行该case处理语句 case chan2 <- 1: // 如果成功向chan2写入数据,则进行该case处理语句 default: // 如果上面都没有成功,则进入default处理流程 }
可以看出,select不像switch,后面并不带判断条件,而是直接去查看case语句。
二.基本示例
示例:
func main() { ch := make(chan int, 1) // 创建1个缓存区大小的channel for { select { case ch <- 1: case ch <- 0: } i := <-ch fmt.Println("Value received:", i) } }
这将随机输出0和1
make(chan int, 1),这表示创建1个缓存区大小的channel,如果没有该参数,因为channel的特性,将造成一个死锁.
default:
func main() { ch1 := make(chan int) ch2 := make(chan int) select { case <-ch1: fmt.Println(<-ch1) case <-ch2: fmt.Println(<-ch2) default: fmt.Println("default") } }
ch1和ch2都为空,所以default执行
三.超时机制或缓存数目检查
1.超时机制
func main() { timeout := make(chan bool, 1) // 带缓存超时channel ch := make(chan int) go func() { time.Sleep(1 * time.Second) // 超时时间 timeout <- true }() select { case <-ch: fmt.Println(ch) case <-timeout: fmt.Println("time out range") } }
2.检查缓存是否已满
func main() { ch := make(chan int, 1) ch <- 1 select { case ch <- 2: fmt.Println(ch) default: fmt.Println("cache num is enough") } }