一些不错的性能改进
我们还没有仔细研究过这些,但它们看起来不错:
- 整体性能提升 2-3%,主要得益于“基于 Swiss Tables 的新型内置映射实现、更高效的小对象内存分配以及新的运行时内部互斥实现” ;
- 两个新的 cgo 指令(noescape和nocallback)2在某些情况下可能会减少从 Go 调用 C 代码的开销
弱指针实现
Go 1.24 可能是我最喜欢的,它包含一个弱指针的实现。
弱指针是对对象的引用,它不会阻止垃圾收集器收集它。实际上,实现只是一个weak.Pointer[T](很好地反映了atomic.Pointer[T]),它有一个Value() *T方法。
这个新的弱指针概念——除了Go 1.23 中引入的unique包之外——有潜力为现实世界的 Go 应用程序的内存使用率带来良好的改善。
后量子密码学
此版本在软件包中引入了对后量子加密的支持crypto/tls。标准库现在包括 ML-KEM,“一种后量子密钥交换机制,以前称为 Kyber,在FIPS 203中指定” 3。
如果您还没有关注过,后量子密码学是指一组新的加密算法,这些算法被认为可以抵抗量子计算机的攻击,而量子计算机的攻击可能会破坏许多当前常用的加密算法。
加密客户端问候 (ECH)crypto/tls
加密客户端问候 (ECH) 及其前身加密 SNI (ESNI) 的目标是消除 TLS 中长期存在的隐私漏洞:虽然通过 TLS 进行的实际通信是私密的,但服务器的身份却不是。该协议使用通过 DNS 分发并使用 DNS-over-HTTPS 获得的公钥在客户端首次飞行期间进行加密。
encoding/json 通过omitzero新标签更好地支持零值
此版本修复了 encoding/json中的一个长期存在的问题:该omitempty标记仅支持部分类型,并且其定义与语言中零值的标准定义不一致。新omitzero标记现在允许您指定如果字段的类型为零值,则应从序列化中省略该字段。
当前omitempty选项指定应从编码中省略该字段:
- 如果字段为空值,定义为 false、0、nil 指针、nil 接口值以及任何空数组、片段、映射或字符串
这一直很不好,因为 Golang 对零值“zero value”有不同的定义:
- 布尔类型为 false,数字类型为 0,字符串为"",指针、函数、接口、切片、通道和映射为 nil
如果比较这两个定义,您会注意到它们对于布尔值、所有数字类型、空数组和接口值是相同的。
但它们处理切片和映射的方式不同:
- omitempty将忽略任何空的切片或映射(即满足的切片或映射len(S) == 0),其中包括nil
- omitzero另一方面,只会省略切片或映射nil
omitzero-example.go
package main |
它生成:
{"omitempty": {"a": 0}} |
鉴于上述情况,我们建议omitempty继续用于 map和切片,但omitzero用于其他所有内容。
一项新tool指令go.mod
此版本向添加了一个新tool指令go.mod,允许您指定依赖项来构建工具,而不必诉诸于当前tools.go在项目中某处留空的惯例。
以前,依赖于stringer生成枚举字符串版本的工具的项目会在某处有一个包含以下内容的文件:
//go:build ignore |
你可以用go:generate如下命令来执行该工具:
//go:generate go run golang.org/x/tools/cmd/stringer -type Foo |
效果还不错。
但是现在在 Golang 1.24 中,您只需向go.mod 中添加一条tool指令即可,如下所示:
tool golang.org/x/tools/cmd/stringer |
只需运行以下命令即可使用此工具:
//go:generate go tool stringer -type Foo |
虽然不是什么大问题,但仍然可以大大改善生活质量。
testing包中的上下文支持
我一直想要这个。
*testing.T 和 *testing.B 类型现在有了 Context() context.Context 方法,可返回一个在调用Cleanup清理函数前被取消的上下文。
之前:
func TestFoo(t *testing.T) { |
使用下面替换上面:
func TestFoo(t *testing.T) { |
这是另一项很好的生活质量改善,以及使构建更清洁的测试变得更容易、更自然的潜力。
testing/synctest用于测试并发代码的新包
这仍处于实验阶段,但看起来非常有趣。这是一个新包,允许您定义 goroutine 的“气泡”,并在其中提供假时钟(即time.Now()返回不同的东西)。
这最终将使测试时间敏感的并发代码变得更容易,目前的最佳实践是提供一个返回当前时间的时钟函数(即 a func() time.Time),以便在测试期间注入假时间(例如,这是测试github.com/juju/ratelimit令牌桶实现的方式)。
还有很多其他的事情
Golang 团队在这个节日里确实给了我们一份很棒的礼物。还有很多值得一提的:
- 改进的终结器支持runtime.AddCleanup;
- 新的encoding.TextAppender和encoding.BinaryAppender接口,以及它们对整个标准库中的许多类型的支持;
- 使用新功能对随机文本字符串进行加密保护rand.Text;
- …还有更多。