接連被開源項(xiàng)目curl、Prisma棄用,Rust語言遭遇水逆,網(wǎng)友:從狂熱粉到后悔莫及
一時(shí)之間,Rust 編程語言陷入到了接連被棄用的窘境。
作為一門系統(tǒng)編程語言,Rust 專注于安全,尤其是并發(fā)安全。它支持函數(shù)式和命令式以及泛型等編程范式的多范式語言,在語法上和 C、C++ 類似。
圖源:https://x.com/ThePrimeagen/status/1875592777440084416
就在剛剛過去的 12 月底,知名開源項(xiàng)目 curl 的創(chuàng)始人 Daniel Stenberg 宣布:將放棄支持基于 Rust 編寫的 Hyper HTTP 后端,并徹底移除相關(guān)代碼。此舉引起了開發(fā)者社區(qū)的廣泛關(guān)注。
旅程即將結(jié)束,實(shí)驗(yàn)結(jié)束了。我們努力過,但還是失敗了。
2020 年,Stenberg 開始在 curl 中添加對(duì)另一種 HTTP 后端的支持,它使用了基于 Rust 編寫的庫,被稱為 hyper。他的想法是引入一種替代的 HTTP 內(nèi)部實(shí)現(xiàn),從而可以讓 curl/libcurl 使用它來代替本機(jī)實(shí)現(xiàn)。目標(biāo)是借助 Rust 的內(nèi)存安全性,為 curl 用戶提供一個(gè)更安全的 HTTP 后端實(shí)現(xiàn)。
最初的工作得到了 ISRG 的慷慨贊助,它是「Let’s Encrypt」等出色工作的背后組織。期間 Stenberg 與 hyper 首席開發(fā)人員 Sean McArthur 密切合作,并取得了很大進(jìn)展。到目前為止,Stenberg 已經(jīng)在 curl 中以 EXPERIMENTAL 為標(biāo)簽提供了 hyper 支持,希望吸引用戶的興趣并激發(fā)他們的實(shí)驗(yàn)精神。
Stenberg 表示,他們已經(jīng)完成了 95% 的工作,而且?guī)缀跽麄€(gè)測(cè)試套件都以相同的方式運(yùn)行,無論構(gòu)建 curl 時(shí)使用哪個(gè)后端。然而,正是那最后的百分之幾卻變成了最大的阻力,最終導(dǎo)致了項(xiàng)目失敗、放棄并全部撤出。
為什么呢?總結(jié)起來,主要有以下兩方面原因。
一方面,幾乎沒人有這樣的需求,curl 的用戶對(duì) hyper 沒有興趣;現(xiàn)有的 hyper 用戶也不關(guān)心它是否兼容 curl。
另一方面,libcurl 庫是用 C 編寫的,hyper 是用 rust 編寫的,兩者之間需要一個(gè) C 粘合層。這就需要同時(shí)精通 C 和 Rust 語言的開發(fā)者來深入研究相關(guān)的架構(gòu)和協(xié)議,來推動(dòng)項(xiàng)目進(jìn)展。現(xiàn)實(shí)卻是缺乏這樣的開發(fā)者。
因此,由于預(yù)計(jì)無法在短中期內(nèi)完成 hpyer 工作,并且保留代碼的成本實(shí)在太高,只能通過削減這些代碼來提供靈活性并降低復(fù)雜性。
雖然 hyper 的實(shí)驗(yàn)本身失敗了,Stenberg 認(rèn)為他們從中吸取了一些教訓(xùn),并在過程中改進(jìn)了 curl。其實(shí)在 2020 年開始 hyper 項(xiàng)目的時(shí)候,Rust 語言本身并沒有準(zhǔn)備好。隨著時(shí)間的推移,Rust 現(xiàn)在已經(jīng)有所改進(jìn),成為一種更好的語言,并可以為類似 hyper 的項(xiàng)目提供更好的服務(wù)。
另外,在拋棄 hyper 之后,curl 仍然有兩個(gè) Rust 編寫的實(shí)驗(yàn)性后端支持,分別是 rustls(用于 TLS)和 uiche(用于 QUIC 和 HTTP/3)。這兩個(gè)后端在 crul 中使用了更好的內(nèi)部 API,并以更干凈的方式掛接到 libcurl 中,因而相較于 hyper 更易于支持,負(fù)擔(dān)也更小。
目前,hyper 的超級(jí)后端代碼已從 git 中刪除,并且 2025 年 2 月發(fā)布的 curl 8.12.0 版本中將不會(huì)留下任何痕跡。
不過,雖然 hpyer 被移除了,Stenberg 對(duì)未來引入 Rust 或其他語言編寫的安全后端持開放態(tài)度。未來會(huì)采用一些不一樣的做法,畢竟與 2020 年開始 hyper 時(shí)相比,他們現(xiàn)在擁有了更好的內(nèi)部架構(gòu)。
無獨(dú)有偶,在 12 月初,另一個(gè)開源數(shù)據(jù)庫工具鏈項(xiàng)目 Prisma 也表態(tài)將從 Rust 遷移至 TypeScript,以追求更好的插件和擴(kuò)展生態(tài)。
聲明中寫道:Prisma 的架構(gòu)歷來限制社區(qū)貢獻(xiàn),其核心功能(例如查詢解析、驗(yàn)證和執(zhí)行)由 Rust 引擎管理,而這對(duì)于專注于 TypeScript 的社區(qū)來說是不透明的。因此決定將 Prisma 的核心邏輯從 Rust 遷移到 TypeScript,并重新設(shè)計(jì) ORM,以使定制和擴(kuò)展更容易。
近幾年 Rust 語言正在強(qiáng)勢(shì)崛起,在一些編程語言排行榜中的排名一直在攀升,比如 2024 IEEE Top 編程語言榜單中,Rust 的排名就很靠前。另外,用 Rust 取代 C 和 C++ 的呼聲也很高。
雖然 Rust 很強(qiáng)大且在安全性方面獨(dú)樹一幟,但它的學(xué)習(xí)成本也相對(duì)比較高。在一個(gè)關(guān)于「哪些原因阻止你在 2025 年學(xué)習(xí) Rust」的調(diào)查中,有人拋出了一個(gè)有力的觀點(diǎn):他最常用的 C/C++ 庫是同類中最好的,背后有數(shù)十年的開發(fā)經(jīng)驗(yàn)。對(duì)于 Rust,他要么費(fèi)盡心力地繼續(xù)使用它,要么使用一些隨機(jī)、不知名、沒有血統(tǒng)的包。也有人認(rèn)為,Rust 語法看起來很丑陋。
圖源:https://x.com/kai_fall/status/1875549570513658212
用了 18 個(gè)月,我滿滿的都是后悔
其實(shí),在 2024 年初,Medium 一篇文章講述了作者花費(fèi)了 18 月用 Rust 語言重建自己的算法交易平臺(tái)的過程。雖然費(fèi)了很多心思,但最終十分后悔。一起看看在這過程中,Austin Starks 到底經(jīng)歷了什么吧。
在文章開頭 Austin 就表示了他曾經(jīng)十分看好 Rust,甚至是 Rust 的狂熱愛好者。Rust 看起來似乎是目前最快的、最安全編程語言之一。當(dāng)然他發(fā)現(xiàn)不止自己一人這么認(rèn)為。如果在網(wǎng)上閱讀有關(guān) Rust 編程語言的文章,你很可能會(huì)遇到壓倒性的正面評(píng)價(jià)。每一篇 Medium 上的指南、每一篇 Reddit 上的帖子、每一個(gè) Stack Overflow 上的回答 —— 一切都在贊美它。
這是故事的開始,或者說是「噩夢(mèng)」的開始,Austin 決定放棄 TypeScript,將自己的整個(gè)開源算法交易系統(tǒng)重寫成 Rust。
其實(shí),這次不好的體驗(yàn)早有端倪。更早前,Austin 就寫過一篇關(guān)于使用 Rust 的經(jīng)歷。他當(dāng)時(shí)表示雖然非常喜歡 Rust 的速度和一些語言設(shè)計(jì),但并不完全真正喜歡這門語言。不過文章一經(jīng)發(fā)出,就遭到了猛烈的抨擊。甚至有一條高贊評(píng)論指責(zé) Austin 是用 ChatGPT 寫的文章。這顯然已經(jīng)是 AI 時(shí)代人們對(duì)文字創(chuàng)作最大的批評(píng)了。
Austin 進(jìn)行了反思,或許是自己沒有給予 Rust 足夠的機(jī)會(huì)。他決定再使用一段時(shí)間 Rust。使用過后,他終于能夠自信地給出結(jié)論:
這門語言就是糟透了?。?!
Rust 差在哪里?
Austin 用了幾個(gè)詞來形容來總結(jié)自己對(duì) Rust 的厭惡:糟糕、冗長(zhǎng)、難以理解的語法和語義。
一個(gè)復(fù)雜的 Rust 函數(shù)示例
Austin 吐槽道,說 Rust 語義不糟糕的人都是在撒謊。如果沒有一個(gè)非常強(qiáng)大的大型語言模型,在寫函數(shù)的時(shí)候就會(huì)有很多事情做不成。他不想花 90 分鐘去弄清楚 run_transaction 函數(shù)中的 where 子句。最終,他完全放棄了使用輔助函數(shù)的想法,因?yàn)楦緹o法讓代碼編譯通過。人們所說的 Rust 最大的優(yōu)點(diǎn)(嚴(yán)格的編譯器來消除錯(cuò)誤)反而是 Rust 最大的缺點(diǎn)。
Austin 舉了個(gè)例子,如果在 Go 中編寫這個(gè)完全相同的函數(shù),代碼大概會(huì)下圖這樣。雖然函數(shù)的核心結(jié)構(gòu)保持相對(duì)不變, 但代碼能直接按照預(yù)期運(yùn)行,不需要做過多復(fù)雜的調(diào)整、技巧或反復(fù)的嘗試。
Go 實(shí)現(xiàn)的函數(shù)
Rust 在錯(cuò)誤處理方面似乎有些優(yōu)勢(shì)。只要你避免使用不安全的 unwrap 來減少運(yùn)行時(shí)錯(cuò)誤(例如空指針異常),就可以確定代碼會(huì)運(yùn)行并持續(xù)運(yùn)行。真的是這樣嗎?Austin:不!
他指出當(dāng)數(shù)據(jù)出錯(cuò)或發(fā)生意外時(shí),開發(fā)者很難快速診斷問題,因?yàn)殄e(cuò)誤信息往往不夠直觀,開發(fā)者可能很難弄明白錯(cuò)誤的根本原因。他自嘲,可能自己沒有找到啟用堆棧跟蹤的正確方法,這讓調(diào)試變得更加困難。
Austin:我的堆棧跟蹤在哪兒???
相比之下,Python 能夠提供堆棧跟蹤,精確告訴你發(fā)生了什么,甚至到行號(hào)。Austin 表示,就算是 Go 語言,也有 errors.Wrap (...),讓你能夠查看整個(gè)錯(cuò)誤堆棧。顯然,這是 Rust 的設(shè)計(jì)缺陷。
除了 Rust 的設(shè)計(jì)缺陷,社區(qū)氛圍也是難評(píng)。Austin 表示,社區(qū)不能接受別人提出 Rust 有缺陷這個(gè)觀點(diǎn)。發(fā)表的看法會(huì)遭到攻擊,提出的問題也只能收獲陰陽怪氣。
Austin 在 Rust 社區(qū)中收到的「有用」回復(fù)