英文:
What is the preferred approach to do non-blocking select statement with channels in Go
问题
这里有一个我想要做的例子:
func (zoo *Zoo) feedAnimals(food Food) {
for animal := range zoo.Animals {
select {
case animal.EatChan() <- food:
default: // 什么都不做
}
}
}
动物的EatChan
有一个小缓冲区,有时feedAnimals
的调用频率比某些动物消耗食物的速度更快。当这种情况发生时,如果我省略select
块中的default
语句,select
语句将阻塞for循环
,其他饥饿的动物将无法获得食物。因此,我宁愿跳过已经饱食的动物(即通道已达到其容量)。
然而,只有一个空的default
语句对我来说感觉很奇怪。有没有更好的方法来做到这一点?
英文:
Here's an example with what I want to do
func (zoo *Zoo) feedAnimals(food Food) {
for animal := range zoo.Animals {
select {
case animal.EatChan() <- food:
default: // Do nothing
}
}
}
Animal's EatChan
has a small buffer, some times rate of which feedAnimals
is called more often than the rate of which some animals can consume the food. When that happens, if I omit default
statement in the select
block, the select statement will block the for loop
and other hungry animals can't get their food. So I'd rather skip the animal that is full (i.e. the channel has reached its capacity.)
However, having an empty default
feels weird to me. Is there a better way to do this?
答案1
得分: 2
然而,对我来说,使用一个空的默认值感觉很奇怪。
不应该感觉奇怪。
有没有更好的方法来做这个?
没有。
你已经做得很正确了。空的默认值不是一个“什么都不做”的语句,而是一个“不阻塞”的语句。这只是非阻塞选择的语义。
英文:
> However, having an empty default feels weird to me.
It shouldn't.
> Is there a better way to do this?
No.
You're already doing it properly. The empty default isn't a "do nothing" statement, it's a "don't block" statement. This is just the semantics of how a non-blocking select works.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论