Rust 語(yǔ)言的設(shè)計(jì)者們可能沒(méi)想到,他們精心打磨的"一致性規(guī)則"(coherence),正在把生態(tài)變成一潭死水。
這不是某個(gè)庫(kù)的 bug,也不是開發(fā)者偷懶。當(dāng)你發(fā)現(xiàn)整個(gè)社區(qū)都在給 serde 寫膠水代碼,卻沒(méi)人能做出更好的替代品時(shí),問(wèn)題出在語(yǔ)言本身。
01 serde 成了甩不掉的房東
幾乎所有 Rust 開發(fā)者都用過(guò) serde。它定義了 Serialize 和 Deserialize 這兩個(gè)核心 trait,然后整個(gè)生態(tài)的 crate 都要給自家類型實(shí)現(xiàn)這倆接口。
邏輯很簡(jiǎn)單:你的類型不支持 serde,下游就沒(méi)法序列化它。更坑的是,serde 的 trait 只能由類型所在的 crate 實(shí)現(xiàn),或者由 serde 自己實(shí)現(xiàn)。用戶夾在中間,干瞪眼。
假設(shè)有人寫了個(gè)更好的序列化庫(kù),叫 nextserde。理論上它應(yīng)該有機(jī)會(huì)取代 serde,對(duì)吧?
現(xiàn)實(shí)是:所有已經(jīng)支持 serde 的 crate,必須再寫一遍代碼支持 nextserde。作者們不會(huì)干這種吃力不討好的事,用戶也只能繼續(xù)用 serde。新庫(kù)再好,沒(méi)生態(tài)支持就是死路一條。
serde 就像個(gè)早到一步的房東,把整棟樓的好位置全占了。后面來(lái)的租客再優(yōu)秀,也只能去郊區(qū)。
02 一致性規(guī)則:好意辦壞事
Rust 的一致性規(guī)則(coherence)本意是防止沖突:同一個(gè)類型對(duì)同一個(gè) trait,只能有一種實(shí)現(xiàn)。編譯器會(huì)檢查這個(gè),報(bào)錯(cuò)信息你可能見過(guò):
error[E0119]: conflicting implementations of trait `Trait`這保證了代碼安全,但也帶來(lái)了副作用。配合"孤兒規(guī)則"(orphan rules),它把 trait 實(shí)現(xiàn)的權(quán)限鎖死了。
孤兒規(guī)則說(shuō):你只能給"自己 crate 里的類型"或"自己 crate 里的 trait"寫實(shí)現(xiàn)。兩個(gè)都是外來(lái)的?門都沒(méi)有。
看個(gè)例子。crate A 定義了 trait 和類型:
// crate apub trait Trait {}pub struct Foo;crate B 想用?編譯器直接攔下:
// crate buse a::*;impl Trait for Foo {} // 報(bào)錯(cuò)!錯(cuò)誤信息很直白:only traits defined in the current crate can be implemented for types defined outside of the crate。
這套規(guī)則本意是防止兩個(gè)人同時(shí)給 Vec 實(shí)現(xiàn) Display,結(jié)果編譯器不知道該用哪個(gè)。但副作用是:第三方庫(kù)之間的互操作性,被一刀切了。
03 創(chuàng)新者的困境:不是不想,是不能
這種設(shè)計(jì)制造了強(qiáng)大的"先發(fā)優(yōu)勢(shì)"。serde 2014 年就發(fā)布了,十年過(guò)去,它依然是事實(shí)標(biāo)準(zhǔn)。不是因?yàn)楹竺鏇](méi)有更好的想法,而是因?yàn)樘鎿Q成本被語(yǔ)言規(guī)則人為抬高了。
想做替代品?你得讓用戶去 fork 所有依賴的 crate,手動(dòng) patch 支持你的庫(kù)。這活兒沒(méi)人愿意干。
作者 Niko Matsakis 在《Coherence and crate-level where clauses》里詳細(xì)解釋過(guò)這個(gè)問(wèn)題。他是 Rust 核心團(tuán)隊(duì)成員,也是這套機(jī)制的設(shè)計(jì)者之一。連他自己都在反思:一致性規(guī)則對(duì)生態(tài)的傷害,可能比預(yù)想的更大。
其他語(yǔ)言怎么處理?Haskell 也有類似的一致性,但允許某些靈活的擴(kuò)展。C++ 的模板沒(méi)有這種限制,代價(jià)是編譯錯(cuò)誤像天書。Rust 選了安全,但安全的代價(jià)是創(chuàng)新被鎖在既得利益者的圍墻外。
04 用戶成了最后的接盤俠
最憋屈的是普通開發(fā)者。你可能只是想把某個(gè)庫(kù)的數(shù)據(jù)結(jié)構(gòu),用新的序列化方案?jìng)鞯角岸恕=Y(jié)果發(fā)現(xiàn)要么自己 fork 維護(hù),要么乖乖用 serde。
社區(qū)不是沒(méi)有討論過(guò)解法。crate-level where 子句、特化(specialization)、或者更寬松的孤兒規(guī)則變體,都有人提案。但語(yǔ)言層面的改動(dòng)慢得像化石形成,而 serde 的地位每天都在加固。
這不是 serde 的錯(cuò)。它是個(gè)好庫(kù),設(shè)計(jì)精良,維護(hù)積極。問(wèn)題是:一個(gè)生態(tài)的健康,不應(yīng)該依賴"第一個(gè)到的人永遠(yuǎn)贏"的運(yùn)氣。
Rust 以"零成本抽象"和" fearless concurrency"自豪。但在庫(kù)生態(tài)的層面,開發(fā)者們正在支付一種隱性的成本——選擇的自由被悄悄沒(méi)收了。
如果明天有人做出比 serde 快 3 倍、內(nèi)存占用減半的序列化方案,你覺(jué)得 Rust 社區(qū)能平滑遷移過(guò)去嗎?還是我們會(huì)繼續(xù)維護(hù)那個(gè) 2014 年的接口,直到下一個(gè)十年?
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.