你期望 Go 1.18 中泛型是什么樣子?
大家好,我是程序員幽鬼。
前段時(shí)間 Rob Pike 在 Go repo 提了一個(gè) issue:go: don't change the libraries in 1.18[1],提到因?yàn)榉盒褪钦Z(yǔ)言層面的大改動(dòng),必須循序漸進(jìn),步子不能邁太大。具體介紹可以查看:Go 重視兼容性是認(rèn)真的:泛型得慢慢加。
昨天,Go Team Leader Russ Cox 在 golang-dev 郵件組發(fā)了一篇較長(zhǎng)的郵件:expectations for generics in Go 1.18[2],對(duì) Go 1.18 與泛型當(dāng)前進(jìn)展及后續(xù)的支持策略做了說(shuō)明,已確定 Go 核心團(tuán)隊(duì)與社區(qū)的努力方向。
以下是該郵件的內(nèi)容,非完全翻譯版。
如果不出嚴(yán)重意外的話,Go 1.18 將包含對(duì)泛型的支持。泛型是自 Go1 發(fā)布以來(lái)最重要的變化,當(dāng)然也是我們做過(guò)的最大一次語(yǔ)言變化[3]。這封郵件解釋了包含泛型對(duì)我們和用戶的意。
任何新的 Go 特性,無(wú)論是語(yǔ)言層面還是庫(kù)層面,都帶有不確定性:包括不確定如何使用它,不確定如何不使用它,以及關(guān)于哪些微小 bug 已經(jīng)通過(guò)現(xiàn)有測(cè)試的不確定性。泛型的加入當(dāng)然也會(huì)存在這種不確定性。事實(shí)上,由于泛型是一個(gè)較大的新特性,因此不確定性也相應(yīng)地更大。
因?yàn)槲覀儾恢朗褂梅盒偷淖罴褜?shí)踐是什么,我們的文檔將無(wú)法給出關(guān)于何時(shí)使用它們以及何時(shí)不使用它們的準(zhǔn)確、明確的答案。當(dāng)然,我們可以而且仍然會(huì)給出粗略的泛型使用指南。其實(shí),我們之前也有類似的做法:我們?cè)诓婚g斷地編寫 Go 代碼一整年之后,才寫出了 Effective Go 的初始版本[4]。我們對(duì)泛型同樣沒(méi)有高水平的經(jīng)驗(yàn),因此,雖然我們會(huì)提供有關(guān)如何使用泛型的文檔,但我們無(wú)法提供任何關(guān)于代碼風(fēng)格和最佳實(shí)踐的說(shuō)明。
因?yàn)槲覀儾恢谰帉懛盒桶淖罴褜?shí)踐是什么,因此,原本計(jì)劃發(fā)布的特意為泛型增加的包 maps 和 slices,不會(huì)進(jìn)入標(biāo)準(zhǔn)庫(kù),而是先放入 golang.org/x/exp[5],這里的代碼不保證向后兼容。一旦我們有了更多的經(jīng)驗(yàn),我們希望將其中一些包加入到標(biāo)準(zhǔn)庫(kù)中。不過(guò),constraints 包會(huì)如期進(jìn)入 Go1.18 的標(biāo)準(zhǔn)庫(kù)中,因?yàn)樗蔷帉懩承┓盒痛a的基礎(chǔ)。
因?yàn)槲覀儧](méi)有 Go 泛型的任何線上使用經(jīng)驗(yàn),所以我們將在發(fā)行說(shuō)明中明確指出,應(yīng)適當(dāng)謹(jǐn)慎地處理泛型的生產(chǎn)用途(注:大概率大家也會(huì)比較謹(jǐn)慎,不會(huì)立馬使用)。注意,這不是說(shuō)團(tuán)隊(duì)的工作不出色。畢竟,泛型與大多數(shù) Go 更改不同。當(dāng)時(shí),我們重寫垃圾收集器或更改調(diào)用規(guī)約時(shí),我們會(huì)使用新的實(shí)現(xiàn)在測(cè)試和生產(chǎn)中運(yùn)行所有 Google 的 Go 程序,這樣就能很好地驗(yàn)證了變化,發(fā)現(xiàn)難以發(fā)現(xiàn)的錯(cuò)誤。相比之下,還在開(kāi)發(fā)的 Go 1.18 工具鏈重建非泛型代碼并不能驗(yàn)證對(duì)泛型的支持,這意味著我們無(wú)法建立同樣的信心。
綜上所述,Go 1.18 具有與其他 Go 1.x 版本相同的向后兼容性承諾:我們不會(huì)破壞使用 Go 1.18 構(gòu)建的代碼,包括使用泛型的代碼。在最壞的情況下,如果我們發(fā)現(xiàn) Go 1.18 語(yǔ)義存在一些致命問(wèn)題并需要更改它們(例如在 Go 1.19 中),我們將使用 go.mod 文件的 go 版本指示來(lái)確定該 module 中的源文件是期望 Go 1.18 還是 Go 1.19+ 語(yǔ)義。(目前,我們預(yù)計(jì)不需要這樣做!)
我們預(yù)計(jì)一些第三方包的作者會(huì)第一時(shí)間采用泛型。如果你正在更新你的包以使用泛型,請(qǐng)考慮將新的泛型 API 單獨(dú)到它自己的文件中,并增加 Go1.18 的構(gòu)建 tag,如 //go:build go1.18,以便 Go 1.17 用戶可以繼續(xù)構(gòu)建和使用非泛型。
另外值得注意的是,第三方工具在 Go 1.18 版本發(fā)布時(shí)可能不完全支持泛型。我們正在與許多工具的作者交流,并試圖確保他們得到適當(dāng)?shù)母拢總€(gè)工具都會(huì)有自己的時(shí)間表。
有不少人給我們反饋了一個(gè)常見(jiàn)問(wèn)題:考慮到所有這些不確定性,為什么不讓泛型在 Go1.18 中成為可選的?(注:實(shí)際上,Go1.17 就有部分可選了)實(shí)際上,在這一點(diǎn)上,減少不確定性的唯一方法是默認(rèn)情況下提供泛型。當(dāng)我們?cè)?Go 1.5 中可選地加入 vendoring 時(shí),結(jié)果真實(shí)情況是幾乎沒(méi)有人真正使用它,直到 Go 1.6 默認(rèn)打開(kāi)它,大家才使用它。所以 Go 1.5 版本沒(méi)有減少我們對(duì) Go 開(kāi)發(fā)者使用 vendoring 情況的不確定性。另一方面,這種情況,Go 1.5 版本無(wú)疑將生態(tài)系統(tǒng)分為“在標(biāo)準(zhǔn) Go 下運(yùn)行的代碼”和“在啟用 vendoring 后運(yùn)行的代碼”兩個(gè)部分。我們希望 Go1.18 盡可能地避免這種結(jié)果。
作為 Go 愛(ài)好者,作為期待泛型的你,最重要的事情是編寫一些泛型代碼,如果你發(fā)現(xiàn)了 bug、不清楚的編譯器錯(cuò)誤等,請(qǐng)?zhí)? issue。我最近寫了一些泛型數(shù)據(jù)結(jié)構(gòu),對(duì)整體體驗(yàn)非常滿意。我希望你也是;如果沒(méi)有這種感覺(jué),請(qǐng)?zhí)峤?issue。謝謝!
本文轉(zhuǎn)載自微信公眾號(hào)「幽鬼」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系幽鬼公眾號(hào)。