官方定義
每個case都必須是一個通信
所有channel表達式都會被求值
所有被發送的表達式都會被求值
如果任意某個通信可以進行,它就執行;其他被忽略。
如果有多個case都可以運行,Select會隨機公平地選出一個執行。其他不會執行。否則,如果有default子句,則執行該語句;如果沒有default字句,select將阻塞,直到某個通信可以運行;Go不會重新對channel或值進行求值。
舉例說明
下面針對官方的定義,我們結合例子看一下。
首先,列舉一下select語句中,case會出現的操作:
- channel操作
case中為channel操作時,select用來監聽和channel有關的IO操作。示例-1中若ch1和ch2有讀寫操作,就會觸發執行case中的代碼。
若ch1和ch2都有讀寫操作,select隨機選擇一個執行
//示例-1
ch1 := make(chan int)
ch2 := make(chan int)
select {
case <-ch1:
fmt.println("ch1")
case <-ch2:
fmt.println("ch2")
}
//示例-2
- 表達式
var ch1 chan int
var ch2 chan int
var chs = []chan int{ch1, ch2}
var numbers = []int{1, 2, 3, 4, 5}
func getNumber(i int) int {
fmt.Printf("numbers[%d]\n", i)
return numbers[i]
}
func getChan(i int) chan int {
fmt.Printf("chs[%d]\n", i)
return chs[i]
}
select {
case getChan(0) <- getNumber(2):
case getChan(1) <- getNumber(3):
}