爲什麼我說Rust是靠譜的編程語言

爲什麼我說Rust是靠譜的編程語言

作者:Liigo(莊曉立)
時間:2015年5月16日
原創鏈接:http://blog.csdn.net/liigo/article/details/45757123
版權聲明:未經作者許可不得轉載;授權轉載需註明出處。


2016年2月22日修補說明:本文最初發表至今已逾半年,這期間Rust語言蓬勃發展,版本從1.0升級到了1.6(1.7也近在咫尺),變化很大。現借《程序員》雜誌3月刊發行之際對原文做一些修訂和增補,其中增補部分在文中有明確標記。


序言:本文試圖幫您解答“我要不要(投入大量時間和精力)學習Rust語言?”這個問題。作者儘量較少的談及Rust語言本身,反而嘗試從Rust語言周邊入手,長時間、大範圍、多角度地考察,研判Rust語言是否靠譜,並給出儘可能客觀的理由。爲寫成本文,作者Liigo不惜“臥底”Rust“老巢”長達一年多,收集整理總結了大量信息。如果嫌長,可以只看小標題,粗略瀏覽一番。


1. Rust編程語言

Rust(blog)是一門強調安全、併發、高效的系統編程語言。其中四個關鍵詞,系統編程、安全、併發、高效,是Rust語言的核心特徵,也是區別於其他編程語言的首要因素。

  • Memory safety without garbage collection

  • Concurrency without data races

  • Abstraction without overhead

除此之外,我再補充一些關鍵詞,以便讀者更直觀地瞭解Rust:靜態類型/編譯式語言/靜態編譯/動態編譯、泛型/函數式/面向對象、模式匹配/ADT、DST/Associated Types/閉包(Closures)、Static/Dynamic/Multiple-Dispatch、 沒有虛擬機(VM)、沒有垃圾收集器(GC)、沒有運行時(Runtime)、沒有空指針/野指針/內存越界/緩衝區溢出/段錯誤、沒有數據競爭(Data Race)……

Rust語言具有特性豐富、設計優良、適用範圍廣等諸多優點。

我(Liigo)從2013年底開始正式關注Rust項目,……至今有一年半了。其中有贊有批,有爭有鬧,也有貢獻源碼。本文所寫的是我這些日子以來的所看、所聞、所感。

判斷一門新的編程語言“是否靠譜”,是主觀性很大的課題。Rust語言今日纔剛剛發佈1.0版本,它的未來發展走向如何,誰也說不清楚,說到底都是猜測。但是直覺告訴我,如果人靠譜、團隊靠譜、技術能力靠譜、態度靠譜、社區靠譜,這個項目在很大程度上就是靠譜的、值得期待的。

謹以此文,獻給我長久期待的 Rust 1.0


2. 開放、友好、高效的開源社區

相當徹底的開源項目,開放、透明、友好,進度熱火朝天,動作大刀闊斧。這是我第一次親身參與並觀察到的如此大規模的開源編程語言項目的開發過程。(之前也關注過Go語言項目,但其規模要小得多。)

  • 開放源代碼、GitHub/Git在線開發 https://github.com/rust-lang/rust

  • 開放系統設計過程,重要設計項目的提出、討論、評估、決策均在線進行(RFCs)

  • 內部決策過程也公開透明,每週發佈會議記錄(meetimg-minutes)

  • 公開接受第三方開發者提交的 Pull Requests,必要時還指導開發

  • 有一個核心團隊(the core team)負責項目的發展方向和最終決策

  • 有大量的(超過 1000 人!)第三方開發者給Rust貢獻源代碼、文檔和測試用例

  • 多次將優秀的第三方開發者吸納進入官方開發團隊和核心團隊

  • 多次在世界各地(包括北京)主辦和協辦小型本地開發者見面會

  • IRC,internals,Reddit/r/rust,HN(Hacker News), StackOverflow有許多跟Rust相關的技術討論,常見核心開發者參與其中

  • Github上用Rust語言開發的項目也風風火火(詳見下文)

熱火朝天”,用於形容其工程量大、進度快、成效顯著。看看Rust的 Release Notes,常見這類字眼:

  • Version 1.0.0 (May 2015): ~1500 changes, numerous bugfixes

  • Version 1.0.0-alpha.2 (February 2015): ~1300 changes, numerous bugfixes

  • Version 1.0.0-alpha (January 2015): ~2400 changes, numerous bugfixes

  • Version 0.12.0 (October 2014): ~1900 changes, numerous bugfixes

  • Version 0.11.0 (July 2014): ~1700 changes, numerous bugfixes

  • Version 0.10 (April 2014): ~1500 changes, numerous bugfixes

  • Version 0.9 (January 2014): ~1800 changes, numerous bugfixes

  • Version 0.8 (September 2013): ~2200 changes, numerous bugfixes

  • …​…​

還有很多就不一一列出了。Rust自從2012年1月20日發佈0.1版,到現在的1.0正式版,平均每隔三個月發佈一版,每次升級改進都多達一兩千項。 Rust是在GitHub/Git上在線開發的,開發者對源代碼的每一項改動(commits)都被版本管理系統記錄在案,有據可查。 大多數是實質性的功能升級,不存在靠修改標點、配置文件、拼寫錯誤、或者每改三五行代碼就提交的湊數行爲(在此嚴重鄙視Atom編輯器、Kotlin語言)。 反而常見動不動就 甚至 行 Rust 代碼的情況,

有一個網站叫 "This Week in Rust",每週進展公告,專門介紹Rust語言最近一週的最新重大變動,可供大家參考。裏面的內容雖然不全,但頗有代表性。這個網站幾經變遷,但是自2013年6月上線時起,兩年來,作者cmr堅持每週更新,幾乎從未中斷。

總之我(Liigo)說Rust的開發“熱火朝天”,一點也不誇張。(我還要順便鄙視Apple公司,發佈某某OS新版的時候,動不動就說“新增1500項API”,哎,咱還就較真兒了,去查,算上所有Function、所有Type、Type內的所有Method、所有常量定義—— #define XX 123,你懂的 ——勉強夠數!跟Rust的 "~1500 changes" 相比,天上人間。)

大家可以比照近十年在中國大陸和近兩年在南中國海的大型基建項目的進展速度,體會Rust那種熱火朝天的開發場面。處於這樣的開發環境下,所有人都深受鼓舞,所有人都知道,一切都會越來越好,知道所有的欠缺和困難都是暫時的。行動永遠比語言有說服力。

大刀闊斧”,用於形容其開發行爲豪邁、乾脆,持續追求“更好的設計和實現”,無包袱、無遷就。 只要有了更好的設計(或實現),經過深入討論和評估之後,果斷替換掉舊的設計(或實現)。 不管這項改動有多複雜、多麻煩,也不理會因此形成的大量不兼容性,勇往直前的行動。 說去胳膊就去胳膊,說卸腿就卸腿,就是眼睛它也敢摘下來鑲個火眼金睛再裝回去。牽一髮而動全身的事情,幹了可不止一次。 例子有很多,最典型的是libgreen,之前Rust靠它一條腿走路,後來有了libnative,兩條腿走路,再後來全都砍掉,最終做到沒有運行時(Runtime)。 其他的例子還有std::io/os/path的大型重構(I/O OSPath Reform),重新設計然後無縫替換回去(有rustc、servo爲證),可謂自己給自己做了大型手術。 一個新興的項目,在真正面世之前的開發過程中,如果不經歷幾次這類大的陣痛,很難說它最終是成熟的和久經考驗的。 如果因爲各種顧慮而遷就、保留舊的設計(或實現),很難說最終的產品是完善的和設計優良的。 如果面世之前都不肯改進,面世定型之後改進的可能性就更小了(束手縛腳),缺陷可能伴隨終生,令所有的用戶長期的糾結。 (這種大刀闊斧,與我(Liigo)當年在易語言公司參與研發EF語言時我所主張並踐行的觀點一致。有意推遲發佈1.0也是爲了給完善產品留足充裕的時間。)

需要強調的是,Rust開發者大刀闊斧的日子,只發生在Rust 1.0正式版發佈之前。1.0之後,他們將老老實實的遵守 SemVer 2.0 規範,再也不會輕易做出破壞代碼向後兼容性的行爲。本文後面還會談到這一點。


3. 十年勤耕不輟、低調做人高調做事

2006年,創始人Graydon Hoare啓動了Rust編程語言項目,利於業餘時間開發了三年,完成Rust語言的第一個可用版本。早期的Rust編譯器 rustboot 是用OCaml語言開發的。這三年間發生的事情,我們現在知道的並不多。根據創始人對Rust的命名,可以一窺其設計初衷:

我從很多名稱中挑選出了"Rust"。主要受到病原菌的啓發——那些令人驚訝的、生死輪迴的、多源寄生的奇妙物種。而且"Rust"還有其他內涵:它很好地契合了“貼近金屬”(bare metal)、“復古編程語言技術”的主題;它從字面上融合了"Trust"(信任)和"Robust"(健壯)。 —— Graydon Hoare

2009年,Rust項目被Graydon Hoare贈送給(英文原文"was presented to")Mozilla公司,並得到持續活躍地開發支持。Mozilla創建了以Graydon爲首的專業團隊全職開發Rust,並且開放源代碼。

2010年至2011年,Rust語言的編譯器被用Rust語言重寫,完成自舉,採用LLVM作爲編譯後端——之前的Rust編譯器是用OCaml語言編寫的。

2012年1月發佈0.1版,第一個面向公衆的預覽版本問世。從那時起,平均每3個月發佈一個新版本,版本號每次只加0.1,改動的內容卻往往天翻地覆。2012年到2015年這三年多的時間裏,開發者持續不斷的改進Rust語言、編譯器和標準庫,翻新重修,精益求精。不斷地否定自己,不斷地超越自己,一步一個里程碑。

2012年2月,也就是Rust 0.1剛剛發佈不久, Servo項目被創建,用Rust語言開發下一代瀏覽器引擎,目的在於驗證Rust語言開發大型實用項目的能力。

2012年到2015年這三年多時間,Rust和Servo互相扶持着茁壯成長起來了。Mozilla公司在Rust和Servo這兩個不盈利的開源項目上付出的大量人力物力財力和時間成本,體現了他們全力打造下一代全新系統編程語言的決心和氣魄。但是他們很少花費精力在大規模宣傳和營銷上,導致大部分公衆/開發者幾乎從沒聽過Rust語言,僅靠長期的口碑相傳吸引了一批慧眼識金的忠實的開發者。

Rust不是富二代也不是官二代,它沒有一個有錢或有權的爹。Mozilla公司,論資金規模和影響力,遠遠不及Google、Apple、Microsoft,勉強算是二流公司,但是它依然給予了Rust長期的堅定的支持。

歷經近十年精心打造,Rust靠自身實力贏得未來。2015年5月16日,Rust正式發佈1.0版本,破繭成蝶,吹響進入新時代的號角。


4. 定位精準而潛力廣泛的應用領域

現今的軟件系統開發,從底層到中層到上層,大致分爲以下三個層次:

  • (底層)系統底層開發:裸金屬(bare metal)、操作系統(OS)、內核(kernel)、內核模塊(mod)等

  • (中層)系統應用開發:虛擬機(VM)、容器(Container)、數據庫/遊戲/Web/Ftp/Dns服務器、瀏覽器引擎、模擬器等

  • (上層)普通應用開發:編譯器、瀏覽器、消息推送系統、Web應用系統、管理信息系統、其他等等

其中,(底層)系統底層開發,強調對底層硬件的控制;(中層)系統應用開發,對CPU和內存的佔用十分敏感;(上層)普通應用開發,更傾向於方便快捷的開發效率。通常意義上所說的“系統編程”,往往是指中底層系統開發。

Liigo認爲,Rust語言足以勝任這三個層次的軟件開發。理由是:Rust是靜態類型的編譯式語言,基於LLVM生成高度優化的代碼,再加上沒有垃圾收集器(GC)等額外的運行時開銷,執行效率非常高,對內存的利用十分靈活,因而勝任(中層)系統應用開發;Rust具有豐富的語言特性,便捷的項目編譯和依賴管理,充分可用的跨平臺的標準庫,因而勝任(上層)普通應用開發;Rust支持raw pointer、unsafte block、C ffi、asm!、No runtime,因而勝任(底層)系統底層開發。Rust語言特別強調並保證的內存安全,對於三個層次尤其是中底層,是額外的突出的加分項。

上面的論述偏向於理論,可能不如實踐有說服力。下面我們看看現實中Rust已經做到了什麼程度(不是能做什麼,而是做了什麼,咱們靠事實說話):

早在2013年我(Liigo)開始關注Rust之前,那時候Rust還有可選的GC,還有不算小的Runtime,還有笨重的標準庫。即使在那種情況下,都有人不斷地嘗試用Rust做底層開發(參見前面的鏈接)。後來,Rust有了幾個大的動作,令其更加勝任系統底層開發工作:

Rust是名副其實的系統編程語言,在這個領域,它不懼怕跟任何對手競爭。向下,Rust可取代C語言地位;居中,Rust可挑戰C++市場,向上,Rust可向Java、Python分一杯羹。總之,Rust精準定位於中底層系統應用開發,上可攻下可守,適用範圍相當廣泛,具有全能型選手的潛質。開發者們學習Rust語言,不怕沒有用武之地。


5. 自舉(用Rust語言開發Rust編譯器)

Rust在2010年至2011年完成自舉,使用Rust語言開發出Rust編譯器rustc, 取代了之前用OCaml語言開發的Rust編譯器rustboot。Rust標準庫,很早就是Rust語言寫的。這意味着,早在四年前,Rust早期核心開發人員,就已經是全職的Rust程序員了,一天八小時,幾乎完全使用Rust語言編程:用Rust開發標準庫(和其他庫),用Rust調用標準庫開發編譯器,用編譯器編譯標準庫和編譯器。等到1.0發佈時,他們已經是具有多年極其豐富的Rust開發經驗的程序員,這期間他們積累的大量設計開發經驗和教訓,無疑不斷地推進了Rust自身的迭代更新。

有人說:沒有必要自舉,不自舉不代表它沒有這個能力。這話說的沒有太大毛病。但是我們考慮如下兩點:

  • 1、自舉從事實上印證了它(編程語言+編譯器)具備這個(強大的)能力,不自舉只能在理論上保留它具有這個能力的可能性,兩者不在一個層面上,說服力孰強孰弱不言而喻。新語言在大規模推廣之前,往往欠缺這種說服力,進而導致推廣不利,陷入怪圈不能自拔。

  • 2、自舉過程中和自舉之後,核心開發者每天使用自己開發的語言工作(開發自己的編譯器),不斷的在實踐中鍛造,利於及早發現設計缺陷和不足之處,並及時解決;自舉之前,只能每天花費大量的時間和精力,使用其他編程語言開發和維護自己的編譯器,學習積累的都是別的語言的經驗和教訓,缺少在實踐中檢驗自己設計的語言的機會。如果自己設計的語言自己都不去深度地使用,又上哪裏獲取第一手的反饋信息呢,又如何改善呢。

所以自舉越早對編程語言自身發展完善越有利,最好是在自身定型之前儘早自舉。

在編程語言自身定型之前儘早自舉,這句話說起來容易,實施起來卻非常困難。語言不完善,某些功能就可能暫時沒法實現;語言不穩定,需要不斷的修正和改進,用它寫的編譯器也需要相應的大量的維護更新甚至重寫,是很大的工作負擔。所以很多新的編程語言的作者,不願意(儘早)自舉,相應地也就永久失去了自舉帶來的好處。

我(Liigo)舉兩個反例:

  • 第一個是Google公司的 Go語言,截止到2015年本文發表時,其編譯器和運行時庫,包括語言核心數據結構和算法map、channel、scheduler等等,還是用C語言開發的(補記:2015年8月1.5版本之後才替換爲Go)——他們的核心開發人員真正用自己開發的Go語言進行實際的大型應用開發的機會並不多。雖然標準庫是用Go語言自己寫的,但他們卻沒有大範圍使用標準庫的經歷。實際上,他們缺少使用Go語言的實戰開發經驗,往往不知道處於開發第一線的用戶真正需要什麼,無法做到設身處地爲程序員着想。缺少使用Go語言的親身經歷,也意味着他們不能在日常開發中,及時發現和改進Go語言設計上的缺陷和不足。

  • 第二個反例是中文編程的翹楚 —— 易語言,它的編譯器、核心支持庫、集成開發環境(IDE),和絕大多數支持庫,都是用C語言或C++語言開發的,他們的主要開發人員,包括創始人吳濤在內,每天的工作是熟練編寫大量C/C++代碼,寫易語言代碼的機會少之又少,即使有也是寫一些調用支持庫的示例這類淺嘗輒止的代碼。事實上在易語言研發部,只有莊曉立(Liigo)、袁曉輝(海洋)、龔闢愚(GBB)等少數幾位開發者具有較深的易語言功底,其他開發人員進入研發部之前甚至都沒聽過易語言。吳濤本人早年還寫過一些較大的易語言程序,代表作是俄羅斯方塊(代碼多達500行),後期也很少寫了,偶爾寫一些Sample代碼作爲支持庫的示例(往往不超過100行)。易語言公司裏寫易語言代碼最多的應該是項目教育培訓等部的史世恆、潘春華、季翔、王軍、張志恆他們。後來易語言暴露出來一些大的設計缺陷,已經不好修復了,除非傷筋動骨地翻修(放棄向後兼容性)。再後來吳濤組織團隊又開發了全新的編程語言“易語言.飛揚”(EF),發佈之前用EF語言開發了自己的集成開發環境(IDE),是一大進步,但依然沒有完成自舉。後來聽說吳濤自己一個人在搞3D遊戲引擎(Volcano3D),氣場強大,希望推出真實的遊戲(而非demo)檢驗其優秀品質。

而Rust語言,偏偏克服了諸多困難,提前4年完成自舉,成爲是最成功的案例之一,充分的享受了自舉的好處,不斷地在實踐中完善了自身的設計。

沒有深度的實踐,就沒有優秀的設計。除了自舉,Rust還有其他的深度實踐。


6. 兩個半"大型成功案例": servo, rustc+std, cargo

(作者Liigo注:本節以下有關代碼行數的數據於2015年7月30日得到修正,詳情另見《關於Servo項目中Rust代碼行數的數據來源》一文。)

  • Servo: 下一代瀏覽器渲染引擎(類Webkit/Blink),超過25萬行Rust代碼

Servo是Mozilla公司另外一個獨立開發組的項目,啓動於2012年初,跟Rust並行開發。多年來,在Rust語言從幼年到少年逐步成長、長期劇烈變動的情況下,Servo居然還能保持正常開發進度,實屬不易。Patrick Walton在Servo開發組和Rust開發組都是核心程序員,Servo組的Lars Bergstrom經常參加Rust組的每週會議,這保證了兩部門的有效溝通。Rust組經常會優先協助解決Servo組遇到的問題,維持Servo開發任務正常推進。

對於Rust而言,Servo項目存在的最大意義就是,它實踐並印證了Rust語言具有實際的大中型項目開發能力(而不僅僅停留在理論上),同時獲得了珍貴的設計開發經驗和教訓,反過來進一步促進了Rust自身的發展。Rust語言和標準庫逐步發展到今天,許多優秀的設計得以引進,許多有缺陷的設計得以改良,都要感謝Servo這類大型實踐項目,在Rust 1.0之前就已經長期存在。試想,如果Rust定型之後才啓動Servo項目,實踐中發現語言的重大設計缺陷又能怎樣,反正木已成舟,悔之晚矣。

Servo已經通過了 Acid2 標準測試;可以 併發渲染 Github/Reddit/CNN 這類大型靜態網頁,性能 明顯高於 當前的Firefox瀏覽器的Gecko引擎;可以無縫替換基於Chrome的CEF 框架;已經實驗性的應用在Firefox OS平臺(b2s)。2015年將發佈測試版瀏覽器。Servo有機會成爲瀏覽器歷史上里程碑式的產品。

  • rustc+std: Rust編譯器和標準庫,超過30萬行Rust代碼

時至今日,rustc負責編譯全世界所有的Rust源代碼,包括rustc+std的30萬行和servo的25萬行,以及crates.io網站上的2000多個第三方庫,是名副其實的大型成功項目。

  • Cargo: Rust的package管理器,項目依賴管理

代碼量相比前兩者而言要小的多,所以我算它是半個成功案例。代碼雖少,但實用性、流行度有過之而無不及。全世界大約99%的Rust項目採用Cargo編譯。crates.io網站上有2000多個包,總下載量超150萬次。Cargo最大幅度地簡化了Rust項目的編譯和依賴管理,可以說是目前開發Rust項目的必備工具。


7. 十分重視並認真對待1.0版本

Rust 1.0被開發者視爲第一個穩定可靠的可用於生產環境的正式版本。也就是要承諾:現有的大部分語言特性和標準庫API要穩定下來,以後不能輕易改變,非得要變得話也得保持向後兼容;功能上要基本全面,至少要滿足基本的軟件開發需求,不能有明顯的欠缺;質量上要有可靠性保證,不能動不動就這裏有問題那裏有問題。此外,還要給語言將來的發展留足餘地。官方博客Road to Rust 1.0 對於 1.0 有詳細的闡述。

任何認真的新編程語言面臨“何時發佈1.0版”這個問題時都會感到糾結。發佈的越早吧,初級產品沒經過多少實際檢驗,用戶量一上來用的人多了,很可能爆出基礎設計缺陷,不得已大幅翻修,導致口碑不佳,然後無人問津,項目就算失敗了;發佈的越晚吧,影響力小用戶量一直上不去,也得不到太多實際檢驗,始終達不到1.0的水平,可能就一直默默無聞下去了。Rust在1.0發佈時機上把握的還算比較到位:誕生快十年,高速發展三五年,吸引了一大批用戶,自身也經過的“兩個半”大型項目的實際檢驗。要說早,肯定是不早了。Rust沒有盲目的早早發佈1.0(例如在2012年),是因爲他們對1.0期待很高,他們對自己要求很高,他們心裏有一杆秤。因爲他們是認真的。

爲了在2015年5月保質保量發佈Rust 1.0,他們提前做了哪些工作?

7.1. 標準庫API的穩定性

Rust爲標準庫內所有API,即所有fn、所有type(struct/enum/trait)、所有method、所有impl、所有const/static、所有macro_rules!,都逐一標註了穩定性標籤:stable、unstable或deprecated。並且聲明,1.0版本內包含的所有stable API,都將在SemVer 2.0規範下得到向後兼容性保證,今後所有1.x版本都不會破壞其穩定性(除非遇到重大BUG不得已而爲之)。

我們去查Rust開發組公開的會議記錄,會發現在2014年6月23日到10月1日,共有8次API review專題會議(01234567),逐一審查確定各API的穩定性標籤。此後更長的時間裏,又不定期的將更多API標註爲stable或unstable/deprecated,在rust repo裏搜索"stabilize" 可以得到大批提交記錄,顯示出這項系統工程顯然不是一朝一夕所能完成的。

目前標準庫名下stable API大約有2500條,佔總數的80%。新生編程語言中能做到這個程度的,很少見。


增補:針對穩定版API的修改,怎樣的修改是向後兼容的、怎樣的修改是破壞兼容性的呢? RFC #1105 給出了非常詳盡的說明和指導。而且Rust還有一個叫Crater的工具,負責檢測某項修改是否破壞了兼容性,其工作原理是,藉助集成測試環境,以該項修改爲基礎構建臨時Rust工具鏈,用之逐一編譯crates.io網站上的三千多個Rust開源項目,只要有一個不通過,就說明該項修改存在破壞兼容性的可能。許多代碼提交後首先要經過Crater的檢驗纔可能被正式接納(案例:PR #29498 PR #30796 )。

增補:Rust在1.0發佈之前籌劃實施了類似Chrome的滾動式版本升級計劃(RFC #507)。nightly版本6周後升級爲beta版本,beta版本6周後升級爲stable版本。新提交到創庫裏的代碼,必然經過nightly和beta兩個週期,經過總共約12周的測試和過渡期,纔會正式進入stable版本。許多核心開發者都是基於nightly版本工作的,還有很有用beta版本的開發者,再加上完善的travis-ci測試,基本可以保證在stable發佈之前發現並修正存在的問題,確保stable版本的可靠性。

7.3. 精益求精的類型系統設計

7.4. 精益求精的文檔和代碼複審

7.5. 1.0之後的開發計劃

1.0是起點而不是終點,1.0之後Rust還將持續不斷地開發新的語言特性,打造更完善的標準庫。

核心開發者Niko Matsakis在今年4月份發表 Priorities after 1.0 一文,詳細闡述了1.0之後的開發任務、計劃、優先級,內容很多卻安排有序,體現了他們對這些問題的深度思考。此文在開發者社區中引起強烈反響,獲得熱烈討論。Niko還發表了系列博客文章的第一篇"Virtual Structs Part 1: Where Rust’s Enum Shines"


8. 精心設計的規範透明的開發流程

在2014年3月之前,Rust開發組並沒有十分規範的開發流程,基本過程是這樣:修改代碼,提交PR,Review,Merger。這樣導致的問題是,沒有形成設計文檔,一旦遇到較大規模的代碼改動,別人想理解他的設計思路,首先要讀懂他的代碼,這給方案評估、代碼評審製造了困難,而且容易形成無人理解或難於維護的代碼。

從2014年3月開始,Rust引入了規範化的RFC流程。規定,對語言重大改動之前,需先提交RFC文檔,寫明包括意圖、詳細設計、優缺點等在內的完整技術方案,供社區集體討論,最後提交到Rust核心開發組每週的專題會議上評估審覈,獲得批准之後才進入實施階段(代碼實現)。規範化RFC的好處是,首先形成了完整的技術文檔,利於集體討論、評估(進而優化方案),利於方案實施、後期維護,而且利於核心開發組主導項目進展方向。RFC流程實施一年來,在Rust發展過程中發揮了極其深遠的作用,先後通過了一大批十分重要的RFC,有力地推動了Rust語言的革新。

舉一個例子,說明社區會主動監督開發流程的規範性和透明度:2014年8月,官方人員aturon居然想偷偷摸摸地把unwrap方法改名爲assert, PR #16436: API conventions cleanup(80+),被網友發現(120+) 後引起極大爭議。爭議的起因是他們工作透明度不夠,事先公示(50+) 範圍不足,未得到充分討論。最終這一改動被迫撤消。


增補:1.0發佈前後籌備創建了Sub Teams,整合了各細分領域的開發專家,負責所屬領域的RFC設計、討論、評估、決策,令過程更專業化。之前的Core Team,只有少數幾位官方核心開發人員,地位相當於我黨的政治局常委會,技術、能力、威望都很牛逼,但隨着開發規模的擴大,他們自己也忙的團團轉,疲於參與呈爆發式增長的RFC,工作效率不高,況且他們未必在所有細分領域都是專家,一把抓並不理想。組建Language Design Team, Library Team, Compiler Team, Tooling and Infrastructure Team, Community Team, Moderation Team 等 Sub Teams之後,各自吸納了來自官方和民間的細分領域專家,可以更加專業化更有針對性的處理本領域的RFC,同時給Core Team節省出寶貴的精力去處理更核心的工作(Sub Teams有時上報某些重要RFC給Core Team決策)。參見RFC #1068

增補:1.0發佈後對每週技術例會(meetimg-minutes)做了較大調整。之前的慣例是,民間開發人員在RFC頁面上討論,然後Core Team開發人員在每週例會上討論並決策,最後公佈會議記錄。之後的慣例是,民間和官方人員一起在RFC頁面討論,然後Sub team閉門決策(必要時Core Team介入),最後公佈決策結果。調整之後,討論更民主化、透明化,決策更集中化,提升了工作效率。

增補:(2014年那時候,北京時間每週三凌晨Core Team發佈會議記錄,每週三就是我(Liigo)的節日,早上起牀看Core Team的技術討論和決策過程,持續了大約一年,現在還是美好的回憶。後來Sub Teams的會議記錄通常只剩下決策結果,沒有技術討論過程了,而且他們的發佈間隔也延長到兩週左右。)

增補:1.0發佈後爲RFC增設了 “Final Comment Period (FCP)” 窗口期,並及時公告,使得關注該RFC的開發者不會輕易錯過決策前的最後集中討論階段。這也是提供開發透明度的一項措施。同樣參見RFC #1068


9. 不拘一格聘請專業技術人員

Steve Klabnik之前寫過一篇介紹Rust的入門教程 Rust for Rubyists,文風娓娓道來,深得羣衆喜愛。2014年2月,Rust官方人員看重了他的文檔寫作才華,付費聘請 他全職爲Rust創作文檔。他的主要代表作是Rust官方的The Rust Programming Language(Rust Book),以及大量API Docs。因爲其卓越貢獻,steveklabnik目前已經成爲Rust核心開發組 八成員之一。

Tilde公司以前開發的Ruby包管理器Bundler在Ruby領域非常流行,其架構設計被實踐證實獲得成功。2014年3月,Rust官方 宣佈 聘請 Tilde公司的核心技術人員Yehuda Katz和Carl Lerche,全職爲Rust設計開發全新的開源的Cargo,目標是打造世界級的包管理器("a world-class package manager for Rust")。現在Cargo已經初步獲得了很大的成功,還在蓬勃發展中。因爲Yehuda Katz的卓越貢獻,他已經成爲Rust核心開發組 八成員之一。

深受好評的Rust學習示例網站 http://rustbyexample.com 的早期創建者 Jorge Aparicio(japaric) 後來被邀請加入 了(Mozilla公司的)Rust官方團隊。

meeting-minutes 裏面搜索 "Friend of the Tree" 或 "fott" 你會發現更多人陸續加入了Rust開發團隊。


10. 大規模的廣泛的社區參與

我上面列出的多是長期以來持續開發和維護的項目,這在Rust語言長期劇烈變動的情況下愈顯彌足珍貴。理智的人們不會無緣無故的花費大量時間和精力。許多忠實的第三方開發者長期地投資Rust項目,體現了他們對於Rust語言的熱愛和對其前景的看好。

10.1. 社區合力完成的項目(libextra, diagnostics):

10.1.3. 排錯語言手冊Issue #16676

10.2. 社區廣泛參與的大型技術討論:

10.2.1. inherents:

圍繞實現“繼承”這一語言特性,社區涌現出一批設計方案,一時間爭奇鬥豔。暫時沒有結果,最終決策要在1.0之後才能做出。(括號內是評論數,下同。)

10.2.2. scoped thread:

2015年4月11日爆出這個大BUG(Issue #24292),直接拷問Rust“內存安全”核心概念,當時距離1.0發佈已不足5周時間。要知道,剛剛一天前,std::thread::scoped()還被官博 當作既安全又典雅的優秀API的典型、滿懷驕傲地向全世界推介。是不幸,還是該慶幸?我認爲該慶幸,有機會消除一個隱患,而不是在不知情中帶着重大缺陷進入1.0。

官方人員一味的強調 Issue #24292 是個例,一味的強調“不保證析構函數務必執行”不違反內存安全,並不能消除羣衆心中的不安全感。在我看來,官方人員給出的解決方案(RFC PR #1066 #1084)一個是“頭痛醫頭”一個是“腳痛醫腳”,反而是民間技術人員提交的方案(RFC PR #1085 #1094)更接地氣,至少是朝羣衆期望的方向努力了。可能是1.0發佈日期逼近,實在沒有時間評估和實施其他方案,最終官方堅持通過了RFC #1066。這一次我給他們集體評負分。好在他們廣泛深入地參與了所有相關的討論,內部無爭議地做出了理性決策,結果未必壞。

10.2.3. mutable & unique:

Rust社區對於可變性(mutable)和唯一性(unique)的反思和爭議。所有這些話題,都引發了許多熱烈的討論和激烈的爭論,火熱程度空前。之前 reddit.com/r/rust 內評論數達到200+的極爲少見。

  • 先是RFC 58,DaGenix 要求把 &mut 改爲 &only(50+)

  • 再是 Nicholas 要求徹底取消mut,增加 unique(240+) 引用

  • 還有pcwalton發出的 追問(180+):誰表達更清晰,可變性(mutability)還是唯一性(uniqueness)?

10.2.4. others

  • int/uint ⇒ isize/usize:

  • integer overflow:

  • reddit/HN hot posts:

  • Rust中文社區(rust.cc),新手QQ羣(303838735)

大量的、廣泛的、深入的社區技術討論,體現了人民羣衆積極參與Rust開源項目的熱情。多個體、多角度、多出發點的爭論,有利於參與者充分認清同一個技術問題,有利於鑑別各方案的優缺點,有利於折中優選最佳可行方案。優質社區是Rust發展的基石。

當多方爭論不相上下的時候,我們發現,Rust擁有一個堅強的核心團隊(the core team),總是會應急出面,充當主心骨,做出最終的理性決策,避免出現互相扯皮卻始終一事無成的最壞結局。他們的實力是有目共睹的,他們的信譽是逐步贏得的,他們做出的選擇,不一定是最優的,但一定也不差。



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

全文完,感謝!(翻頁到這裏也不容易呀,順便吐個槽吧:)~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~




發佈了275 篇原創文章 · 獲贊 442 · 訪問量 244萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章