Golang-select語句

初識

  • select是golang中一種控制結構
    • 可透過select語句監聽在channel上的數據流動狀態
  • 類似於switch語句,但是select隨機執行任何一個可運行的case
  • 沒有case可運行時,則阻塞;直到有case可運行

語法結構

類似switch,仍存在case語句和default語句

1
2
3
4
5
6
7
8
9
10
select {
case communication clause:
statement(s)
case communication clase:
statement(s)
//可定義任意數量的case

default: //可選擇使用
statments(s)
}

  • 每一個case都是一個通信
    • 必須為對channel操作(對channel發送數據 or 從channel中獲取數據 皆可)
  • (重要)如果有多個case都可運行,select會隨機地選出一個執行,其他case便不會執行
  • 否則:
    • 如果有default語句,則執行該語句
    • default語句時,select將阻塞,直到某個通信可以運行

Example I:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import (
"fmt"
"time"
)

func main(){
timer := time.NewTimer(1*time.Second)
timer2 := time.NewTimer(2*time.Second)
for i:=0;i<2;i++{
select {
case <-timer.C:
fmt.Println("1")
case <-timer2.C:
fmt.Println("2")
}
}

}

Result

1
2
1
2

Example II:

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
package main

import (
"fmt"
"time"
)

func main(){
ch1 := make(chan int,1)
ch2 := make(chan int)

go func(){
for {
ch2 <- 100
time.Sleep(100*time.Millisecond)
}
}()

for {
select {
case ch1 <- 1:
fmt.Println("1")
time.Sleep(1*time.Second)
case num := <- ch1:
fmt.Println("get data from ch1",num)
case <- ch2 :
fmt.Println("2")
}
}

}

Result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1
2
get data from ch1 1
1
get data from ch1 1
2
1
get data from ch1 1
2
1
2
get data from ch1 1
1
2
get data from ch1 1
1
get data from ch1 1
1
2