GO語言標准庫的演進叠代原則

超級歐派課程 2024-05-04 04:39:04

go 官方表示此項工作的目標之一是爲如何處理標准庫中所有v2包確立一套原則與模式。未來幾個Go版本並不會一口氣出現衆多新v2包。我們將逐一處理,確保設定的品質標准可以持續未來十年。有許多包可能完全不需要v2版本。但是,對于那些需要版本升級的包,我們的方法可以歸納爲以下三個原則。

新舊版本並存

與之前版本不兼容的包將采用that/package/v2作爲其導入路徑,就像標准庫以外的v2模塊一樣,遵循語義導入版本號規則。這使得原本包的使用與v2包在同一個程序中共存成爲可能,這對逐步過渡新API至關重要。

不同版本的包應該能夠在代碼中共存的原因主要有以下幾點:

兼容性:在現實的開發過程中,引入新版本的包可能會改變某些API或者引入新的特性,這些變化可能會與已有的代碼産生沖突。如果不同版本的包可以共存,開發者就可以在不改變已有代碼的情況下引入新版本,避免破壞現有的系統。平滑升級:如果新舊版本可以共存,那麽開發者就可以逐漸將代碼遷移到新版本,而不是一次性將所有的代碼都進行升級。這樣的過渡可以讓開發者有足夠的時間來適應新版本,同時也可以在過渡期間識別並解決可能出現的問題。靈活性:在某些情況下,開發者可能同時需要使用新舊兩個版本的包。比如,他們可能在一些舊的代碼模塊中使用舊版本,同時在新的代碼模塊中使用新版本。如果新舊版本可以共存,那麽開發者就有更大的靈活性來組織他們的代碼。保障穩定性:引入新版本的包往往意味著存在風險,比如新版本的包可能存在尚未發現的bug,或者其性能還沒有被充分驗證。如果新舊版本可以共存,那麽當新版本的包出現問題時,開發者可以立即回退到舊版本,保障系統的穩定性。

因此,允許不同版本的包在代碼中共存是非常重要的,它可以幫助開發者更好地管理代碼,同時也能提高代碼的穩定性和開發的靈活性。

尊重現有用戶以及使用方式

所有的修改必須基于對當前用戶和使用情況的尊重:不能引入不必要的變動,無論是對現有包的無謂改動,還是完全需要重新學習的新包。實際運用中,這意味著我們以當前的包作爲起點,只對有充分理由且能爲用戶更新帶來價值的變動進行修改。

不能引入無需的變化,無論是形式上對現有包的不必要改動,還是完全需要用戶重新學習的全新包。

這個原則的主要考慮因素有:

尊重用戶需求:每一次的改變都必須基于對現有用戶和他們的實際需求的深入理解。這樣可以保證在叠代優化的過程中,始終會在提升用戶體驗並增加用戶價值的方向上進行。穩定性保障:避免了因頻繁的無需改動而導致用戶的混亂和系統的不穩定,相反,只對有充分理由且對更新用戶帶來價值的部分進行改變。低學習成本:這個原則保證了改動會以當前包爲起點,避免用戶需要花費額外的時間和精力去學習全新的包。更好的演進策略:它確保了標准庫的演進方向以對現有用戶和使用方式的尊重爲基礎,使得標准庫的演進更加目標明確,更加符合用戶的實際需要。

這個原則有助于維護用戶信任,降低學習成本,並指導標准庫往更實用、更穩定的方向發展。

向前兼容:v2包應具備v1包的全部能力

v2包不應遺忘v1的用戶。理想情況下,v2包應具備v1包的全部能力。同時,在v2發布時,v1包應被改寫爲基于v2的薄層封裝。這能確保v1版本的現有用戶依然可以從v2中的錯誤修複和性能優化中受益。當然,由于v2引入了一些重大改變,這並不總是可能的,但這仍是我們需要仔細考慮的一點。

保留v1的用戶的原因主要有以下幾點:

兼容性:許多現有的項目可能已經基于v1版本的庫進行了開發和部署,他們可能無法立即升級到v2,因爲這可能會需要進行大量的代碼修改和測試。保留v1用戶可以確保這些項目可以繼續正常運行,同時也可以在適當的時候平滑地過渡到v2。學習曲線:對于新來的或者不熟悉v2的用戶,v1可能是他們接觸和學習的起點。同時,v1對于一些老用戶來說已經非常熟悉,他們可能不願意或者沒有必要立即遷移到v2。保留v1用戶也就意味著尊重他們的學習選擇和使用習慣。維護性:通常情況下,v1版本在發布v2的時候已經非常穩定,並且積累了大量的使用案例和社區資源,如文檔和問題解答。這些是無法短時間內完全複制到v2的。 通過保留v1,可以讓用戶在享受新功能的同時,還能利用到這些已有的社區資源。持續優化:如原文提到的,v1版本應該是v2版本的薄封裝,這樣v1版本就可以繼續從v2中的錯誤修複和性能優化中受益,也就是說,雖然使用的是舊版本,但是用戶依然可以享受到新版本帶來的一些優點。

保留v1的用戶不僅體現了對用戶的尊重,也確保了Go標准庫的穩定性和持續優化。同時,也爲用戶提供了更多的選擇,確保了他們可以根據自身的實際情況和需求選擇最合適的版本。

以math/rand/v2 這個包爲例進行說明

對于math/rand/v2,我們設計了自動初始化種子的v1函數調用v2生成器,但我們無法共享其他代碼,因現有代碼不符合可重複性。

最終,math/rand 並不是很大的代碼庫,且無需定期進行維護,所以代碼重複問題是可以控制的。在其他環境中,更多的避免重複可能是有價值的。

例如,在進行中的encoding/json/v2設計中,盡管默認語義和API發生了變更,但包內提供了一些配置選項,使v1 API的實現成爲可能。最終,當我們發布encoding/json/v2時,v1版的encoding/json將成爲其薄層封裝,確保那些未從v1遷移的用戶可以從v2的優化和安全性修複中受益。

總結

Go的演進策略充分體現了其作爲工程型的語言特性,穩定、實用和持續優化是其主要的考慮方向:

穩定性和兼容性:Go被廣泛應用在各類底層系統和基礎設施中,穩定性和兼容性是其核心的需求。Go的策略保證了在引入新特性和優化的同時,不會對現有的代碼産生破壞,使得開發者可以依賴其長期穩定地運行。實用和可維護:Go注重實用性,對于不必要的改變持謹慎態度,這既是出于尊重現有用戶,也是爲了降低維護成本。暴力升級會給開發者帶來額外的學習成本,而且可能引入新的bug,Go的策略避免了這種情況的發生。持續優化:Go的方向是持續優化和改進,但不應犧牲現有用戶的利益。新版的優化和修複可以反饋到舊版,使所有用戶都能夠受益。

因爲 golang 是面向工程,面向研發人員而設計的輕量級現代化編程語言,因此其演進方向也是考慮了很多工程特性,這也是 golang 的優勢,如果您剛好在學習 golang,我推薦下面這個專欄,裏面包含了各種一線生産最佳實踐和使用技巧,讓你可以快速了解並學會通過 golang 編寫符合最佳實踐的大型項目。

0 阅读:22

超級歐派課程

簡介:感謝大家的關注