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
}
}

TA贡献1786条经验 获得超13个赞
您可以接受上下文,而不是持续时间。函数中的上下文
,我认为这在 Go 代码中非常习惯用语。
然后,调用方可以根据需要使用上下文
背景或上下文
调用该函数。该函数选择上下文的 ,如果背景上下文永不结束(chan 实际上为零)。service
Done()
如果永远无法取消此上下文,则 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
}
}

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
}
}
- 3 回答
- 0 关注
- 118 浏览
添加回答
举报