Go 部落格
泛型的下一步
引言
距離我們上一次撰寫關於在 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 中的版本將是 Go 1.17,計劃於 2021 年 8 月釋出。當然,實際情況中可能會有不可預見的問題,因此這只是一個樂觀的時間表;我們無法做出任何確定的預測。
反饋
關於語言變更反饋的最佳方式是透過郵件列表 golang-nuts@googlegroups.com
。郵件列表並非完美,但對於初步討論來說,它們似乎是我們的最佳選擇。在撰寫關於設計草案的郵件時,請在主題行的開頭加上 [generics]
,並針對不同的具體議題開啟不同的討論串。
如果您在泛型型別檢查器或轉換工具中發現了錯誤,請在標準的 Go 問題跟蹤器 go.dev/issue 中提交。請在問題標題的開頭加上 cmd/go2go:
。請注意,問題跟蹤器並非討論語言變更的最佳場所,因為它不提供討論串功能,也不適合進行冗長的對話。
我們期待您的反饋。
致謝
我們尚未完成,但已經走了很長一段路。沒有大量的幫助,我們不可能走到今天。
我們想感謝 Philip Wadler 及其合作者,他們對 Go 中的泛型進行了形式化思考,並幫助我們闡明瞭設計的理論方面。他們的論文Featherweight Go分析了受限版本 Go 中的泛型,並且他們在GitHub 上開發了一個原型。
我們還要感謝那些在早期版本設計草案上提供了詳細反饋的人們。
最後但同樣重要的是,我們想感謝 Go 團隊的許多成員,Go 問題跟蹤器的許多貢獻者,以及所有其他在早期設計草案上分享了想法和反饋的人。我們閱讀了所有的反饋,我們非常感激。沒有你們,我們不會走到今天。
下一篇文章:保持您的模組相容
上一篇文章:Pkg.go.dev 已開源!
部落格目錄