Go 1.20新变化!第一部分:语言特性

又到了 Go 发布新版本的时刻了!

2022 年第一季度的 Go 1.18 是一个主版本,它在语言中增加了期待已久的泛型,同时还有许多微小功能更新[1]与优化[2]。2022 年第三季度的 Go 1.19 是一个比较低调[3]的版本。

现在是 2023 年,Go 1.20 RC 版本[4]已经发布,而正式版本也即将到来,Go 团队已经发布了版本说明草案[5]。

在我看来,Go 1.20 的影响介于 1.18 和 1.19 之间,比 1.19 有更多的功能更新并解决了一些长期存在的问题,但没有达到 1.18 中为语言增加泛型这样的重磅规模。

尽管如此,我还是要把我对“Go 1.20 的新变化”的看法分成系列三篇博文。

首先,我写了 Go 1.20 中的语言变化(如下),在下一篇文章中,我将写标准库的重要变化,最后一篇将讲解 Go 1.20 中我最喜欢的对标准库的小改动。


那么,让我们来看看语言方面的变化。首先,对泛型的规则做了一个小小的修改。有了 Go 泛型,你可以通过一个函数获取任何map的键:

func keys[K comparable, V any](m map[K]V) []K {
    var keys []K
    for k := range m {
        keys = append(keys, k)
    }
    return keys
}
···

在这段代码中,K comparable, V any 为“类型约束”。这意味着 K 可以是任何 comparable 的类型,而 V 则没有类型限制。comparable 类型为数字、布尔、字符串和由 comparable 元素组成的固定大小的复合类型等。因此,K 为 int,V 为一个 bytes 切片是合法的,但 K 是一个 bytes 切片是非法的。

我说过上面的代码会给你任何 map 的键,但在 Go 1.18 和 1.19 中,这并不是完全正确的。如果你试图把它用在一个键值为接口类型的 map 上,它将不会被编译。

m := make(map[any]any) // ok
keys(m)
// 编译器错误(Go 1.19):any 没有实现 comparable
···

这个问题归结为围绕 K comparable 含义的解读。要作为 map 键使用,类型必须被 Go 编译器认为是 comparable 的。例如,这是无效的:

m := make(map[func()]any)
// 编译器错误:无效的 map 键类型 func()
···

然而,你可以通过使用接口来得到一个运行时错误而不是编译器错误:

m := make(map[any]any) // 正确
k := func() {}
m[k] = 1 // panic:运行时错误:哈希值为不可哈希的类型 func()
<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值