Go 1.18 正式釋出了!支援泛型、效能優化...

2022-03-16 09:01:13

距離 Go 1.17 釋出七個月後,Go 1.18 正式釋出了! Go 1.18 是一個包含大量新功能的版本,包括對語言本身做了有史以來最大的改變(泛型)、工具鏈的實現、執行時和庫的更改,還改善了效能。

與往常一樣,該版本保持了 Go 1:幾乎所有 Go 程式都能像以前一樣繼續編譯和執行。下面來看一下新版本的一些重大特性:

泛型

以下是關於 Go 1.18 泛型的最明顯變化的列表,如需更全面的概述請參閱泛型,更詳細資訊請參閱。

  • 函數和型別宣告的語法,現在接受。
  • 引數化函數和型別可以通過在方括號中列出型別引數來範例化。
  • 新標記~已新增到中。
  • 介面型別的語法現在允許嵌入任意型別(不僅僅是介面的型別名稱)以及 union 和 ~T 型別元素。,這樣的介面只能用作型別約束。
  • 新的  any是空介面的別名,可以用來代替 interface{}.
  • 新的  comparable是一個介面,表示可以使用==或者 != 比較的所有型別的集合,它只能用作(或嵌入)型別約束。

有三個使用泛型的實驗包可能有用,這些包在 x/exp 儲存庫中;但它們的 API 不在 Go 1 相容性承諾的保證範圍內:

  • :對通用程式碼有用的約束,例如 .
  • :對任何元素型別的切片進行操作的通用函數集合。
  • :對任何鍵或元素型別的對映進行操作的通用函數集合。

當前的泛型實現具有以下已知限制:

  • Go 編譯器無法處理泛型函數或方法中的型別宣告,計劃在 Go 1.19 中取消這個限制。
  • Go 編譯器不接受具有預宣告函數 real、imag 和 complex 的引數型別的引數,計劃在 Go 1.19 中取消這個限制。
  • 如果 m 由 P 的約束介面顯式宣告,Go 編譯器僅支援在型別引數型別 P 的值 x 上呼叫方法 m。 類似地,方法值 x.m 和方法表示式 P.m 也僅在 m 由 P 顯式宣告時才受支援,即使 m 可能在 P 的方法集中,因為 P 中的所有型別都實現了 m,計劃在 Go 1.19 中取消這個限制。
  • Go 編譯器不支援存取結構欄位 x.f,其中 x 是型別引數型別,即使型別引數的型別集中的所有型別都具有欄位 f,計劃在 Go 1.19 中取消這個限制。
  • 不允許將型別引數或指向型別引數的指標作為結構型別中的未命名欄位嵌入,同樣地,也不允許在介面型別中嵌入型別引數。
  • 具有多個 term 的 union 元素可能不包含具有非空方法集的介面型別。

泛型代表 Go 生態系統的巨大變化,雖然官方更新了幾個支援泛型的核心工具,但還有很多工作要做。剩餘的工具、檔案和庫需要一些時間才能趕上這些語言變化。此外,官方公告中還有這麼一段話:

  • 可能會有一些使用泛型的程式碼可以在 1.18 版本中使用,但在以後的版本中會中斷。
  • 我們不計劃或期望做出任何此類更改,但是,由於我們今天無法預見的原因,可能需要在未來版本中破壞 1.18 的程式
  • 我們鼓勵在有意義的地方使用泛型,但在生產環境中部署泛型程式碼時,請謹慎行事。

(雖然泛型是搞出來了,但很可能有 Bug,不建議在生產中使用)

模糊測試

  • Go 1.18 包括 fuzzing(模糊測試) 的實現,如 所述,詳情請參閱 以開始使用。
  • 注意,模糊測試會消耗大量記憶體,並且可能會影響機器執行時的效能。
  • 另請注意,模糊引擎在執行時會將擴充套件測試覆蓋率的值寫入模糊快取目錄 $GOCACHE/fuzz。目前對可以寫入模糊快取的檔案數量或總位元組數沒有限制,因此可能會佔用大量儲存空間(可能為 GB 級別)。

編譯器

  • 現在編譯器可以內聯包含範圍迴圈或標記為迴圈的函數。
  • 編譯器的型別檢查器被完全替換以支援泛型,一些錯誤訊息可能使用與以前不同的措辭(提供更多詳細資訊,或以更有用的方式表述)。
  • 由於與支援泛型相關的編譯器的更改,Go 1.18 的編譯速度可能比 Go 1.17 的編譯速度慢大約 15%,程式碼的執行時間不受影響,目前計劃在 Go 1.19 中提高編譯器的速度。

Bug fixes

  • Go 1.18 編譯器可以正確地報告在函數文字中設定但從未使用過的變數的錯誤(已宣告但未使用),解決了一個老問題 issue  。
  • Go 1.18 編譯器現在在將如 '1' << 32 之類的符文常數表示式作為引數傳遞給預宣告函數 print 和 println 時會報告溢位。

AMD64

Go 1.18 引入了新的GOAMD64環境變數,它在編譯時選擇 AMD64 架構的最低目標版本,允許的值為v1、 v2v3v4,預設是v1

RISC-V

Linux 上的 64 位 RISC-V 架構(linux/riscv64 埠)現在支援 c-archive 和 c-shared 構建模式。

Linux

Go 1.18 需要 Linux 核心版本 2.6.32 或更高版本。

Windows

windows/arm 和 windows/arm64 端在支援非合作搶佔,有希望解決在呼叫 Win32 函數時遇到的一些細微的 bug,這些bug在很長一段時間內會阻塞。

iOS

在 iOS(ios/arm64 埠)和在基於 AMD64 的 macOS(ios/amd64 埠)上執行的 iOS 模擬器上,Go 1.18 現在需要 iOS 12 或更高版本; 已停止支援以前的版本。

FreeBSD

Go 1.18 是支援 FreeBSD 11.x 的最後一個版本,Go 1.19 需要 FreeBSD 12.2+ 或 FreeBSD 13.0+。

效能提升

由於 Go1.17 中暫存器 ABI 呼叫約定擴充套件到了 RM64 / Apple M1 / PowerPC 64 架構,因此 Go1.18 對這幾個架構包含了高達 20% 的 CPU 效能提升。

 

該 Go 1.18 版本還包含其他大量更新項,完整更新列表請在中檢視。

相關連結

  • 下載:
  • 發行說明:
  • 部落格:
  • 關於新教學的博文:
展開閱讀全文