Go 部落格

泛型的下一步

Ian Lance Taylor 和 Robert Griesemer
2020 年 6 月 16 日

引言

距離我們 上次撰寫關於在 Go 中新增泛型的可能性的文章已經將近一年了。現在是時候進行一次更新了。

更新的設計

我們一直在持續改進 泛型設計草案。我們為此編寫了一個型別檢查器:一個可以解析如設計草案所述使用泛型的 Go 程式碼並報告任何型別錯誤的程式。我們編寫了示例程式碼。並且我們收集了許多許多人的反饋——感謝你們的提供!

基於我們的學習,我們釋出了一個更新的設計草案。最大的變化是我們放棄了“契約”(contracts)的概念。契約和介面型別之間的區別令人困惑,所以我們消除了這種區別。型別引數現在由介面型別約束。介面型別現在允許包含型別列表,但僅當它們用作約束時;在先前設計草案中,型別列表是契約的一個特性。更復雜的情況將使用引數化介面型別。

我們希望人們會發現這個設計草案更簡單、更容易理解。

實驗工具

為了幫助決定如何進一步完善設計草案,我們釋出了一個翻譯工具。這個工具允許人們對使用設計草案中所描述的泛型版本的程式碼進行型別檢查和執行。它透過將泛型程式碼翻譯成普通 Go 程式碼來實現。這個翻譯過程會施加一些限制,但我們希望它足以讓人們感受一下泛型 Go 程式碼可能是什麼樣子。如果泛型被接受到語言中,實際的實現將有所不同。(我們才剛剛開始勾勒出直接的編譯器實現會是什麼樣子。)

該工具可在 Go playground 的一個變體版本上使用,網址是 https://go2goplay.golang.org。這個 playground 工作方式與普通的 Go playground 類似,但它支援泛型程式碼。

你也可以自己構建和使用該工具。它在 Go 主倉庫的一個分支中可用。請遵循 從原始碼安裝 Go 的說明。在那些指示你檢出最新發布標籤的地方,請改為執行 git checkout dev.go2go。然後按照指示構建 Go 工具鏈。

翻譯工具在 README.go2go 中有文件說明。

下一步

我們希望該工具能讓 Go 社群有機會試驗泛型。我們希望學習到的主要有兩點。

首先,泛型程式碼有意義嗎?它感覺像 Go 嗎?人們會遇到什麼意外?錯誤訊息有用嗎?

其次,我們知道許多人說過 Go 需要泛型,但我們不一定確切地知道這意味著什麼。這個草案設計是否以一種有用的方式解決了問題?如果你遇到的問題讓你覺得“如果 Go 有泛型,我可以解決它”,那麼在使用這個工具時,你能解決這個問題嗎?

我們將使用從 Go 社群收集到的反饋來決定如何前進。如果設計草案受到好評且不需要重大更改,下一步將是正式的語言變更提案。為了設定預期,如果每個人都對設計草案完全滿意且不需要任何進一步的調整,最早將泛型新增到 Go 的時間將是 2021 年 8 月釋出的 Go 1.17 版本。實際上,當然,可能會有未預見的困難,所以這是一個樂觀的時間表;我們無法做出任何明確的預測。

反饋

提供語言變更反饋的最佳方式是使用郵件列表 golang-nuts@googlegroups.com。郵件列表不完美,但似乎是我們初步討論的最佳選擇。在撰寫關於設計草案的內容時,請在主題行開頭加上 [generics],併為不同的特定主題開啟不同的主題帖。

如果你在泛型型別檢查器或翻譯工具中發現 bug,應在標準的 Go 問題跟蹤器 go.dev/issue 中提交。請在問題標題開頭加上 cmd/go2go:。請注意,問題跟蹤器不是討論語言變更的最佳場所,因為它不提供執行緒功能,也不適合進行冗長的討論。

我們期待您的反饋。

致謝

我們還沒有完成,但已經取得了長足的進步。如果沒有許多人的幫助,我們不會走到今天這一步。

我們要感謝 Philip Wadler 和他的合作者對 Go 泛型進行了正式思考,並幫助我們理清了設計的理論方面。他們的論文 Featherweight Go 分析了一個受限版本的 Go 中的泛型,並且他們在 GitHub 上開發了一個原型。

我們還要感謝那些人,他們對設計草案的早期版本提供了詳細的反饋。

最後但同樣重要的是,我們要感謝 Go 團隊中的許多人,Go 問題跟蹤器的許多貢獻者,以及所有在早期設計草案中分享想法和反饋的其他人。我們閱讀了所有內容,並且心存感激。沒有你們,我們不會走到今天這一步。

下一篇文章:保持模組的相容性
上一篇文章:Pkg.go.dev 開源了!
部落格索引