亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

選擇單個案例塊,添加默認值:unblocks

選擇單個案例塊,添加默認值:unblocks

Go
紅顏莎娜 2022-03-02 19:27:18
在用這樣的東西測試一些代碼時:// ch := make(chan error)for {    select {      case <- ch:           println("here")    }}我注意到,如果我不添加default代碼塊:for {    select {       case <- ch:            println("here")       default:    }}如果需要該塊,最好使用range,例如:for {    for _ = range <- ch {        println("here")    }}或者在這種情況下使用selectover有什么區別/優勢嗎?range
查看完整描述

3 回答

?
慕姐4208626

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 通道且沒有默認案例的選擇會永遠阻塞。


查看完整回答
反對 回復 2022-03-02
?
斯蒂芬大帝

TA貢獻1827條經驗 獲得超8個贊

在您的情況下,似乎一個簡單的循環就足夠了:

for _ = range ch {
    fmt.Println("drain")}

如果您有多個goroutines 需要處理,則 Select 是必需的。巡回賽有一個range 和 close的例子。

另一種情況select是冪等通道關閉: https: //play.golang.org/p/_Ol42BvuuS。


查看完整回答
反對 回復 2022-03-02
?
慕工程0101907

TA貢獻1887條經驗 獲得超5個贊

如果 select 中只有一種情況,那么最好use for range instead of for { select {} } (gosimple)使用S1000golint 檢查。

for range代碼就像:

for range ch {
    fmt.Println("here")}



查看完整回答
反對 回復 2022-03-02
  • 3 回答
  • 0 關注
  • 518 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號