英文:
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:
switch
is about the part after thecase
expression - thecase
expression here is mostly a simple, side-effect free expressionselect
is about the part in thecase
expression - thecase
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论