Jtti1.14

Go 1.18正式发布!支持泛型、性能优化...

Go 1.18正式发布!支持泛型、性能优化...

距离 Go1.17发布七个月后,Go1.18正式发布了!Go1.18是一个包含大量新功能的版本,包括对语言本身做了有史以来最大的改变(泛型)、工具链的实现、运行时和库的更改,还改善了性能。

与往常一样,该版本保持了 Go1的兼容性承诺:几乎所有 Go 程序都能像以前一样继续编译和运行。下面来看一下新版本的一些重大特性:

泛型

以下是关于 Go1.18泛型的最明显变化的列表,如需更全面的概述请参阅泛型提案,更详细信息请参阅语言规范。

泛型提案:https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md

语言规范:https://tip.golang.org/ref/spec

  • 函数和类型声明的语法,现在接受类型参数。
  • 参数化函数和类型可以通过在方括号中列出类型参数来实例化。
  • 新标记~已添加到操作符和标点符号中。
  • 接口类型的语法现在允许嵌入任意类型(不仅仅是接口的类型名称)以及 union 和 ~T 类型元素。,这样的接口只能用作类型约束。
  • 新的预声明标识符any是空接口的别名,可以用来代替interface{}.
  • 新的预声明标识符comparable是一个接口,表示可以使用==或者!=比较的所有类型的集合,它只能用作(或嵌入)类型约束。

有三个使用泛型的实验包可能有用,这些包在 x/exp 存储库中;但它们的 API 不在 Go1兼容性承诺的保证范围内:

  • golang.org/x/exp/constraints:对通用代码有用的约束,例如constraints.Ordered.
  • golang.org/x/exp/slices:对任何元素类型的切片进行操作的通用函数集合。
  • golang.org/x/exp/maps:对任何键或元素类型的映射进行操作的通用函数集合。

当前的泛型实现具有以下已知限制:

  • Go 编译器无法处理泛型函数或方法中的类型声明,计划在 Go1.19中取消这个限制。
  • Go 编译器不接受具有预声明函数 real、imag 和 complex 的参数类型的参数,计划在 Go1.19中取消这个限制。
  • 如果 m 由 P 的约束接口显式声明,Go 编译器仅支持在类型参数类型 P 的值 x 上调用方法 m。类似地,方法值 x.m 和方法表达式 P.m 也仅在 m 由 P 显式声明时才受支持,即使 m 可能在 P 的方法集中,因为 P 中的所有类型都实现了 m,计划在 Go1.19中取消这个限制。
  • Go 编译器不支持访问结构字段 x.f,其中 x 是类型参数类型,即使类型参数的类型集中的所有类型都具有字段 f,计划在 Go1.19中取消这个限制。
  • 不允许将类型参数或指向类型参数的指针作为结构类型中的未命名字段嵌入,同样地,也不允许在接口类型中嵌入类型参数。
  • 具有多个term的 union 元素可能不包含具有非空方法集的接口类型。

泛型代表 Go 生态系统的巨大变化,虽然官方更新了几个支持泛型的核心工具,但还有很多工作要做。剩余的工具、文档和库需要一些时间才能赶上这些语言变化。此外,官方公告中还有这么一段话:

  • 可能会有一些使用泛型的代码可以在1.18版本中使用,但在以后的版本中会中断。
  • 我们不计划或期望做出任何此类更改,但是,由于我们今天无法预见的原因,可能需要在未来版本中破坏1.18的程序。
  • 我们鼓励在有意义的地方使用泛型,但在生产环境中部署泛型代码时,请谨慎行事。

(虽然泛型是搞出来了,但很可能有 Bug,不建议在生产中使用)

模糊测试

  • Go1.18包括 fuzzing(模糊测试) 的实现,如fuzzing 提案所述,详情请参阅fuzzing 教程(https://go.dev/doc/tutorial/fuzz)以开始使用。
  • 注意,模糊测试会消耗大量内存,并且可能会影响机器运行时的性能。
  • 另请注意,模糊引擎在运行时会将扩展测试覆盖率的值写入模糊缓存目录$GOCACHE/fuzz。目前对可以写入模糊缓存的文件数量或总字节数没有限制,因此可能会占用大量存储空间(可能为 GB 级别)。

编译器

  • 现在编译器可以内联包含范围循环或标记为循环的函数。
  • 编译器的类型检查器被完全替换以支持泛型,一些错误消息可能使用与以前不同的措辞(提供更多详细信息,或以更有用的方式表述)。
  • 由于与支持泛型相关的编译器的更改,Go1.18的编译速度可能比 Go1.17的编译速度慢大约15%,代码的执行时间不受影响,目前计划在 Go1.19中提高编译器的速度。

Bug fixes

  • Go1.18编译器可以正确地报告在函数文本中设置但从未使用过的变量的错误(已声明但未使用),解决了一个老问题issue#8560(https://golang.org/issue/8560)。
  • Go1.18编译器现在在将如 '1' <<32之类的符文常量表达式作为参数传递给预声明函数 print 和 println 时会报告溢出。

Ports

AMD64

Go1.18引入了新的GOAMD64环境变量,它在编译时选择 AMD64架构的最低目标版本,允许的值为v1v2v3v4,默认是v1

RISC-V

Linux 上的64位 RISC-V 架构(linux/riscv64端口)现在支持 c-archive 和 c-shared 构建模式。

Linux

Go1.18需要 Linux 内核版本2.6.32或更高版本。

Windows

windows/arm 和 windows/arm64端在支持非合作抢占,有希望解决在调用 Win32函数时遇到的一些细微的 bug,这些bug在很长一段时间内会阻塞。

iOS

在 iOS(ios/arm64端口)和在基于 AMD64的 macOS(ios/amd64端口)上运行的 iOS 模拟器上,Go1.18现在需要 iOS12或更高版本;已停止支持以前的版本。

FreeBSD

Go1.18是支持 FreeBSD11.x 的最后一个版本,Go1.19需要 FreeBSD12.2+ 或 FreeBSD13.0+。

性能提升

由于 Go1.17中寄存器 ABI 调用约定扩展到了RM64/ Apple M1/ PowerPC64架构,因此 Go1.18对这几个架构包含了高达20% 的 CPU 性能提升。

该 Go1.18版本还包含其他大量更新项,完整更新列表请在发行公告(https://tip.golang.org/doc/go1.18)中查看。

Go1.18相关链接

  • https ://go.dev/dl/
  • https ://go.dev/doc/go1.18
  • https ://go.dev/blog/go1.18
  • https ://go.dev/blog/tutorials-go1.18
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
广告位招租919838898
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索