break in select will not break the outer for loop

背景

后臺(tái)廣告系統(tǒng)匹配由串行轉(zhuǎn)為并行,涉及到并發(fā)數(shù)控制和一些資源回收工作,利用channel去做非常容易實(shí)現(xiàn)。細(xì)節(jié)是魔鬼,還是寫的少:)

有問(wèn)題代碼示例

有問(wèn)題代碼

代碼實(shí)現(xiàn)功能很簡(jiǎn)單,for 循環(huán)中接收 N 個(gè) channel 的數(shù)據(jù),業(yè)務(wù) channel 傳送業(yè)務(wù)數(shù)據(jù),最后一個(gè) ch 用來(lái)傳遞取消信號(hào),如果 ch 接收到數(shù)據(jù)那么退出 for 循環(huán)。按照 C-LIKE 習(xí)慣,理想的輸出肯定這樣的:

start cancel

do something?

do something

do something

receive cancel 0

over

但是真實(shí)情況是:

start cancel

do something

do something

do something

receive cancel :0receive cancel :0 無(wú)數(shù)個(gè) receive cancel :0陷入死循環(huán)?

channel 特性

先拋開(kāi)問(wèn)題,簡(jiǎn)單列一個(gè) channel 的特性

1. buffered channel 和 unbuffered channel,緩沖與否的區(qū)別

2. 寫入關(guān)閉的 channel 會(huì)導(dǎo)致panic

3. 數(shù)據(jù)未消費(fèi)完的 buffered channel 關(guān)閉后,是可以讀到未消費(fèi)數(shù)據(jù)

4. 無(wú)數(shù)據(jù)的 channel 關(guān)閉后,可以立刻讀到該類型的零值

死循環(huán)原因

上面列的 channel 特性只是為了湊數(shù) ~~

Golang 中的 break 有兩種寫法,一個(gè)是 break, 一個(gè)是 break [label], 見(jiàn)官方文檔,經(jīng)過(guò)測(cè)試有如下結(jié)論:

1. 不帶 label 的break,只能退出最近的 loop,并且對(duì) select, switch 無(wú)效

2. 帶 label 的 break,對(duì) for, select , switch 均有效

3. break 的 label 只能附著在同一函數(shù)的 for, select 或 switch 語(yǔ)句上,對(duì)比來(lái)講 goto 的 label就隨意一些

退出的正確姿勢(shì)


break

或是用 C-Like 的goto

goto
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容