How do I react to input from multiple channels the same way in Go?

huangapple go评论88阅读模式
英文:

How do I react to input from multiple channels the same way in Go?

问题

我有一些并发代码,其中有两个不同的超时时间间隔,一个是静态的,一个是动态的。我希望对它们都采取相同的反应方式。以下是代码的要点:

select {
case <-time.After(staticTimeoutInterval):
    doSomething()
case <-time.After(dynamicTimeoutInterval):
    doSomething()
}

有没有办法只写一次doSomething()?奇怪的是,select在这方面不如switch灵活。

英文:

I have some concurrent code that has two different timeout intervals, one static and one dynamic. I want to react the same way to both of them. This is the gist of it:

select {
case &lt;-time.After(staticTimeoutInterval):
    doSomething()
case &lt;-time.After(dynamicTimeoutInterval):
    doSomething()
}

Is there any way to write doSomething() only once? It's strange that select isn't as flexible as switch in this respect.

答案1

得分: 3

在你的特定情况下,你可以使用类似以下的代码:

timeout := min(staticTimeoutInterval, dynamicTimeoutInterval)

select {
case <-time.After(timeout):
    doSomething()
}

func min(a, b time.Duration) int {
    if a < b {
        return a
    }
    return b
}

关于switchselect的看似不一致的处理方式 - 虽然这两个语句的语法相似,但switch的目的是分支执行,而select的目的是通信。

如果我可以夸张一下:

  • switch关注的是case表达式之后的部分 - 这里的case表达式大多是一个简单的、无副作用的表达式
  • select关注的是case表达式中的部分 - 这里的case表达式为你提供了重要的通信副作用,而且实现起来并不简单

select中允许使用fallthrough可以在某些情况下节省几行代码,但它往往会使select语句更难理解。在其他情况下,Go 语言的创建者们几乎总是选择更冗长但更容易理解的方式。

英文:

In your specific case you can use something like

timeout := min(staticTimeoutInterval, dynamicTimeoutInterval)

select {
case &lt;-time.After(timeout):
	doSomething()
}

func min(a, b time.Duration) int {
	if a &lt; b {
		return a
	}
	return b
}

About the seemingly inconsistent treatment of switch and select - while these statements have similar syntax, the purpose of switch is branched execution, while the purpose of select is communication.

If I can exaggerate:

  • switch is about the part after the case expression - the case expression here is mostly a simple, side-effect free expression
  • select is about the part in the case expression - the case expression here provides you with the important communication side effect and is not trivial to implement at all

Allowing fallthrough in select will allow you to save a couple of lines in some cases, but it will often make select statements harder to reason about. Given a similar choice in other situations, the Go creators have almost always gone with more verbose but simpler to understand.

答案2

得分: 0

你得到的看起来是正确的。select语句不会穿透。如果它穿透了,会降低代码的清晰度,并且导致代码行数相同。

英文:

What you got looks right. select cases do not fall through. And if it did, it would remove clarity and result in the same number of lines of code.

huangapple
  • 本文由 发表于 2016年3月25日 10:59:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/36213355.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定