如何在 Golang 中使用“time.After”和“default”?

我正在尝试理解 Golang 例程的简单代码:


package main


import (

    "fmt"

    "time"

)


func sleep(seconds int, endSignal chan<- bool) {

    time.Sleep(time.Duration(seconds) * time.Second)

    endSignal <- true

}


func main() {

    endSignal := make(chan bool, 1)

    go sleep(3, endSignal)

    var end bool


    for !end {

        select {

        case end = <-endSignal:

            fmt.Println("The end!")

        case <-time.After(5 * time.Second):

            fmt.Println("There's no more time to this. Exiting!")

            end = true

        }

    }


}

很好,但是为什么我不能在这个“选择”块中使用简单的默认值?像这样的东西:


for !end {

    select {

    case end = <-endSignal:

        fmt.Println("The end.")

    case <-time.After(4 * time.Second):

        fmt.Println("There's no more time to this. Exiting!")

        end = true

    default:

        fmt.Println("No end signal received.")

    }

}

它得到这个输出:


❯ go run goroutines-timeout.go

No end signal received!

No end signal received!

No end signal received!

No end signal received!

...

The end!

我不明白为什么。


UYOU
浏览 153回答 1
1回答

慕斯王

每次执行时,time.After(4 * time.Second)您都会创建一个新的计时器通道。该select语句无法记住它在上一次迭代中选择的通道。您还采用了异步操作并将其变成了一个繁忙的循环,从而违背了select语句的目的。您所需要的只是围绕您感兴趣的两个频道进行简单的选择。它根本不需要循环。select {case <-endSignal:&nbsp; &nbsp; fmt.Println("The end!")case <-time.After(4 * time.Second):&nbsp; &nbsp; fmt.Println("There's no more time to this. Exiting!")}https://play.golang.org/p/jb4EE8e6cw如果您真的想多次轮询,请将计时器设置在 for 循环之外,以便每次迭代都检查相同的计时器timeout := time.After(5 * time.Second)pollInt := time.Secondfor {&nbsp; &nbsp; select {&nbsp; &nbsp; case <-endSignal:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("The end!")&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; case <-timeout:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("There's no more time to this. Exiting!")&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("still waiting")&nbsp; &nbsp; }&nbsp; &nbsp; time.Sleep(pollInt)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go