新聞中心
大家好,我是煎魚。新春快樂呀!

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


咨詢
建站咨詢
