英文:
Why doesn't this Golang code to select among multiple time.After channels work?
问题
为什么这段 Golang 代码中选择多个 time.After 通道的部分不起作用?
请看下面的代码。"timeout" 消息从未被输出。为什么呢?
package main
import (
"fmt"
"time"
)
func main() {
count := 0
for {
select {
case <-time.After(1 * time.Second):
count++
fmt.Printf("tick %d\n", count)
if count >= 5 {
fmt.Printf("ugh\n")
return
}
case <-time.After(3 * time.Second):
fmt.Printf("timeout\n")
return
}
}
}
在 Playground 上运行它:http://play.golang.org/p/1gku-CWVAh
输出:
tick 1
tick 2
tick 3
tick 4
tick 5
ugh
英文:
Why doesn't this Golang code to select among multiple time.After channels work?
See code below. The 'timeout' message is never issued. Why?
package main
import (
"fmt"
"time"
)
func main() {
count := 0
for {
select {
case <-time.After(1 * time.Second):
count++
fmt.Printf("tick %d\n", count)
if count >= 5 {
fmt.Printf("ugh\n")
return
}
case <-time.After(3 * time.Second):
fmt.Printf("timeout\n")
return
}
}
}
Run it on Playground: http://play.golang.org/p/1gku-CWVAh
Output:
tick 1
tick 2
tick 3
tick 4
tick 5
ugh
答案1
得分: 15
因为time.After
是一个函数,所以在每次迭代中它都会返回一个新的通道。如果你希望这个通道在所有迭代中保持相同,你应该在循环之前保存它:
timeout := time.After(3 * time.Second)
for {
select {
//...
case <-timeout:
fmt.Printf("超时\n")
return
}
}
Playground: http://play.golang.org/p/muWLgTxpNf.
英文:
Because time.After
is a function, so on every iteration it returns a new channel. If you want this channel to be the same for all iterations, you should save it before the loop:
timeout := time.After(3 * time.Second)
for {
select {
//...
case <-timeout:
fmt.Printf("timeout\n")
return
}
}
Playground: http://play.golang.org/p/muWLgTxpNf.
答案2
得分: 5
即使<a href="https://stackoverflow.com/users/1892060/ainar-g">@Ainar-G</a>已经提供了答案,另一种可能性是使用time.Tick(1e9)
来生成每秒钟的时间间隔,然后在指定的时间段后监听timeAfter
通道。
package main
import (
"fmt"
"time"
)
func main() {
count := 0
timeTick := time.Tick(1 * time.Second)
timeAfter := time.After(5 * time.Second)
for {
select {
case <-timeTick:
count++
fmt.Printf("tick %d\n", count)
if count >= 5 {
fmt.Printf("ugh\n")
return
}
case <-timeAfter:
fmt.Printf("timeout\n")
return
}
}
}
英文:
Even <a href="https://stackoverflow.com/users/1892060/ainar-g">@Ainar-G</a> has already provided the answer, another possibility is to use time.Tick(1e9)
to generate a time tick on every second and then listen for timeAfter
channel after the specified period.
package main
import (
"fmt"
"time"
)
func main() {
count := 0
timeTick := time.Tick(1 * time.Second)
timeAfter := time.After(5 * time.Second)
for {
select {
case <-timeTick:
count++
fmt.Printf("tick %d\n", count)
if count >= 5 {
fmt.Printf("ugh\n")
return
}
case <-timeAfter:
fmt.Printf("timeout\n")
return
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论