大家好,我是煎魚。
Go 泛型配套了各種標準庫,像是常見的 maps、slices 泛型庫。
早期他們是長這樣的:
package maps
func Keys[M constraints.Map[K, V], K comparable, V any](m M) []K
func Values[M constraints.Map[K, V], K comparable, V any](m M) []V
...
又或是:
package slices
func Compare[E constraints.Ordered](s1, s2 []E) int
...
關注到裡面的標準庫 constraints
,他就是今天變更的主角。他咋了呢?
背景
標準庫 constraints
是個新鮮事物,由泛型扛把子 Ian Lance Taylor 在 2021 年 9 月 24 日提交《constraints: new package to define standard type parameter constraints》 所新增。
如下圖:
主要作用是新增一個約束(constraints)包來定義一些標準有用的約束,所以我們會在通用庫看到這些標準約束的使用。
緣由
新提案
在社群一番熱烈討論中,有人提了一個提案《proposal: constraints: rename package to "of"》,希望對 constraints 包進行更名。
新的程式碼如下:
func Abs[V of.Number](v V) V{...}
func Sum[K comparable, V of.Number](m map[K]V) V {...}
作者認為使用 “of” 這個關鍵字比 “constraints” 更簡單流暢。
該提案引來了大量的討論,覺得 constraints 這個名字現在太長,一旦函式簽名比較多,就會很繁瑣,看著也不舒服。
有建議使用引用別名來解決的:
import of “constraints”
也有說是用 any,is 名字,甚至叫 std,或是其他的匯入方式。
眾說紛紜,雖然在後面大幅度的優化了 constraints
的使用頻率,但一旦用到 2~3 次,就會出現函式簽名過於龐大的問題。
最終由於未能討論出明確的共識,被拒絕。
掙扎的結論
經過這長時間的泛型推進和命名爭議,Russ Cox 發現約束包仍然存在著許多問題,是待商榷的。
分別是:
- 包名字太醜:很多人對包的名字,也就是對 constraints 很滿意,也有很不滿意的,覺得太長,太囉嗦。
- 不知道放什麼:對於放在包裡面的東西,尚不清楚哪些介面是重要的,應該存在,哪些不應該存在。
- 似乎不需要:一開始認為標準的約束是使用泛型的基礎,但在實踐中並沒有證明是這樣,甚至可以不要。
基於上述原因,Go 團隊決定將標準庫 constraints 與 maps、slices 一樣,轉移到 x/exp 中,作為實驗性功能來對待。
再在 Go 1.19 或 1.20 中重新審視他們,看看是不是真的有用,又或是怎麼用才是對的,再做決定。
總結
Go 泛型在本月(2月)即將在 Go1.18 中釋出(春節的時候,通知社群鴿到 3 月份了...),雖然從表面來看,核心功能已經基本定型了,但配套設施還是比較亂。
建議大家在正式生產使用上,還是有注意節奏,免得踩坑。
你覺得 constraints 這個命名咋樣,歡迎大家一起來討論:)
若有任何疑問歡迎評論區反饋和交流,最好的關係是互相成就,各位的點贊就是煎魚創作的最大動力,感謝支援。
文章持續更新,可以微信搜【腦子進煎魚了】閱讀,本文 GitHub github.com/eddycjy/blog 已收錄,學習 Go 語言可以看 Go 學習地圖和路線,歡迎 Star 催更。