還能這樣玩?Go 將會增強 Go1 向前兼容性
大家好,我是煎魚。新春快樂呀!
年前我們在《醒醒吧,未來不會有 Go2 了!》文章中討論了 Go2 的未來,明確了未來是以 Go1.x.y 為主的 Go1 時代。
為了實現(xiàn)這個北極星目標,Go 團隊采取的策略分別是:增強 Go1 向后兼容(在前文已分享)和 Go1 向前兼容(本文重點內(nèi)容)。
本次要提到的 “向前兼容”,指的是舊版本的 Go 編譯新的 Go 代碼。這個方向比較少被談論,甚至特意設計。
讓我有種,還能這樣搞的感覺?
Go1 向前兼容
Go 團隊的大當家 Russ Cox,針對如下幾個方面做了新設計和調(diào)整,輸出了《Proposal: Extended forwards compatibility in Go[1]》,已經(jīng)得到討論,很大概率落地,把版本號停留在 Go1.x.y。
將會涉及的部分重點如下:
- 新增 GOTOOLCHAIN 環(huán)境變量的設置。
- 改變在工作模塊(work module)中解釋 go 行的方式,增加了新的工具鏈(toolchain)行以此實現(xiàn)聲明。此對應的是 go.mod 文件的 go 行和toolchain 行。
- 對 go get 等命令進行聯(lián)動修改,允許對 GOTOOLCHAIN 和工作模塊的 go 版本進行修改。
增強工作模塊的 go.mod 和 toolchain
聲明 Go 版本號
我們會在 go module 生成時,在 Go 工程下生成一個 go.mod 文件。其中會包含一個 go 行,將會聲明該模塊應該應用的 go 版本語義是什么版本。
如下圖,聲明的是 go1.13:
go.mod 文件中的 go 版本聲明
在該提案落地后,本地安裝的 Go 工具鏈如果比 go 行所聲明的 go 版本新時,它將會直接提供所要求的舊語義,而不會重新下載和調(diào)用一個舊版本的 Go 工具鏈。
但如果 go 行聲明了一個較新的 Go 工具鏈,那么本地安裝的 Go 工具鏈就會下載并運行較新的工具鏈來滿足其需求。
以下是一個例子。
在例子中,我們正在運行的版本是 go1.30。但在模塊中,有一個 go.mod 聲明了 go 版本:
Go1.30 會下載并調(diào)用 go1.30.1 來完成命令,因為模塊中要求的 go 版本比本地安裝的更高。
但如果 go.mod 文件中聲明的是:
Go1.30 將自己提供 go1.20rc1 語義,而不是運行 go1.20 rc1 工具鏈。因為本地安裝的版本更新,可以通過 GODEBUG 來滿足舊語義的訴求。
聲明 Go 工具鏈版本號
可能會有同學想要運行更新版本的 Go 工具鏈,但 Go 語義上還是使用舊版本。
為了滿足這點訴求,go.mod 文件也會支持 toolchain 行的設置,以此來支持新版本的工具鏈的使用。
如果 go.mod 文件中設置了 toolchain 行,將指定使用的工具鏈版本,go 行只指定語言語義的 Go 版本。
go.mod 文件如下:
作用是將為這個模塊選擇 go1.18 的語義,使用 go1.20rc1 的工具鏈來構建應用。
增強 Go 工具鏈 GOTOOLCHAIN
將會在 Go 工具鏈新增 GOTOOLCHAIN 環(huán)境變量的設置和使用可以使用 go env -w 設置。也可以在 go test 時做如下調(diào)整:
go build 編譯時可以:
可能會有同學疑惑 GOTOOLCHAIN 的默認值哪來,有哪些值?
- 設置GOTOOLCHAIN=local:使用本地安裝的 Go 工具鏈,不會下載不同版本的工具鏈。這是現(xiàn)在的的默認行為。
- 設置GOTOOLCHAIN=auto:使用工作模塊的 go.mod 中聲明的 go 版本(當它比本地安裝的 Go 工具鏈要新時)。
GOTOOLCHAIN 環(huán)境變量的默認值取決于 Go 工具鏈。標準 Go 發(fā)行版默認為 GOTOOLCHAIN=auto,也就是將控制權交給 go.mod 文件。這是在實施這個提案后 99% 會看到的默認行為。
Go 工具鏈的一攬子東西里也比較多,例如:go get 命令,也會對 go.mod 文件中的 go 版本或 toolchain 行進行變更,以配合使用。
總結
在今天這篇文章中,我們介紹了 Go1 兼容性增強中的 “向前兼容” 部分,其中要點是:加大對 go.mod 文件中的 go 行和 toolchain 行和工具鏈 GOTOOLCHAIN 相關的應用。
核心目的是為了將 go 語法語義和 go 工具鏈的版本聲明公開出來,達到隔離使用。再配合 “向后兼容” 中的 GODEBUG 的使用,讓 Go 語言做兼容性時有更多更大的使用空間來實現(xiàn)機制上的保障。
這么一來,Go 語言在這一塊會變得異常復雜,理解成本也會變高。希望大家后續(xù)在這塊也不要再踩坑了。