3 回答

TA貢獻1852條經驗 獲得超7個贊
1-當您處理一個頻道時,可以使用for,
考慮這個工作代碼(The Go Playground):
package main
import "fmt"
func main() {
ch := make(chan int, 2)
ch <- 1
ch <- 2
close(ch)
for range ch {
}
fmt.Println("Done.")
}
這將清空通道。
注意:您應該close使用通道或使用break語句來完成該循環。
2- 當您處理更多可能使用的頻道時select,就像這樣(The Go Playground):
for {
select {
case <-pause:
fmt.Println("pause")
select {
case <-play:
fmt.Println("play")
case <-quit:
wg.Done()
return
}
case <-quit:
wg.Done()
return
default:
work()
}
}
3- 使用 nil 和封閉通道(The Go Playground):
package main
import "fmt"
func main() {
var quit chan struct{} // nil
select {
case <-quit:
fmt.Println("1")
default:
fmt.Println("2") // This runs
}
quit = make(chan struct{}, 1)
select {
case <-quit:
fmt.Println("10")
default:
fmt.Println("20") // This runs
}
quit <- struct{}{} // send
select {
case <-quit:
fmt.Println("100") // This runs
default:
fmt.Println("200")
}
close(quit)
select {
case <-quit:
fmt.Println("1000") // This runs
default:
fmt.Println("2000")
}
select {
case <-quit:
fmt.Println("10000") // This runs
default:
fmt.Println("20000")
}
}
輸出:
2
20
100
1000
10000
選擇語句
“選擇”語句選擇一組可能的發送或接收操作中的哪一個將繼續。它看起來類似于“switch”語句,但所有案例都涉及通信操作。
具有 RecvStmt 的案例可以將 RecvExpr 的結果分配給一個或兩個變量,這些變量可以使用短變量聲明來聲明。RecvExpr 必須是(可能帶括號的)接收操作。最多可以有一個默認案例,它可能出現在案例列表中的任何位置。
“select”語句的執行分幾個步驟進行:
對于語句中的所有情況,在輸入“select”語句時,接收操作的通道操作數以及發送語句的通道和右側表達式僅按源順序計算一次。結果是一組要接收或發送到的通道,以及要發送的相應值。無論選擇哪種(如果有)通信操作進行,該評估中的任何副作用都會發生。RecvStmt 左側的帶有短變量聲明或賦值的表達式尚未計算。如果一個或多個通信可以進行,則通過統一的偽隨機選擇選擇一個可以進行的通信。否則,如果存在默認情況,則選擇該情況。如果沒有默認情況,則“選擇” 語句塊,直到至少有一個通信可以進行。除非所選案例是默認案例,否則執行相應的通信操作。如果所選用例是帶有短變量聲明或賦值的 RecvStmt,則計算左側表達式并分配接收到的值(或多個值)。執行所選案例的語句列表。由于 nil 通道上的通信永遠無法進行,因此只有 nil 通道且沒有默認案例的選擇會永遠阻塞。執行所選案例的語句列表。由于 nil 通道上的通信永遠無法進行,因此只有 nil 通道且沒有默認案例的選擇會永遠阻塞。執行所選案例的語句列表。由于 nil 通道上的通信永遠無法進行,因此只有 nil 通道且沒有默認案例的選擇會永遠阻塞。

TA貢獻1827條經驗 獲得超8個贊
在您的情況下,似乎一個簡單的循環就足夠了:
for _ = range ch { fmt.Println("drain")}
如果您有多個goroutines 需要處理,則 Select 是必需的。巡回賽有一個range 和 close的例子。
另一種情況select
是冪等通道關閉: https: //play.golang.org/p/_Ol42BvuuS。

TA貢獻1887條經驗 獲得超5個贊
如果 select 中只有一種情況,那么最好use for range instead of for { select {} } (gosimple)
使用S1000
golint 檢查。
for range
代碼就像:
for range ch { fmt.Println("here")}
- 3 回答
- 0 關注
- 518 瀏覽
添加回答
舉報