1. 程式人生 > >【基本流程控制】4.select語句

【基本流程控制】4.select語句

Go語言-select語句

    select語句屬於條件分支流程控制方法,不過它只能用於通道。它可以包含若干條case語句,並根據條件選擇其中的一個執行。進一步說,select語句中的case關鍵字只能後跟用於通道的傳送操作的表示式以及接收操作的表示式或語句。示例如下:

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語句被執行時通道ch1ch2中都沒有任何資料,那麼肯定只有default case會被執行。但是,只要有一個通道在當時有資料就不會輪到default case執行了。顯然,對於包含通道接收操作的case來講,其執行條件就是通道中存在資料(或者說通道未空)。如果在當時有資料的通道多於一個,那麼Go語言會通過一種偽隨機的演算法來決定哪一個case將被執行。
   
   另一方面,對於包含通道傳送操作的case來講,其執行條件就是通道中至少還能緩衝一個數據(或者說通道未滿)。類似的,當有多個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的傳送操作。如果我們把這條語句置於一個迴圈中,那麼就相當於用有限範圍的隨機整數集合去填滿一個通道。
   
    請注意,如果一條select

語句中不存在default case, 並且在被執行時其中的所有case都不滿足執行條件,那麼它的執行將會被阻塞!當前流程的進行也會因此而停滯。直到其中一個case滿足了執行條件,執行才會繼續。我們一直在說case執行條件的滿足與否取決於其操作的通道在當時的狀態。這裡特別強調一點,即:未被初始化的通道會使操作它的case永遠滿足不了執行條件。對於針對它的傳送操作和接收操作來說都是如此。
  
    最後提一句,break語句也可以被包含在select語句中的case語句中。它的作用是立即結束當前的select語句的執行,不論其所屬的case語句中是否還有未