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

有没有办法问时间。在()之后无限期?

有没有办法问时间。在()之后无限期?

Go
慕尼黑5688855 2022-09-19 20:45:12
有没有办法要求无限的时间?time.After()动机:我有一个服务,调用方可以从中请求消息,但可以选择超时。这样做的明显方法是:func service(timeout *time.Duration) SomeType {    var timeout_value time.Duration    if timeout != nil {        timeout_value = *timeout    } else {        timeout_value = time.Forever /* or something */    }    select {    case value <- some_channel:        return value    case <- time.After(timeout_value):        return nil    }}除了我不知道是否有办法说.time.Forever
查看完整描述

3 回答

?
月关宝盒

TA贡献1772条经验 获得超5个赞

没有“永久”持续时间,但有最大持续时间:


const maxDuration time.Duration = 1<<63 - 1

maxDuration大约是292年。对于单个应用的生存期来说,它应该足够了。但相反,我提出了以下不使用它的解决方案:


请注意,如果“永远”是预期的最长等待时间,则省略和使用简单接收会更简单、更高效:time.After()


func service(timeout *time.Duration) SomeType {

    if timeout == nil {

        return <-some_channel

    }


    select {

    case value := <-some_channel:

        return value

    case <-time.After(*timeout):

        return nil

    }

}

您指出您的实际代码要复杂得多,并且包含更多事例。


在这种情况下,我会将超时通道创建移到语句之外,并相应地进行初始化。当 is 时,只需离开通道(其零值),该通道永远不会提供任何值,因此从通道接收从字面上看需要“永远”:selecttimeoutnilnilnil


func service(timeout *time.Duration) SomeType {

    var timeoutCh <-chan time.Time

    if timeout != nil {

        timeoutCh = time.After(*timeout)

    }


    select {

    case value := <-some_channel:

        return value

    case <-timeoutCh:

        return nil

    }

}


查看完整回答
反对 回复 2022-09-19
?
开满天机

TA贡献1786条经验 获得超13个赞

您可以接受上下文,而不是持续时间。函数中的上下文,我认为这在 Go 代码中非常习惯用语。

然后,调用方可以根据需要使用上下文背景或上下文调用该函数。该函数选择上下文的 ,如果背景上下文永不结束(chan 实际上为零)。serviceDone()

如果永远无法取消此上下文,则 Done 可能会返回 nil。[...]提供“完成”以用于选择语句

func callerNoTimeout() {

    foo := service(context.Background())

}


func callerTimeout() {

    foo := service(context.WithTimeout(context.Background(), timeOut))

}


func service(ctx context.Context) SomeType {

    select {

        case value <-some_channel:

            return value

        case <-ctx.Done():

            return nil

    }

}


查看完整回答
反对 回复 2022-09-19
?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

首先,通常的做法是使用 of(或负)来表示没有超时 - 因此没有必要传递指针。time.Duration0


其次,只需在强制实施超时时检查此零值:


func service(timeout time.Duration) SomeType {

    

    if timeout <= 0 {

        return <- some_channel


    }


    select {

        case value <- some_channel:

            return value

        case <- time.After(timeout):

            return nil

    }

}


查看完整回答
反对 回复 2022-09-19
  • 3 回答
  • 0 关注
  • 118 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号