Go 1.23引入的新Bug?其实只是文档没看仔细

上个月中旬,Go 1.23版本正式发布!这也是Russ Cox作为Go tech leader的最后一个发布版本,他本人在该版本中做出重要贡献,那就是解决了一直困扰Go团队的Timer/Ticker的GC回收问题,进而解决了Timer的Stop和Reset很难正确使用的问题。

7bfde931ddbcd2cee4f6122eca945aec.png

不过,就在昨天,一个叫tulir的gopher提出的issue(ttps://github.com/golang/go/issues/69186)差点让Russ Cox“晚节不保”:)。该issue提到,他写的一段使用了Timer的代码在Go 1.22中工作正常,但在Go 1.23中就无法工作了,具体现象是:在linux上,整个程序hang住不动了,而在macOS上,则直接引发panic异常退出:"fatal error: ts set in timer"。

随即,Go101老貘兄“补上一刀”,给出了一个更为简洁的示例:

package main

import "time"

func main() {
 illegalTimerCopy := *time.NewTimer(time.Second)
 illegalTimerCopy.Stop() // block for ever
}

我也实测了该示例,在我的macOS上,用go1.23.0运行,直接panic,即便使用GODEBUG=synctimerchan=1退回到Go 1.23以前的行为也不行。在centos 7.9(kernel 3.10)上跑,也发生了和issue一样的现象:hang住不动。

到这里,我也不得不认为:这是go 1.23 Timer引入的新bug!但真相果真如此吗?

几个小时后,Go大神Ian Lance Taylor现身说法了。他居然表示对Go 1.23之前的版本依然可以正确运行上述代码表示“惊讶”。

adb3090384bbb35a5348039840867390.png

之后,他表示从Go 1.4版本开始,Go标准库文档(#8776)就对Timer类型的使用做出了限制:"A Timer must be created with NewTimer or AfterFunc.",即Timer只能使用NewTimer和AfterFunc创建。

6e8c760db74af8977e4b6c527528c85f.png

而像上述代码中的对Timer实例的Copy的行为则是未定义的。

5284e3105be743522379c5df804fd152.png

目前Ian Lance Taylor将该issue改名为“proposal: cmd/vet: warn about copying a time.Timer value”,即建议在vet中增加warning,但他也不保证该proposal能被accept,因为要看后续是否会受到很多类似的问题报告。

盖棺定论了,原来是我们的文档看的还不够仔细:)。

不过,即便go vet不增加对Timer copy的warning,我也想建议官方修改一下Timer的doc描述,再直白一些,就像对sync.Mutex那样:A Mutex must not be copied after first use.

43a27381c51633818015dd7cc51b8739.png

在Timer文档中,也补充依据:A Timer must not be copied after being created.

你说呢?

- END -


推荐阅读:

6 个必须尝试的将代码转换为引人注目的图表的工具

Go 1.23新特性前瞻

Gopher的Rust第一课:第一个Rust程序

Go早期是如何在Google内部发展起来的

2024 Gopher Meetup 武汉站活动

go 中更加强大的 traces

「GoCN酷Go推荐」我用go写了魔兽世界登录器?

Go区不大,创造神话,科目三杀进来了

想要了解Go更多内容,欢迎扫描下方👇关注公众号,扫描 [实战群]二维码  ,即可进群和我们交流~


- 扫码即可加入实战群 -

0081b33d696be2e67d9d6717d765d1ef.png

3c614f9c447550dc030991bd0ce3ef39.png

分享、在看与点赞Go 1d3ae0b19417240bcecf81d3e4ae0fea.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值