大家好,我是煎魚。
前兩天 Go1.18 beta1 已經發布,距離正式釋出 Go1.18 的生產可用還有 2 個月,也就是泛型即將正式面世。
最近正在收集泛型的一些資料,看到在 2015 年有人在 Hacker News 上的《Go 1.5 max procs default》吐槽 Go 不支援泛型是 “政治” 原因...
看了還是有些意義的,與現在的矛盾點基本一致,為此分享給大家。
網友吐槽
網友 @aikah 認為 Go 團隊不太可能在語言中加入泛型,這顯然是一個政治問題而不是技術問題。錯誤處理也是如此。
和許多人一樣,該網友認為 Go 在極簡主義和功能之間沒有取得正確的平衡。反對泛型的人贊成用編譯時型別檢查(總是安全的)換取執行時型別斷言(可能失敗)。
他們拒絕承認這一事實。這就是他們反對泛型的論點,並將最終損害語言的任何潛在增長。他們基本上是在違背自己的利益。
官方回覆
Russ Cox 做了正式的回覆:很抱歉,但不是:泛型是一個技術問題,不是一個政治問題。
Go 團隊並不反對泛型本身,只是反對做那些沒有被很好理解或不能很好地與 Go 配合的事情。
這就是核心觀點和矛盾點,也從 2009 年,延續到了現在。
會遇到的問題
Go 團隊認為要將泛型的概念融入 Go,並與系統的其他部分很好地配合,必須解決一些深層次的技術問題,而我們並沒有解決這些問題的辦法。
關於這些問題,在幾年前就在部落格上寫過一篇《The Generic Dilemma》:
即使克服了那一頁上的問題,也有其他問題,接下來你會遇到的問題是:”如何讓程式設計師以一種有用的、易於解釋的方式省略型別註釋“。
也就是如何更人性、更易於的表達泛型的型別引數。
泛型例子
舉個例子,C++ 允許你寫 make_pair(1, "foo")
,而不是 make_pair<int, string>(1, "foo")
。
為了達到這種效果,推斷註釋背後的邏輯需要幾頁幾頁的規範,這並不是一個特別容易理解的程式設計模型,當事情出錯時,編譯器也不能輕易解釋。
在這之後肯定還有更多的新問題在這裡面。
和專家溝通
Go 團隊和一些真正的 Java 泛型專家談過,他們每個人都說了大致相同的話:要非常小心,它不像看起來那麼容易,而且你會被你犯的所有錯誤困住。
作為一個 Java 示範,可以瀏覽一下《Java Generics FAQs - Frequently Asked Questions》的大部分內容:
看看過了多久你會開始思考 "這真的是最好的方法嗎?"。
在泛型過程中會遇到許多問題,像是《How do I decrypt Enum<E extends Enum<E>>》:
為此,Go 團隊在泛型的推動上非常謹慎。
承認缺點
Go 團隊說得很清楚,承認這個事實:沒有泛型是有一定的缺點的。
你要麼使用 interface{}
而放棄編譯時檢查,要麼寫程式碼生成器而使你的構建過程複雜化。
現有語言中實現的泛型也有明確的缺點,而且今天不妥協有一個非常大的好處:它使明天採用更好的解決方案變得更加容易。
總結
今天給大家分享了過去在國外社群針對 Go 泛型的各種爭議和探討,其實泛型的核心觀點很明確:”Go 團隊不反對泛型本身“。
一直沒能把泛型做起來,也是因為顧慮很多,做泛型要和 Go 多個部分,要解決很多深層次的問題,還要解決型別引數可讀性等問題。所以一直拖到了現在。
回到即將 2022 年的現在,都預言對了。社群都在扯做泛型後的多個關聯元件,以及泛型可讀性和結構...
顯然,泛型就是雙刃劍?你怎麼看。
若有任何疑問歡迎評論區反饋和交流,最好的關係是互相成就,各位的點贊就是煎魚創作的最大動力,感謝支援。
文章持續更新,可以微信搜【腦子進煎魚了】閱讀,本文 GitHub github.com/eddycjy/blog 已收錄,學習 Go 語言可以看 Go 學習地圖和路線,歡迎 Star 催更。