終於!Go 1.18 將支援泛型,來聽聽Go 核心技術團隊 Russ Cox怎麼說

MissD發表於2021-11-04

近日,Go 語言核心開發團隊技術主管 Russ Cox 在 golang-dev group 發了公開郵件,宣佈稱“如果沒有意外情況,Go 1.18 將會支援泛型。”據悉,Go 1.18 版即將於2022年初發布。

還記得10月初,本站剛剛報導了“Go語言之父”Rob Pike在github上關於“不建議在Go 1.18的標準庫中使用泛型”issue的訊息。當時,Rob Pike的擔心是“Go 1.18版本承載了太多的change,容易出錯”,所以建議先等待觀察,穩步向前。

而到了10月28日的昨天,Russ Cox又發文針對 Rob Pike 的 issue,介紹了Go 1.18 版本與泛型目前的進展和後續的支援策略,這也終於確定了Go核心團隊下階段的方向——也就是說,如果不出意外的話,Go 1.18版本中將支援泛型。

加入泛型對於Go團隊的意義

作為Go釋出以來最重要的變化,Russ Cox在這封公開郵件中簡單解釋了泛型的加入對Go團隊和使用者的意義。

Russ Cox表示,任何Go的新功能特性,無論是語言還是庫,都帶有不確定性,包括不確定如何使用、如何不使用它們,以及有哪些微小的bug已經通過了現有的測試集。泛型也不能避免這種不確定性,特別是由於泛型是個大型的新功能,所以它的不確定性也會更大。

同時,在該團隊最初發布的泛型程式碼–特別是通過提案程式的maps和slices包–將首先放在golang.org/x/exp中,但不能保證向後相容。Russ Cox稱,未來一旦有了更多的經驗,會希望將其中一些包推廣到標準庫中(constraints包例外,它作為編寫某些泛型程式碼的基礎,將被新增到Go 1.18標準庫中。)

Russ Cox 強調,Go 1.18與其他Go 1.x版本一樣具有向後相容的承諾,“不會破壞用Go 1.18構建的程式碼,包括使用泛型的程式碼。在最壞的情況下,如果我們發現Go 1.18的語義有一些致命的問題,並需要改變它們(例如在Go 1.19中),我們將使用go.mod檔案的go版本指示符來確定該module中的原始檔是使用Go 1.18還是Go 1.19+的語義。(我們預計不需要這樣做!)”

對於不少急於採用泛型的軟體包作者,Russ Cox建議稱“如果您正在更新您的軟體包以使用泛型,請考慮將新的泛型API隔離到自己的檔案中,併為其使用Go 1.18的構建標籤(//go:build go1.18),以便Go 1.17使用者可以繼續構建和使用非泛型部分。”

值得注意的是,第三方工具可能不會在Go 1.18釋出時完全支援泛型。目前,Go核心團隊正在與不少第三方工具的作者溝通,試圖確保他們得到適當的更新,但他們都有自己的時間安排表。

對於“為什麼不把泛型變成可選項加入Go 1.18?”的疑問,Russ Cox解釋稱,減少不確定性的唯一方法是讓其預設可用。

“當我們在Go 1.5版本中讓vendor機制作為可選項加入時,發現幾乎沒有人真正使用它,直到Go 1.6版本預設開啟它。所以Go 1.5版本沒有減少我們對Go開發者使用vendor情況的不確定性。另一方面,Go 1.5版本無疑將生態系統分為’在標準Go下執行的程式碼‘和 ’在啟用vendoring後執行的程式碼‘兩部分。我們希望在這裡儘可能地避免這種結果。”

Go語言為什麼需要泛型?

一直以來,業界關於Go語言泛型的話題討論都非常激烈,而Go團隊也一直對否加入泛型而猶豫不決,因為他們希望找到一種好的解決方案。

我們知道,函數語言程式設計是一種非常流行的程式設計正規化,在很多組合語言型別裡都有構建或支援。而對於Go語言來說,儘管並非是一種函式式語言,但它確實提供了一組允許函數語言程式設計的特性(有相當數量的開源Go庫提供功能特性集)。

函數語言程式設計的語言支援範圍從只支援函式式正規化(如Haskell)到多正規化+一流支援(如Scala、Elixir)再到多正規化+部分支援(如Javascript、Go)。在後一類語言中,函數語言程式設計一般通過使用社群建立的庫來支援,這些庫複製前兩種語言的標準庫中的部分或全部功能。

Go語言則屬於最後一類,它可以實現下圖中的功能程式設計:

在Go語言生態系統中,已經存在許多功能性程式設計庫,它們在流行程度、功能和工效方面各不相同。

儘管已經支援其中的一些功能,例如一級和高階函式以及啟用函式程式設計,但依舊缺少一個關鍵特性——泛型。

如果沒有泛型,Go語言的功能庫和應用程式將被迫走兩條路徑:

一、型別安全+用例特定。選擇這種方法的庫實現了型別安全的設計,但只能處理某些預定義型別。由於不能使用自定義型別或結構,這些庫可以應用於的問題的種類是有限的。當然這兩種型別都是安全的,但僅適用於預定義的型別。

二、型別不安全+用例不可知。選擇這種方法的庫,實現了一種型別不安全但可應用於任何用例的設計。這些庫使用自定義型別和結構,但需要權衡,如果未正確實現,會使應用程式面臨執行時當機風險。這兩個設計選項提供了兩個類似的選項,“有限實用程式或執行時恐慌風險”。因此,最簡單也是最常見的選擇是不要使用帶有命令式風格的函數語言程式設計庫。

所以現在,隨著 Go 1.18 版的到來,Go團隊也正式宣佈泛型終於要被新增進去了,以在Go語言中實現新的函數語言程式設計解決方案。

自從Go 1.18“支援泛型”的訊息傳開之後,一些外媒隨即整理了一些基於Go泛型(Go 1.18)的函式庫,可以新增到切片包中,供開發者使用。但我們在這裡建議大家,希望一切以官方資訊為主。

相關文章