还能这样玩?Go 将会增强 Go1 向前兼容性

开发 前端
在今天这篇文章中,我们介绍了 Go1 兼容性增强中的 “向前兼容” 部分,其中要点是:加大对 go.mod 文件中的 go 行和 toolchain 行和工具链 GOTOOLCHAIN 相关的应用。

大家好,我是煎鱼。新春快乐呀!

年前我们在《醒醒吧,未来不会有 Go2 了!》文章中讨论了 Go2 的未来,明确了未来是以 Go1.x.y 为主的 Go1 时代。

为了实现这个北极星目标,Go 团队采取的策略分别是:增强 Go1 向后兼容(在前文已分享)和 Go1 向前兼容(本文重点内容)。

本次要提到的 “向前兼容”,指的是旧版本的 Go 编译新的 Go 代码。这个方向比较少被谈论,甚至特意设计。

让我有种,还能这样搞的感觉?

Go1 向前兼容

Go 团队的大当家 Russ Cox,针对如下几个方面做了新设计和调整,输出了《Proposal: Extended forwards compatibility in Go[1]》,已经得到讨论,很大概率落地,把版本号停留在 Go1.x.y。

将会涉及的部分重点如下:

  1. 新增 GOTOOLCHAIN 环境变量的设置。
  2. 改变在工作模块(work module)中解释 go 行的方式,增加了新的工具链(toolchain)行以此实现声明。此对应的是 go.mod 文件的 go 行和toolchain 行。
  3. 对 go get 等命令进行联动修改,允许对 GOTOOLCHAIN 和工作模块的 go 版本进行修改。

增强工作模块的 go.mod 和 toolchain

声明 Go 版本号

我们会在 go module 生成时,在 Go 工程下生成一个 go.mod 文件。其中会包含一个 go 行,将会声明该模块应该应用的 go 版本语义是什么版本。

如下图,声明的是 go1.13:

图片

go.mod 文件中的 go 版本声明

在该提案落地后,本地安装的 Go 工具链如果比 go 行所声明的 go 版本新时,它将会直接提供所要求的旧语义,而不会重新下载和调用一个旧版本的 Go 工具链。

但如果 go 行声明了一个较新的 Go 工具链,那么本地安装的 Go 工具链就会下载并运行较新的工具链来满足其需求。

以下是一个例子。

在例子中,我们正在运行的版本是 go1.30。但在模块中,有一个 go.mod 声明了 go 版本:

go 1.30.1
  • 1.

Go1.30 会下载并调用 go1.30.1 来完成命令,因为模块中要求的 go 版本比本地安装的更高。

但如果 go.mod 文件中声明的是:

go 1.20rc1
  • 1.

Go1.30 将自己提供 go1.20rc1 语义,而不是运行 go1.20 rc1 工具链。因为本地安装的版本更新,可以通过 GODEBUG 来满足旧语义的诉求。

声明 Go 工具链版本号

可能会有同学想要运行更新版本的 Go 工具链,但 Go 语义上还是使用旧版本。

为了满足这点诉求,go.mod 文件也会支持 toolchain 行的设置,以此来支持新版本的工具链的使用。

如果 go.mod 文件中设置了 toolchain 行,将指定使用的工具链版本,go 行只指定语言语义的 Go 版本。

go.mod 文件如下:

go 1.18
toolchain go1.20rc1
  • 1.
  • 2.

作用是将为这个模块选择 go1.18 的语义,使用 go1.20rc1 的工具链来构建应用。

增强 Go 工具链 GOTOOLCHAIN

将会在 Go 工具链新增 GOTOOLCHAIN 环境变量的设置和使用可以使用 go env -w 设置。也可以在 go test 时做如下调整:

GOTOOLCHAIN=go1.17.2 go test
  • 1.

go build 编译时可以:

GOTOOLCHAIN=go1.18rc1 go build -o myprog.exe
  • 1.

可能会有同学疑惑 GOTOOLCHAIN 的默认值哪来,有哪些值?

  • 设置GOTOOLCHAIN=local:使用本地安装的 Go 工具链,不会下载不同版本的工具链。这是现在的的默认行为。
  • 设置GOTOOLCHAIN=auto:使用工作模块的 go.mod 中声明的 go 版本(当它比本地安装的 Go 工具链要新时)。

GOTOOLCHAIN 环境变量的默认值取决于 Go 工具链。标准 Go 发行版默认为 GOTOOLCHAIN=auto,也就是将控制权交给 go.mod 文件。这是在实施这个提案后 99% 会看到的默认行为。

Go 工具链的一揽子东西里也比较多,例如:go get 命令,也会对 go.mod 文件中的 go 版本或 toolchain 行进行变更,以配合使用。

总结

在今天这篇文章中,我们介绍了 Go1 兼容性增强中的 “向前兼容” 部分,其中要点是:加大对 go.mod 文件中的 go 行和 toolchain 行和工具链 GOTOOLCHAIN 相关的应用。

核心目的是为了将 go 语法语义和 go 工具链的版本声明公开出来,达到隔离使用。再配合 “向后兼容” 中的 GODEBUG 的使用,让 Go 语言做兼容性时有更多更大的使用空间来实现机制上的保障。

这么一来,Go 语言在这一块会变得异常复杂,理解成本也会变高。希望大家后续在这块也不要再踩坑了。

责任编辑:武晓燕 来源: 脑子进煎鱼了
相关推荐

2023-01-27 19:11:40

GoGo1兼容性

2022-12-14 09:13:37

Go程序规范

2022-12-09 08:52:51

Go匿名接口

2021-02-21 09:09:24

GoGOPATH代码

2020-11-16 13:38:31

PostMessage

2021-09-05 07:55:37

前端Emoji 表情

2021-07-28 06:10:47

拖拽设计器 transmat

2023-08-29 08:55:45

Go1Go核心

2025-03-06 08:54:24

泛型类型MapGo1

2024-05-10 08:47:22

标准库v2Go

2025-01-14 11:01:38

2024-08-02 08:38:20

Controller接口地址

2010-08-19 09:59:03

Office 2011兼容性

2023-04-17 19:43:54

兼容性测试软件测试

2009-03-07 09:49:07

Windows 7兼容性

2024-12-03 09:45:34

2018-12-12 11:30:54

JavaString字符串

2021-04-09 08:23:30

Css前端加载动画

2024-01-30 09:21:29

CSS文字效果文字装饰

2011-08-16 15:17:44

IOS SDK
点赞
收藏

51CTO技术栈公众号