Go開發(fā)工程師
未來3-5年企業(yè)高性能項目不可替代的語言,從基礎到項目實戰(zhàn)再到重構,真正從入門到精通
select語句屬于條件分支流程控制方法,不過它只能用于通道。它可以包含若干條case語句,并根據(jù)條件選擇其中的一個執(zhí)行。進一步說,select語句中的case關鍵字只能后跟用于通道的發(fā)送操作的表達式以及接收操作的表達式或語句。示例如下:
ch1 := make(chan int, 1)
ch2 := make(chan int, 1)
// 省略若干條語句
select {
case e1 := <-ch1:
fmt.Printf("1th case is selected. e1=%v.\n", e1)
case e2 := <-ch2:
fmt.Printf("2th case is selected. e2=%v.\n", e2)
default:
fmt.Println("No data!")
}
如果該select語句被執(zhí)行時通道ch1和ch2中都沒有任何數(shù)據(jù),那么肯定只有default case會被執(zhí)行。但是,只要有一個通道在當時有數(shù)據(jù)就不會輪到default case執(zhí)行了。顯然,對于包含通道接收操作的case來講,其執(zhí)行條件就是通道中存在數(shù)據(jù)(或者說通道未空)。如果在當時有數(shù)據(jù)的通道多于一個,那么Go語言會通過一種偽隨機的算法來決定哪一個case將被執(zhí)行。
另一方面,對于包含通道發(fā)送操作的case來講,其執(zhí)行條件就是通道中至少還能緩沖一個數(shù)據(jù)(或者說通道未滿)。類似的,當有多個case中的通道未滿時,它們會被隨機選擇。請看下面的示例:
ch3 := make(chan int, 100)
// 省略若干條語句
select {
case ch3 <- 1:
fmt.Printf("Sent %d\n", 1)
case ch3 <- 2:
fmt.Printf("Sent %d\n", 2)
default:
fmt.Println("Full channel!")
}
該條select語句的兩個case中包含的都是針對通道ch3的發(fā)送操作。如果我們把這條語句置于一個循環(huán)中,那么就相當于用有限范圍的隨機整數(shù)集合去填滿一個通道。
請注意,如果一條select語句中不存在default case, 并且在被執(zhí)行時其中的所有case都不滿足執(zhí)行條件,那么它的執(zhí)行將會被阻塞!當前流程的進行也會因此而停滯。直到其中一個case滿足了執(zhí)行條件,執(zhí)行才會繼續(xù)。我們一直在說case執(zhí)行條件的滿足與否取決于其操作的通道在當時的狀態(tài)。這里特別強調(diào)一點,即:未被初始化的通道會使操作它的case永遠滿足不了執(zhí)行條件。對于針對它的發(fā)送操作和接收操作來說都是如此。
最后提一句,break語句也可以被包含在select語句中的case語句中。它的作用是立即結束當前的select語句的執(zhí)行,不論其所屬的case語句中是否還有未被執(zhí)行的語句。
在命令源碼文件index.go的第 15 行和第 18 行添加一條語句,使該文件被執(zhí)行時會在標準輸出上打印出:
No Data! 1 End.
在第15行添加
close(ch4)
在第18行添加
ch4 <- 1
請驗證,完成請求
由于請求次數(shù)過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報