Go中select行為規(guī)則和執(zhí)行順序的實(shí)現(xiàn)
Go 語言中 select 語句的行為規(guī)則和執(zhí)行順序。
? 規(guī)則1:每個(gè)case表達(dá)式必須有發(fā)送或接收操作,可能還有其他表達(dá)式
含義:
每個(gè) case 至少要有一個(gè)通道操作(<-chan 或 chan<-),可以搭配賦值、函數(shù)調(diào)用等。
示例:
ch := make(chan int, 1)
select {
case x := <-ch: // 接收操作 + 賦值
fmt.Println("Received:", x)
}
select {
case ch <- computeValue(): // 發(fā)送操作 + 函數(shù)調(diào)用
fmt.Println("Sent")
}
? 規(guī)則2:表達(dá)式求值順序是從上到下,從左到右
含義:
所有 case 分支中的表達(dá)式,在 select 執(zhí)行之初就按書寫順序全部求值。表達(dá)式多于一個(gè)時(shí),按從左到右順序求值。
示例:
ch1 := make(chan int)
ch2 := make(chan int)
select {
case x := <-ch1:
fmt.Println("ch1", x)
case y := <-ch2:
fmt.Println("ch2", y)
}
上面例子中:
- ch1 的接收表達(dá)式會先被求值;
- 然后 ch2;
- 然后再看哪個(gè)能成功進(jìn)行選擇。
? 規(guī)則3:如果通道操作阻塞,case 就不滿足條件
含義:
當(dāng)某個(gè) case 執(zhí)行通道操作時(shí),如果它會阻塞(比如通道沒數(shù)據(jù),或者通道滿) ,它就不能被選中。
示例:
ch := make(chan int)
select {
case ch <- 1: // 沒有接收方,發(fā)送會阻塞
fmt.Println("sent")
default:
fmt.Println("default")
}
輸出:
default
? 規(guī)則4:只有所有 case 表達(dá)式求值完后,select 才選分支
含義:
select 要先靜態(tài)地評估所有分支是否能執(zhí)行,然后才在滿足條件的分支中挑選一個(gè)。
示例:
ch := make(chan int, 1)
ch <- 42
select {
case x := <-ch: // 可執(zhí)行
fmt.Println("got", x)
case y := <-ch: // 不可執(zhí)行(通道空了)
fmt.Println("got", y)
}
輸出:
got 42
? 規(guī)則5:多個(gè)可選分支時(shí),select 隨機(jī)選一個(gè)
含義:
多個(gè)分支都可執(zhí)行時(shí),select 不會按照書寫順序選第一個(gè),而是隨機(jī)選一個(gè)。
示例:
ch1 := make(chan int, 1)
ch2 := make(chan int, 1)
ch1 <- 1
ch2 <- 2
select {
case x := <-ch1:
fmt.Println("ch1", x)
case y := <-ch2:
fmt.Println("ch2", y)
}
輸出可能是:
ch1 1
或者
ch2 2
? 規(guī)則6:default分支最多只能有一個(gè),并且只在無其他可選時(shí)執(zhí)行
含義:
- default 分支不能有多個(gè);
- 它只有在所有 case 都阻塞時(shí)才會被執(zhí)行;
- 不管你把它寫在最上面還是最下面,它只有在“無可選分支”時(shí)才會被選中。
示例:
ch := make(chan int)
select {
default:
fmt.Println("default executed")
case <-ch:
fmt.Println("received")
}
輸出:
default executed
小結(jié)
| 場景描述 | 是否滿足選擇條件 |
|---|---|
| 通道有數(shù)據(jù)可讀(接收操作) | ? |
| 通道有空位可寫(發(fā)送操作) | ? |
| 通道阻塞(接收或發(fā)送都不能繼續(xù)) | ? |
| 所有 case 都阻塞 + 有 default | 選中 default |
| 所有 case 都阻塞 + 無 default | select 阻塞 |
| 多個(gè) case 都滿足條件 | 隨機(jī)選一個(gè) |
到此這篇關(guān)于Go中select行為規(guī)則和執(zhí)行順序的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Go select行為規(guī)則和執(zhí)行順序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang實(shí)現(xiàn)sql結(jié)果集以json格式輸出的方法
這篇文章主要介紹了golang實(shí)現(xiàn)sql結(jié)果集以json格式輸出的方法,涉及Go語言針對sql結(jié)果集的遍歷、轉(zhuǎn)換及json格式相關(guān)操作技巧,需要的朋友可以參考下2017-03-03
Go語言基于Goroutine的超時(shí)控制方案設(shè)計(jì)與實(shí)踐
Go語言因其并發(fā)特性而備受青睞,尤其是goroutine和channel的組合,像一對默契的搭檔,為開發(fā)者提供了輕量、高效的并發(fā)工具,下面我們來看看基于goroutine的超時(shí)控制方案吧2025-05-05

