英文:
Unexpected behavior on Ticker interval change
问题
我天真地编写了一段代码来改变time.Ticker
的间隔,令人恼火的是,它居然起作用:
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(5 * time.Second)
switcher := time.NewTimer(16 * time.Second)
for {
select {
case <-ticker.C:
fmt.Println("ticker " + time.Now().Format("15:04:05"))
case <-switcher.C:
fmt.Println("switching")
ticker = time.NewTicker(1 * time.Second)
}
}
}
它实现了我想要的效果,即在16秒后将ticker
的频率切换为1秒。然而,重新阅读代码后,我本以为在16秒后会创建一个新的Ticker
对象,而select
语句会持有旧对象的通道引用,阻止它被垃圾回收,并继续每隔五秒触发。
那么为什么这段代码会改变ticker
的频率呢?
英文:
I naively wrote a piece of code to change the interval of a time.Ticker
, and upon reviewing it I am irritated that it works:
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(5 * time.Second)
switcher := time.NewTimer(16 * time.Second)
for {
select {
case <-ticker.C:
fmt.Println("ticker " + time.Now().Format("15:04:05"))
case <-switcher.C:
fmt.Println("switching")
ticker = time.NewTicker(1 * time.Second)
}
}
}
> $ go run main.go
> ticker 02:19:03
> ticker 02:19:08
> ticker 02:19:13
> switching
> ticker 02:19:15
> ticker 02:19:16
> ticker 02:19:17
It does what I want, namely switch the frequency of the ticker
Ticker to one second after 16 seconds. However, reading it again I would expect that after 16 seconds, a new Ticker object is created, while the select
statement holds a reference to the channel of the old one, preventing it from garbage collection and keep on ticking every five seconds.
So why does this code change the ticker's frequency?
答案1
得分: 5
一个select
语句不是一个闭包,也不会“持有”任何引用。
你只是简单地替换了ticker
的值,正如你所看到的,间隔相应地改变。
英文:
A select
statement isn't a closure and doesn't "hold" a reference to anything.
You're simply replacing the value of ticker
, and as you can see, the interval changes accordingly.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论