为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
UYOU 2022-03-07 15:52:39
我正在尝试理解 Golang 例程的简单代码:package mainimport (    "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.goNo end signal received!No end signal received!No end signal received!No end signal received!...The end!我不明白为什么。
查看完整描述

1 回答

?
慕斯王

TA贡献1864条经验 获得超2个赞

每次执行时,time.After(4 * time.Second)您都会创建一个新的计时器通道。该select语句无法记住它在上一次迭代中选择的通道。您还采用了异步操作并将其变成了一个繁忙的循环,从而违背了select语句的目的。


您所需要的只是围绕您感兴趣的两个频道进行简单的选择。它根本不需要循环。


select {

case <-endSignal:

    fmt.Println("The end!")

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

    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.Second


for {

    select {

    case <-endSignal:

        fmt.Println("The end!")

        return

    case <-timeout:

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

        return

    default:

        fmt.Println("still waiting")

    }

    time.Sleep(pollInt)

}


查看完整回答
反对 回复 2022-03-07
  • 1 回答
  • 0 关注
  • 152 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信