首頁  >  文章  >  後端開發  >  詳解Golang中switch語句和select語句的用法

詳解Golang中switch語句和select語句的用法

零下一度
零下一度原創
2017-06-29 15:30:281900瀏覽

這篇文章主要給大家介紹了關於Golang中switch和select的用法教程,文中透過範例程式碼將switch語句與select語句的使用方法介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面跟著小編一起來學習學習吧。

本文主要介紹了Golang中switch和select用法的相關內容,分享出來供大家參考學習,以下來一起看看詳細的介紹:

一、switch語句

switch語句提供了一個多分支條件執行的方法。每一個case可以攜帶一個表達式或一個型別說明符。前者又可簡稱為case表達式。因此,Go語言的switch語句又分為表達式switch語句和型別switch語句。

1、表達式switch語句


#
var name string 
... 
switch name { 
case "Golang": 
 fmt.Println("Golang") 
case "Rust": 
 fmt.Println("Rust") 
default: 
 fmt.Println("PHP是世界上最好的语言") 
}

Go會依照從上到下的順序對每一則case語句中case表達式進行求值,只要被發現其表達式與switch表達式的結果相同,該case語句就會被選取。其餘的case語句會被忽略。與if相同,switch語句也可以包含初始化字句,且其出現位置與寫法如出一轍:


names := []string{"Golang","java","PHP"} 
switch name:=names[0];name { 
case "Golang": 
 fmt.Println("Golang") 
... 
default: 
 fmt.Println("Unknown") 
}

2、型別switch語句

類型switch語句與一般形式有兩點差異。第一點,緊接在case關鍵字的不是表達式,而是類型說明符。類型說明符由若干個類型字面量組成,且多個類型字面量之間由英文逗號分隔。第二點,它的switch表達式是非常特殊的。這個特殊的表達式也起到了類型斷言的作用,但其表現形式很特殊,如:v.(type) , 其中v必須代表一個介面類型的值。該類別表達式只能出現在類型switch語句中,且只能充當switch表達式。一個型別switch語句的範例如下:


v := 11 
switch i := interface{}(v).(type) { 
case int, int8, int16, int32, int64: 
 fmt.Println("A signed integer:%d. The type is %T. \n", v, i) 
case uint, uint8, uint16, uint32, uint64: 
 fmt.Println("A unsigned integer: %d. The type is %T. \n", v, i) 
default: 
 fmt.Println("Unknown!") 
}

我們這裡把switch表達式的結果賦給了一個變數。如此以來,我們就可以在該switch語句中使用這個結果了。這段程式碼被執行後,輸出:"A signed integer:11. The type is int. "

最後說一下fallthrough。它既是一個關鍵字,又可以代表一條語句。 fallthrough語句可被包含在表達式switch語句中的case語句中。它的作用是使控制權流轉到下一個case。不過要注意fallthrough語句僅能以case語句中的最後一條語句出現。並且,包含它的case語句不是其所屬switch語句的最後一個case語句。

二、select語句

#golang 的select 的功能和select, poll, epoll 相似, 就是監聽IO操作,當IO 操作發生時,觸發對應的動作。

範例:


ch1 := make (chan int, 1) 
ch2 := make (chan int, 1) 
 
... 
 
select { 
case <-ch1: 
 fmt.Println("ch1 pop one element") 
case <-ch2: 
 fmt.Println("ch2 pop one element") 
}

注意到select 的程式碼形式和switch 非常相似, 不過select 的case 裡的操作語句只能是【 IO 操作】 。

此範例裡面 select 會一直等待等到某個 case 語句完成, 也就是等到成功從 ch1 或 ch2 讀到資料。 則 select 語句結束。

break語句也可以被包含在select語句中的case語句中。它的作用是立即結束目前的select語句的執行。不論其所屬的case語句中是否還有未被執行的語句。

【使用select 實作timeout 機制】

如下:


timeout := make(chan bool, 1) 
go func() { 
 time.Sleep(time.Second * 10) 
 timeout <- true 
}() 
select { 
case <-pssScanResponseChan: 
 
case <-timeout: 
 fmt.PrintIn("timeout!") 
}

當逾時時間到的時候, case2 會操作成功。 所以 select 語句則會退出。 而不是一直阻塞在 ch 的讀取操作上。 從而實現了對 ch 讀取操作的逾時設定。

下面這個比較有意思一點。

當select 語句帶有default 的時候:


ch1 := make (chan int, 1) 
ch2 := make (chan int, 1) 
 
select { 
case <-ch1: 
 fmt.Println("ch1 pop one element") 
case <-ch2: 
 fmt.Println("ch2 pop one element") 
default: 
 fmt.Println("default") 
}

此時因為ch1 和ch2 都為空,所以case1 和case2 都不會讀取成功。 則 select 執行 default 語句。

就是因為這個 default 特性, 我們可以使用 select 語句來偵測 chan 是否已經滿了。

如下:


ch := make (chan int, 1) 
ch <- 1 
select { 
case ch <- 2: 
default: 
 fmt.Println("channel is full !") 
}

因為ch 插入1 的時候已經滿了, 當ch 要插入2 的時候,發現ch 已經滿了(case1 阻塞住), 則select 執行default 語句。 這樣就可以實現對 channel 是否已滿的檢測, 而不是一直等待。

例如我們有一個服務, 當請求進來的時候我們會產生一個 job 丟進 channel, 由其他協程從 channel 中取得 job 去執行。 但我們希望當 channel 瞞了的時候, 將該 job 拋棄並回复 【服務繁忙,請稍微再試。 】 就可以用 select 實現該需求。

此外,利用default特性,我们可以使用select语句将chan清空,如下:


flag := false 
for { 
 select { 
 case <-pssScanResponseChan: 
 continue 
 default: 
 flag = true 
 } 
 if true == flag { 
 break 
 } 
}

以上是詳解Golang中switch語句和select語句的用法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn