英文:
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 <-time.After(staticTimeoutInterval):
doSomething()
case <-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
}
关于switch和select的看似不一致的处理方式 - 虽然这两个语句的语法相似,但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 <-time.After(timeout):
doSomething()
}
func min(a, b time.Duration) int {
if a < 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:
switchis about the part after thecaseexpression - thecaseexpression here is mostly a simple, side-effect free expressionselectis about the part in thecaseexpression - thecaseexpression 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论