29 Go 語言中的 select 用法

2021-10-06 21:43:46 字數 3857 閱讀 6237

流程控制:switch-case

go 語言中的型別斷言

今天要學習乙個跟switch-case很像,但還有點個人特色select-case,這一節本應該放在 學習 go 協程:詳解通道/通道 裡一起講的,但是當時漏了,直到有讀者給我提出,才注意到,今天就用這篇文章補充一下。

跟 switch-case 相比,select-case 用法比較單一,它僅能用於 通道/通道 的相關操作。

select
接下來,我們來看幾個例子幫助理解這個 select 的模型。

先建立兩個通道,並在 select 前往 c2 傳送資料

package main

import (

"fmt"

)func main()

}

在執行 select 時,會遍歷所有(如果有機會的話)的 case 表示式,只要有乙個通道有接收到資料,那麼 select 就結束,所以輸出如下

c2 received:  hello
select 在執行過程中,必須命中其中的某一分支。

如果在遍歷完所有的 case 後,若沒有命中(命中:也許這樣描述不太準確,我本意是想說可以執行通道的操作語句)任何乙個 case 表示式,就會進入 default 裡的**分支。

但如果你沒有寫 default 分支,select 就會阻塞,直到有某個 case 可以命中,而如果一直沒有命中,select 就會丟擲deadlock的錯誤,就像下面這樣子。

package main

import (

"fmt"

)func main()

}

執行後輸出如下

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [select]:

main.main()

/users/ming/golandprojects/golang-test/main.go:13 +0x10f

exit status 2

解決這個問題的方法有兩種乙個是,養成好習慣,在 select 的時候,也寫好 default 分支**,儘管你 default 下沒有寫任何**。

package main

import (

"fmt"

)func main()

}

另乙個是,讓其中某乙個通道可以接收到資料

package main

import (

"fmt"

"time"

)func main() ()

select

}

之前學過 switch 的時候,知道了 switch 裡的 case 是順序執行的,但在 select 裡卻不是。

通過下面這個例子的執行結果就可以看出

當 case 裡的通道始終沒有接收到資料時,而且也沒有 default 語句時,select 整體就會阻塞,但是有時我們並不希望 select 一直阻塞下去,這時候就可以手動設定乙個超時時間。

package main

import (

"fmt"

"time"

)func maketimeout(ch chan bool, t int)

func main()

}

輸出如下

timeout, exit.
上面例子裡的 case,好像都只從通道中讀取資料,但實際上,select 裡的 case 表示式只要求你是對通道的操作即可,不管你是往通道寫入資料,還是從通道讀出資料。

package main

import (

"fmt"

)func main()

}

輸出如下

c1 received:  2

c1 received: 4

select 只能用於 channel 的操作(寫入/讀出),而 switch 則更通用一些;

select 的 case 是隨機的,而 switch 裡的 case 是順序執行;

select 要注意避免出現死鎖,同時也可以自行實現超時機制;

select 裡沒有類似 switch 裡的 fallthrough 的用法;

select 不能像 switch 一樣接函式或其他表示式。

01. 開發環境的搭建(goland & vs code)

02. 學習五種變數建立的方法

03. 詳解資料型別:**整形與浮點型**

04. 詳解資料型別:byte、rune與string

05. 詳解資料型別:陣列與切片

06. 詳解資料型別:字典與布林型別

07. 詳解資料型別:指標

08. 物件導向程式設計:結構體與繼承

09. 一篇文章理解 go 裡的函式

10. go語言流程控制:if-else 條件語句

11. go語言流程控制:switch-case 選擇語句

12. go語言流程控制:for 迴圈語句

13. go語言流程控制:goto 無條件跳轉

14. go語言流程控制:defer 延遲呼叫

15. 物件導向程式設計:介面與多型

16. 關鍵字:make 和 new 的區別?

17. 一篇文章理解 go 裡的語句塊與作用域

18. 學習 go 協程:goroutine

19. 學習 go 協程:詳解通道/通道

20. 幾個通道死鎖經典錯誤案例詳解

21. 學習 go 協程:waitgroup

22. 學習 go 協程:互斥鎖和讀寫鎖

23. go 裡的異常處理:panic 和 recover

24. 超詳細解讀 go modules 前世今生及入門使用

25. go 語言中關於包匯入必學的 8 個知識點

26. 如何開源自己寫的模組給別人用?

27. 說說 go 語言中的型別斷言?

28. 這五點帶你理解go語言的select用法

29《Go語言入門》帶緩衝通道

這是我純手寫的 go語言入門 手把手教你入門go。原始碼 文章,看了你就會?文章中所有的 我都放到了github.com ganzhixiong go learning這個倉庫中!看文章時,對照倉庫中 學習效果更佳哦!建立帶緩衝通道 支援?帶緩衝通道 buffered channel 是一種在被接收...

go語言中 select的使用方法

早期的select函式是用來監控一系列的檔案控制代碼,一旦其中乙個檔案控制代碼發生io操作,該select呼叫就會被返回。golang在語言級別直接支援select,用於處理非同步io問題。select用法同switch類似,如下 timeout make chan bool,1 ch make c...

go 語言中的繼承

go 語言中可以通過匿名field來實現繼承的效果,type t1 struct func t t1 log func t t1 print type t2 struct t2 t2 可以通過t2.log 直接訪問t1的method,就像物件導向的繼承之後一樣訪問,不過這裡要注意的傳遞到log的是t...