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

为什么这个 Golang 代码不能在多个 time.After 通道中进行选择?

为什么这个 Golang 代码不能在多个 time.After 通道中进行选择?

Go
白猪掌柜的 2021-12-07 16:12:34
为什么这个 Golang 代码不能在多个 time.After 通道中进行选择?请参阅下面的代码。永远不会发出“超时”消息。为什么?package mainimport (    "fmt"    "time")func main() {    count := 0    for {        select {        case <-time.After(1 * time.Second):            count++            fmt.Printf("tick %d\n", count)            if count >= 5 {                fmt.Printf("ugh\n")                return            }        case <-time.After(3 * time.Second):            fmt.Printf("timeout\n")            return        }    }}在 Playground 上运行:http : //play.golang.org/p/1gku-CWVAh输出:tick 1tick 2tick 3tick 4tick 5ugh
查看完整描述

2 回答

?
森林海

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

因为time.After是一个函数,所以每次迭代都会返回一个新的通道。如果您希望此通道在所有迭代中都相同,则应在循环之前将其保存:


timeout := time.After(3 * time.Second)

for {

    select {

    //...

    case <-timeout:

        fmt.Printf("timeout\n")

        return

    }

}

游乐场:http : //play.golang.org/p/muWLgTxpNf。


查看完整回答
反对 回复 2021-12-07
?
叮当猫咪

TA贡献1776条经验 获得超12个赞

另一种可能性是使用time.Tick(1e9)每秒生成一个时间刻度,然后timeAfter在指定时间段后侦听频道。


package main


import (

    "fmt"

    "time"

)


func main() {

    count := 0

    timeTick := time.Tick(1 * time.Second)

    timeAfter := time.After(5 * time.Second)


    for {

        select {

        case <-timeTick:

            count++

            fmt.Printf("tick %d\n", count)

            if count >= 5 {

                fmt.Printf("ugh\n")

                return

            }

        case <-timeAfter:

            fmt.Printf("timeout\n")

            return

        }

    }

}


查看完整回答
反对 回复 2021-12-07
  • 2 回答
  • 0 关注
  • 176 浏览
慕课专栏
更多

添加回答

举报

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