終于!Go 1.18 將支持泛型,來聽聽 Go 核心技術團隊怎么說
近日,Go 語言核心開發(fā)團隊技術主管 Russ Cox 在 golang-dev group 發(fā)了公開郵件,宣布稱“如果沒有意外情況,Go 1.18 將會支持泛型”。
據(jù)悉,Go 1.18 版即將于2022年初發(fā)布。

還記得10月初,本站剛剛報道了“Go語言之父”Rob Pike在github上關于“不建議在Go 1.18的標準庫中使用泛型”issue的消息。當時,Rob Pike的擔心是“Go 1.18版本承載了太多的change,容易出錯”,所以建議先等待觀察,穩(wěn)步向前。
而到了10月28日的昨天,Russ Cox又發(fā)文針對 Rob Pike 的 issue,介紹了Go 1.18 版本與泛型目前的進展和后續(xù)的支持策略,這也終于確定了Go核心團隊下階段的方向——也就是說,如果不出意外的話,Go 1.18版本中將支持泛型。
加入泛型對于Go團隊的意義
作為Go發(fā)布以來最重要的變化,Russ Cox在這封公開郵件中簡單解釋了泛型的加入對Go團隊和用戶的意義。

Russ Cox表示,任何Go的新功能特性,無論是語言還是庫,都帶有不確定性,包括不確定如何使用、如何不使用它們,以及有哪些微小的bug已經(jīng)通過了現(xiàn)有的測試集。泛型也不能避免這種不確定性,特別是由于泛型是個大型的新功能,所以它的不確定性也會更大。
同時,在該團隊最初發(fā)布的泛型代碼–特別是通過提案程序的maps和slices包–將首先放在golang.org/x/exp中,但不能保證向后兼容。Russ Cox稱,未來一旦有了更多的經(jīng)驗,會希望將其中一些包推廣到標準庫中(constraints包例外,它作為編寫某些泛型代碼的基礎,將被添加到Go 1.18標準庫中)。
Russ Cox 強調(diào),Go 1.18與其他Go 1.x版本一樣具有向后兼容的承諾,
“不會破壞用Go 1.18構建的代碼,包括使用泛型的代碼。在最壞的情況下,如果我們發(fā)現(xiàn)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用戶可以繼續(xù)構建和使用非泛型部分。”
值得注意的是,第三方工具可能不會在Go 1.18發(fā)布時完全支持泛型。目前,Go核心團隊正在與不少第三方工具的作者溝通,試圖確保他們得到適當?shù)母拢麄兌加凶约旱臅r間安排表。
對于“為什么不把泛型變成可選項加入Go 1.18?”的疑問,Russ Cox解釋稱,減少不確定性的唯一方法是讓其默認可用。
“當我們在Go 1.5版本中讓vendor機制作為可選項加入時,發(fā)現(xiàn)幾乎沒有人真正使用它,直到Go 1.6版本默認開啟它。所以Go 1.5版本沒有減少我們對Go開發(fā)者使用vendor情況的不確定性。另一方面,Go 1.5版本無疑將生態(tài)系統(tǒng)分為’在標準Go下運行的代碼‘和 ’在啟用vendoring后運行的代碼‘兩部分。我們希望在這里盡可能地避免這種結(jié)果。”
Go語言為什么需要泛型?
一直以來,業(yè)界關于Go語言泛型的話題討論都非常激烈,而Go團隊也一直對否加入泛型而猶豫不決,因為他們希望找到一種好的解決方案。
我們知道,函數(shù)式編程是一種非常流行的編程范式,在很多匯編語言類型里都有構建或支持。而對于Go語言來說,盡管并非是一種函數(shù)式語言,但它確實提供了一組允許函數(shù)式編程的特性(有相當數(shù)量的開源Go庫提供功能特性集)。
函數(shù)式編程的語言支持范圍從只支持函數(shù)式范式(如Haskell)到多范式+一流支持(如Scala、Elixir)再到多范式+部分支持(如Javascript、Go)。在后一類語言中,函數(shù)式編程一般通過使用社區(qū)創(chuàng)建的庫來支持,這些庫復制前兩種語言的標準庫中的部分或全部功能。
Go語言則屬于最后一類,它可以實現(xiàn)下圖中的功能編程:

在Go語言生態(tài)系統(tǒng)中,已經(jīng)存在許多功能性編程庫,它們在流行程度、功能和工效方面各不相同。
盡管已經(jīng)支持其中的一些功能,例如一級和高階函數(shù)以及啟用函數(shù)編程,但依舊缺少一個關鍵特性——泛型。
如果沒有泛型,Go語言的功能庫和應用程序?qū)⒈黄茸邇蓷l路徑:
一、類型安全+用例特定。選擇這種方法的庫實現(xiàn)了類型安全的設計,但只能處理某些預定義類型。由于不能使用自定義類型或結(jié)構,這些庫可以應用于的問題的種類是有限的。當然這兩種類型都是安全的,但僅適用于預定義的類型。
二、類型不安全+用例不可知。選擇這種方法的庫,實現(xiàn)了一種類型不安全但可應用于任何用例的設計。這些庫使用自定義類型和結(jié)構,但需要權衡,如果未正確實現(xiàn),會使應用程序面臨運行時死機風險。這兩個設計選項提供了兩個類似的選項,“有限實用程序或運行時恐慌風險”。因此,最簡單也是最常見的選擇是不要使用帶有命令式風格的函數(shù)式編程庫。
所以現(xiàn)在,隨著 Go 1.18 版的到來,Go團隊也正式宣布泛型終于要被添加進去了,以在Go語言中實現(xiàn)新的函數(shù)式編程解決方案。
自從Go 1.18“支持泛型”的消息傳開之后,一些外媒隨即整理了一些基于Go泛型(Go 1.18)的函數(shù)庫,可以添加到切片包中,供開發(fā)者使用。但我們在這里建議大家,希望一切以官方信息為主。

