泛型的下一步
引言
距離我們上次編寫向 Go 添加泛型的可行性(https://blog.golang.org/why-generics)已經(jīng)過去差不多一年了。現(xiàn)在是時候進(jìn)行更新了。
設(shè)計(jì)更新
我們一直在不斷完善泛型設(shè)計(jì)草案(https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-contracts.md)。我們已經(jīng)為它編寫了一個類型檢查器:一個可以按照設(shè)計(jì)草案解析使用泛型代碼并報(bào)告任何類型錯誤的程序。我們已經(jīng)完成了示例代碼。同時,我們也收集了許許多多人的反饋ーー謝謝你們提供了這些反饋!
基于我們得到的反饋,我們發(fā)布一個更新的設(shè)計(jì)草案(https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md)。最大的變化是我們放棄了contracts的概念。contracts和interface類型之間的差異令人困惑,因此我們嘗試消除這種差異。類型參數(shù)現(xiàn)在可以被接口類型的約束。現(xiàn)在允許接口類型包含類型列表,但只有在用作約束時才可以。在以前的設(shè)計(jì)草案中,類型列表是contracts的一個特性。更復(fù)雜的情況將使用參數(shù)化的接口類型。
我們希望人們會發(fā)現(xiàn)這個設(shè)計(jì)草案更加簡單易懂。
實(shí)驗(yàn)性工具
為了幫助確定如何進(jìn)一步完善設(shè)計(jì)草案,我們發(fā)布了一個翻譯工具。這個工具允許開發(fā)人員檢查和運(yùn)行使用設(shè)計(jì)草案的泛型版本開發(fā)的代碼。它通過將泛型代碼轉(zhuǎn)換為普通 Go 代碼工作。這個翻譯過程有一些局限性,但我們希望它能夠讓人們對 Go 泛型代碼樣式有所了解。如果這個設(shè)計(jì)被接受,泛型的真正實(shí)現(xiàn)將會有不同的工作方式。(我們才剛剛開始勾勒出直接編譯器實(shí)現(xiàn)的大概樣子。)
這個工具可以在 https://go2goplay.golang.org 的 Go Playground 上使用。這個 Playground 就像通常的 Go Playground 一樣,不過它支持泛型代碼。
您也可以自己構(gòu)建和使用該工具。它在主 Go 倉庫中的一個分支中。按照從源代碼開始安裝 Go 的說明(https://golang.org/doc/install/source)進(jìn)行操作。不過這些操作說明需要你檢查最新的 release 標(biāo)記,而這里我們需要運(yùn)行git checkout dev.go2go。然后按照指引構(gòu)建 Go 工具鏈即可。
這個翻譯工具在 README.go2go (https://go.googlesource.com/go/+/refs/heads/dev.go2go/README.go2go.md)中有文檔說明。
下一步
我們希望這個工具能給 Go 社區(qū)一個體驗(yàn)泛型的機(jī)會。我們希望通過這個工具了解兩件事情。
首先,泛型代碼有意義嗎?感覺像 Go 的風(fēng)格嗎?人們會遇到什么樣的驚喜?錯誤消息有用嗎?
其次,我們知道很多人說 Go 需要泛型,但是我們不一定知道泛型使用具體是什么樣的場景。這個設(shè)計(jì)草案是否有效地解決了問題?如果有一個問題使你認(rèn)為 “如果 Go 有泛型,我就可以解決這個問題” ,那么在使用這個工具能解決你的問題嗎?
我們將使用從 Go 社區(qū)中收集到的反饋來決定如何前進(jìn)。如果設(shè)計(jì)草案很受歡迎,并且不需要重大修改,那么下一步這將是一個正式的語言變更提案(https://github.com/golang/proposal#readme)。為了設(shè)定預(yù)期,如果所有人都對設(shè)計(jì)草案完全滿意,并且不需要進(jìn)一步的調(diào)整,那么最早泛型將會 2021 年 8 月發(fā)布的 Go 1.17 進(jìn)行添加。當(dāng)然,在現(xiàn)實(shí)中,可能會有不可預(yù)見的問題,所以這是一個樂觀的時間表; 我們不能作出任何明確的預(yù)測。
反饋
提供語言變化反饋的最好方法是在郵件列表 [email protected] 上。郵件列表并不是完美的,但它們似乎是我們早期討論的最佳選擇。在撰寫設(shè)計(jì)草案時,請將[generics]放在主題行的開頭,并針對不同的具體主題使用不同的討論串。
如果你在泛型類型檢查器或者翻譯工具中發(fā)現(xiàn)了 bug,它們應(yīng)該被提交到 Go 問題追蹤 https://golang.org/issue 中。請以?cmd/go2go:.?作為標(biāo)題的開頭。注意,問題追蹤不是討論語言更改的最佳位置,因?yàn)樗惶峁┯懻摯膊贿m合長時間的對話。
我們期待著你的反饋。
致謝
我們還沒有結(jié)束,但是我們已經(jīng)走了很長的路。如果沒有很多的幫助,我們無法到達(dá)這里。
我們要感謝 Philip Wadler 和他的合作者,他們正式地思考了 Go 中的泛型,并幫助我們厘清了設(shè)計(jì)的理論方面。他們的論文 Featherweight Go (https://arxiv.org/abs/2005.11710)在受限的 Go 版本中分析泛型,并且他們在 GitHub 上開發(fā)了一個原型。
我們還要感謝那些對早期版本的設(shè)計(jì)草案提供了詳細(xì)反饋的人。
最后但卻很重要的一點(diǎn)就是,我們要感謝 Go 團(tuán)隊(duì)的許多人,Go 問題追蹤的許多貢獻(xiàn)者,以及所有其他對早期設(shè)計(jì)草案分享想法和反饋的人(https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#acknowledgements)。我們讀完了所有的文章,我們很感激。沒有你我們不會到達(dá)這里。
點(diǎn)擊“閱讀原文”即可查看:The Next Step for Generics
