这个问题有点坑,读到最后才会知道!
time.After 每次调用都会返回一个新的 channel,把你的 for + select 简单拆解下,加个临时变量或许比较好理解,比如变成下面这样。
timerC 每次都是重新创建的,什么意思呢?简单说来,当 select 成功监听 ch 并进入它的处理分支,下次循环 timerC 会重新创建。timerC 重新创建了,时间肯定就重置了。
是不是觉得这种方式挺适合超时处理,timerC 只对一个 select 有效,下次处理时重新计算超时时间,每个操作的处理都是独立的。
补充:
感谢评论区的 root 提醒,如果按上面这种方式处理超时可能会出现内存泄露。root 提到了这篇文章,如下:
也就是说如果定时器没有到达定时时间,gc 就不会启动垃圾回收。标准库文档中有说明:
The underlying Timer is not recovered by the garbage collector until the timer fires
文中提到了可以通过创建 timer 配合 reset 实现超时,可解决这个问题。如下:
真是防不胜防!
欢迎关注我的专栏,Golang 之旅。见证我的 Golang 学习历程。