Go 1.18正式发布!支持泛型、性能优化...
文 | 罗奇奇
出品 | OSC开源社区(ID:oschina2013)
泛型
函数和类型声明的语法,现在接受类型参数。
参数化函数和类型可以通过在方括号中列出类型参数来实例化。
新标记
~
已添加到操作符和标点符号中。接口类型的语法现在允许嵌入任意类型(不仅仅是接口的类型名称)以及 union 和 ~T 类型元素。,这样的接口只能用作类型约束。
新的 预声明标识符
any
是空接口的别名,可以用来代替interface{}
.新的 预声明标识符
comparable
是一个接口,表示可以使用==
或者!=
比较的所有类型的集合,它只能用作(或嵌入)类型约束。
golang.org/x/exp/constraints
:对通用代码有用的约束,例如constraints.Ordered
.golang.org/x/exp/slices
:对任何元素类型的切片进行操作的通用函数集合。golang.org/x/exp/maps
:对任何键或元素类型的映射进行操作的通用函数集合。
Go 编译器无法处理泛型函数或方法中的类型声明,计划在 Go 1.19 中取消这个限制。
Go 编译器不接受具有预声明函数 real、imag 和 complex 的参数类型的参数,计划在 Go 1.19 中取消这个限制。
如果 m 由 P 的约束接口显式声明,Go 编译器仅支持在类型参数类型 P 的值 x 上调用方法 m。类似地,方法值 x.m 和方法表达式 P.m 也仅在 m 由 P 显式声明时才受支持,即使 m 可能在 P 的方法集中,因为 P 中的所有类型都实现了 m,计划在 Go 1.19 中取消这个限制。
Go 编译器不支持访问结构字段 x.f,其中 x 是类型参数类型,即使类型参数的类型集中的所有类型都具有字段 f,计划在 Go 1.19 中取消这个限制。
不允许将类型参数或指向类型参数的指针作为结构类型中的未命名字段嵌入,同样地,也不允许在接口类型中嵌入类型参数。
具有多个 term 的 union 元素可能不包含具有非空方法集的接口类型。
可能会有一些使用泛型的代码可以在 1.18 版本中使用,但在以后的版本中会中断。
我们不计划或期望做出任何此类更改,但是,由于我们今天无法预见的原因,可能需要在未来版本中破坏 1.18 的程序。
我们鼓励在有意义的地方使用泛型,但在生产环境中部署泛型代码时,请谨慎行事。
模糊测试
Go 1.18 包括 fuzzing(模糊测试) 的实现,如 fuzzing 提案所述,详情请参阅 fuzzing 教程(https://go.dev/doc/tutorial/fuzz)以开始使用。
注意,模糊测试会消耗大量内存,并且可能会影响机器运行时的性能。
另请注意,模糊引擎在运行时会将扩展测试覆盖率的值写入模糊缓存目录
$GOCACHE/fuzz
。目前对可以写入模糊缓存的文件数量或总字节数没有限制,因此可能会占用大量存储空间(可能为 GB 级别)。
编译器
现在编译器可以内联包含范围循环或标记为循环的函数。
编译器的类型检查器被完全替换以支持泛型,一些错误消息可能使用与以前不同的措辞(提供更多详细信息,或以更有用的方式表述)。
由于与支持泛型相关的编译器的更改,Go 1.18 的编译速度可能比 Go 1.17 的编译速度慢大约 15%,代码的执行时间不受影响,目前计划在 Go 1.19 中提高编译器的速度。
Bug fixes
Go 1.18 编译器可以正确地报告在函数文本中设置但从未使用过的变量的错误(已声明但未使用),解决了一个老问题 issue #8560 (https://golang.org/issue/8560)。
Go 1.18 编译器现在在将如 '1' << 32 之类的符文常量表达式作为参数传递给预声明函数 print 和 println 时会报告溢出。
Ports
AMD64
GOAMD64
环境变量,它在编译时选择 AMD64 架构的最低目标版本,允许的值为v1
、 v2
、v3
或v4
,默认是v1
。RISC-V
Linux
Windows
iOS
FreeBSD
性能提升
https ://go.dev/dl/
https ://go.dev/doc/go1.18
https ://go.dev/blog/go1.18
https ://go.dev/blog/tutorials-go1.18
END