Select
就是Channel
的Switch
. Select
具备一系列的Case
分支和一个默认default
分支, 每一个case
对应于一个channel
操作(send/receive
). select
在多case
场景下会一直等待, 直到某个case
操作完成, 就会执行case
内对应的语句.
代码示例:
1 | select { |
特点:
select
可以同时监听一个或多个channel
, 直到某个channel
操作完成;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan int)
ch2 := make(chan string)
go sender1(ch1)
go sender2(ch2)
select {
case value := <-ch1:
fmt.Printf("Got from channel one: %v \n", value)
case value := <-ch2:
fmt.Printf("Got from channel two: %v \n", value)
}
time.Sleep(1 * time.Second)
}
func sender1(ch chan int) {
ch <- 1
}
func sender2(ch chan string) {
ch <- "Qingzhi"
}上面定义了两个
case
, 分别从ch1
,ch2
两个channel
进行接收操作, 满足操作则进行打印操作;多个
case
同时满足时, 随机选择一个case
执行, 其他case
不执行;在
select
前通过sleep
操作保证多case
同时满足, 多次运行,可以发现输出结果时随机的.default case
一般用于非阻塞的case
.一般通过
time.After
设置超时器.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan int)
ch2 := make(chan string)
go sender1(ch1)
go sender2(ch2)
select {
case value := <-ch1:
fmt.Printf("Got from channel one: %v \n", value)
case value := <-ch2:
fmt.Printf("Got from channel two: %v \n", value)
case <-time.After(1 * time.Second):
fmt.Printf("Time out \n")
}
time.Sleep(1 * time.Second)
}
func sender1(ch chan int) {
time.Sleep(2 * time.Second)
ch <- 1
}
func sender2(ch chan string) {
time.Sleep(2 * time.Second)
ch <- "Qingzhi"
}通过
time.After
可以获得一个仅能够接收的channel
, 这样可以手动设置超时器, 防止程序挂起.