还能这样玩?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

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

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

go 1.20rc1

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

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

增强 Go 工具链 GOTOOLCHAIN

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

GOTOOLCHAIN=go1.17.2 go test

go build 编译时可以:

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

可能会有同学疑惑 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

2023-08-29 08:55:45

Go1Go核心

2021-07-28 06:10:47

拖拽设计器 transmat

2021-09-05 07:55:37

前端Emoji 表情

2024-05-10 08:47:22

标准库v2Go

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兼容性

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

2021-12-27 16:22:19

鸿蒙HarmonyOS应用

2023-03-24 07:31:58

Oracle兼容性产品

2010-03-05 17:09:18

点赞
收藏

51CTO技术栈公众号