break in select will not break the outer for loop

背景

后臺廣告系統匹配由串行轉為并行,涉及到并發數控制和一些資源回收工作,利用channel去做非常容易實現。細節是魔鬼,還是寫的少:)

有問題代碼示例

有問題代碼

代碼實現功能很簡單,for 循環中接收 N 個 channel 的數據,業務 channel 傳送業務數據,最后一個 ch 用來傳遞取消信號,如果 ch 接收到數據那么退出 for 循環。按照 C-LIKE 習慣,理想的輸出肯定這樣的:

start cancel

do something?

do something

do something

receive cancel 0

over

但是真實情況是:

start cancel

do something

do something

do something

receive cancel :0receive cancel :0 無數個 receive cancel :0陷入死循環?

channel 特性

先拋開問題,簡單列一個 channel 的特性

1. buffered channel 和 unbuffered channel,緩沖與否的區別

2. 寫入關閉的 channel 會導致panic

3. 數據未消費完的 buffered channel 關閉后,是可以讀到未消費數據

4. 無數據的 channel 關閉后,可以立刻讀到該類型的零值

死循環原因

上面列的 channel 特性只是為了湊數 ~~

Golang 中的 break 有兩種寫法,一個是 break, 一個是 break [label], 見官方文檔,經過測試有如下結論:

1. 不帶 label 的break,只能退出最近的 loop,并且對 select, switch 無效

2. 帶 label 的 break,對 for, select , switch 均有效

3. break 的 label 只能附著在同一函數的 for, select 或 switch 語句上,對比來講 goto 的 label就隨意一些

退出的正確姿勢


break

或是用 C-Like 的goto

goto
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容