Go 1 與 Go 程式的未來
引言
Go 版本 1(簡稱 Go 1)的釋出,是這門語言發展的一個主要里程碑。Go 1 是一個穩定的平臺,可用於發展以 Go 編寫的程式和專案。
Go 1 定義了兩件事:首先,是語言的規範;其次,是一組核心 API 的規範,即 Go 庫的“標準包”。Go 1 版本包含了它們的實現,形式為兩個編譯器套件(gc 和 gccgo)以及核心庫本身。
我們期望,為 Go 1 規範編寫的程式,在該規範的生命週期內,將能夠持續正確地編譯和執行,無需更改。在未來的某個不確定時間點,可能會出現 Go 2 規範,但在那之前,即使 Go 1 的未來“點”版本(Go 1.1, Go 1.2 等)釋出,今天能執行的 Go 程式也應能繼續執行。
相容性是在原始碼層面。已編譯包的二進位制相容性在各版本之間不作保證。在一個點版本釋出後,Go 原始碼將需要重新編譯以連結到新版本。
API 可能會增長,增加新的包和功能,但不會以破壞現有 Go 1 程式碼的方式進行。
預期
雖然我們預期絕大多數程式能隨時間推移保持這種相容性,但無法保證未來的任何更改都不會破壞任何程式。本文旨在設定對未來 Go 1 軟體相容性的預期。一個今天能編譯和執行的程式,在未來的點版本釋出後可能會失敗,有多種原因。這些情況都很少見,但值得記錄。
- 安全。規範或實現中可能會發現安全問題,其解決方案需要破壞相容性。我們保留解決此類安全問題的權利。
- 未指明行為。Go 規範試圖明確語言的大部分屬性,但有些方面是未定義的。依賴此類未指明行為的程式可能會在未來版本中被破壞。
- 規範錯誤。如果需要解決規範中的不一致或不完整之處,解決問題可能會影響現有程式的含義或合法性。我們保留解決此類問題的權利,包括更新實現。除安全問題外,不會對規範進行不相容的更改。
- Bug。如果編譯器或庫存在違反規範的 bug,依賴於該錯誤行為的程式在 bug 被修復後可能會被破壞。我們保留修復此類 bug 的權利。
- 結構體字面量。為了在之後的點版本中新增新功能,可能需要向 API 中匯出的結構體新增欄位。使用未指定鍵的結構體字面量(如 `pkg.T{3, "x"}`)建立這些型別值的程式碼,在此類更改後將無法編譯。然而,使用指定鍵的字面量(`pkg.T{A: 3, B: "x"}`)的程式碼在此類更改後將繼續編譯。我們將以允許指定鍵的結構體字面量保持相容的方式更新此類資料結構,儘管未指定鍵的字面量可能無法編譯。(還有涉及巢狀資料結構或介面的更復雜情況,但它們有相同的解決方法。)因此,我們建議,型別在單獨包中定義的複合字面量應使用指定鍵的表示法。
- 方法。與結構體欄位一樣,可能需要向非介面型別新增方法。在某些情況下,例如當該型別與另一型別一起嵌入到一個結構體中時,新方法的新增可能會透過與另一個嵌入型別的現有方法產生衝突而破壞該結構體。我們無法防範這種罕見情況,並且不保證在這種情況下能相容。
- 點匯入。如果一個程式使用 `import . "path"` 匯入一個標準包,未來版本中在該匯入包中定義的額外名稱可能會與程式中定義的其他名稱衝突。我們不建議在測試之外使用 `import .`,使用它可能會導致程式在未來版本中無法編譯。
- 使用 `unsafe` 包。匯入 `unsafe` 包的程式可能依賴於 Go 實現的內部屬性。我們保留對實現進行可能破壞此類程式的更改的權利。
當然,對於所有這些可能性,一旦出現,我們都會在可行的情況下努力更新規範、編譯器或庫,而不影響現有程式碼。
這些同樣的考慮也適用於連續的點版本。例如,在 Go 1.2 下執行的程式碼應與 Go 1.2.1、Go 1.3、Go 1.4 等相容,但未必與 Go 1.1 相容,因為它可能使用了僅在 Go 1.2 中新增的功能。
在版本之間新增的功能,可在原始碼倉庫中獲得但尚未成為帶編號的二進位制版本的一部分,正處於積極開發中。對於使用此類功能的軟體,在它們被髮布之前,不作任何相容性承諾。
最後,雖然這不是一個正確性問題,但程式的效能可能會受到其所依賴的編譯器或庫實現變化的影響。無法保證一個給定程式在不同版本之間的效能。
儘管這些預期適用於 Go 1 本身,我們希望在開發基於 Go 1 的外部軟體時也能有類似的考慮。
子倉庫
主 go 樹的子倉庫中的程式碼,例如 golang.org/x/net,可能會在更寬鬆的相容性要求下開發。然而,這些子倉庫將被適當地打上標籤,以識別與 Go 1 點版本相容的版本。
作業系統
無法保證與作業系統介面的長期相容性,因為這些介面由外部方更改。因此,`syscall` 包不在本文所作保證的範圍之內。自 Go 1.4 版本起,`syscall` 包已被凍結。系統呼叫介面的任何演進都必須在其他地方得到支援,例如在 go.sys 子倉庫中。有關詳情和背景,請參閱此文件。
工具
最後,Go 工具鏈(編譯器、連結器、構建工具等)正在積極開發中,其行為可能會改變。這意味著,例如,依賴於工具位置和屬性的指令碼可能會因點版本釋出而被破壞。
除了這些注意事項,我們相信 Go 1 將為 Go 及其生態系統的發展奠定堅實的基礎。