想要改變世界的Rust語言

一門編程語言就像一個小宇宙,語言中的各種語法概念就像一顆顆星辰。對於初學者來說,看這些語法概念與看星羅棋佈時產生的迷惑是相似的。幸虧編程語言是由人類創造的,編程語言的作者可以被找到,編程語言的源碼也可以被看到,甚至一些好的編程語言還會爲你準備好非常豐富的文檔,供你參閱學習。通過這些信息我們可以瞭解到:一門語言緣何誕生?它想解決什麼問題?它遵循什麼樣的設計哲學?一門好的語言是有內涵哲學的語言,它表裏如一,有所想,有所爲。

Rust語言就是這樣一門哲學內涵豐富的編程語言。通過了解Rust遵循什麼樣的設計哲學,進一步瞭解它的語法結構和編程理念,就可以系統地掌握這門語言的核心,而不至於在其紛繁複雜的語法細節中迷失。

引言

世界在變化,但不會如你想象那般迅速,所以你需要仔細觀察。

今年7月發生了兩件不大也不小的事,讓Rust語言開始走進了大衆的視野。

第一件事,7月4日,社交網絡巨頭Facebook聯合其他100個行業巨頭,對外宣佈準備建設Libra(天秤座)項目。該項目的技術特點是:構建於區塊鏈技術之上,並且基於Rust實現。

構建於區塊鏈技術之上,說明Facebook等巨頭認爲下一代金融世界是建立在區塊鏈的基礎上,因爲區塊鏈是信任的未來。選擇使用Rust語言來構建Libra的區塊鏈基建,是因爲Rust語言能夠幫助開發者實現這份信任。 In Rust, We Trust。

第二件事,7月18日,微軟安全響應中心(MSRC)發文宣稱:我們需要更安全的系統編程語言。並且在後面的系列文章中逐步探討,爲什麼微軟認爲 Rust 語言目前是業界的最佳選擇。

微軟的這一系列文章,看樣子比Facebook的Libra項目更加吸引眼球。大家都認爲微軟要計劃使用Rust了,但其實微軟早已在內部使用Rust,比如Azure IoT Edge項目,已經在GitHub開源。再比如現在Rust社區流行的Web開發框架actix-web,就是由微軟的工程師Nikolay開發,用於Azure平臺內部。

微軟安全響應中心是一個專門負責接收和處理微軟安全相關漏洞報告的部門。早在今年2月,該部門的工程師在以色列舉行的BlueHat安全會議上就曾發表過一篇演講《微軟:70%的安全漏洞都是內存安全問題》。時隔半年左右,該部門官方博客纔開始對外宣告Rust應該成爲業界的最佳選擇。這說明微軟經過深思熟慮才得出這一結論。

今年2月的演講,還在Reddit上引起了一番爭論。其中的一個主流觀點是:不是編程語言的問題,而是寫代碼的人水平不夠,纔出現這種安全問題。然而,沒有程序員是全能的,Rust編譯器捕獲的錯誤,有可能超出程序員的經驗之外。難道開車上路,有更好的司機,就不需要安全帶了嗎?非也。我們需要像Rust這樣帶有安全防護的語言來防止錯誤。

以上兩件事,只是你“看得見”的影響較爲廣泛的事,你可能因此而剛剛得知Rust這門語言,但其實已經有很多公司引入了Rust語言。國外有Amazon、Google、Facebook、Dropbox等巨頭,國內有阿里巴巴、知乎、Bilibili、PingCAP、祕猿等公司。

所以,這些先行者們,到底爲什麼選擇Rust呢?難道他們都是新技術的狂熱粉嗎?這一問題的答案,正是本文想要告訴你的。

1.1  緣起

任何一門新技術的興起,都是爲了解決一個問題。

自操作系統誕生以來,系統級主流編程語言,從彙編語言到C++,已經發展了近50個年頭,但依然存在兩個難題:

  • 很難編寫內存安全的代碼
  • 很難編寫線程安全的代碼

這兩個難題存在的本質原因是C/C++屬於類型不安全的語言,它們薄弱的內存管理機制導致了很多常見的漏洞。其實20世紀80年代也出現過非常優秀的語言,比如Ada語言。Ada擁有諸多優秀的特性:可以在編譯期進行類型檢查、無GC式確定性內存管理、內置安全併發模型、無數據競爭、系統級硬實時編程等。但它的性能和同時期的C/C++相比確實是有差距的。那個時代計算資源匱乏,大家追求的是性能。所以,大家都寧願犧牲安全性來換取性能。這也是C/C++得以普及的原因。

時間很快到了2006年,自稱“職業編程語言工程師”的Graydon Hoare(簡稱爲GH),開始開發一門名爲Rust的編程語言。

什麼是“職業編程語言工程師”?用GH自己的話說,職業編程語言工程師的日常工作就是給其他語言開發編譯器和工具集,但並未參與這些語言本身的設計。自然而然地,GH萌生了自己開發一門語言的想法,這門語言就是Rust。

“Rust”這個名字包含了GH對這門語言的預期。在自然界有一種叫作鏽菌(Rust Fungi)的真菌,這種真菌寄生於植物中,引發病害,而且號稱“本世紀最可怕的生態病害”之一。這種真菌的生命力非常頑強,其在生命週期內可以產生多達5種孢子類型,這5種生命形態還可以相互轉化,如果用軟件術語來描述這種特性,那就是“魯棒性超強”。可以回想一下Rust的Logo形狀(如圖1-1所示),Logo上面有5個圓圈,也和鏽菌這5種生命形態相對應,暗示了Rust語言的魯棒性也超強。“Rust”也有“鐵鏽”的意思,暗合“裸金屬”之意,代表了Rust的系統級編程語言屬性,有直接操作底層硬件的能力。此外,“Rust”在字形組合上也糅合了“Trust”和“Robust”,暗示了“信任”與“魯棒性”。因此,“Rust”真可謂是一個好名字。事實證明,Rust語言不僅僅是名字起得好。

圖1-1:Rust語言的Logo

GH 認爲,未來的互聯網除了關注性能,還一定會高度關注安全性和併發性。整個世界對C和C++的設計方式的青睞在不斷地發生改變。其實20世紀七八十年代涌現了很多優秀的語言,擁有很多優秀的特性,但它們的內存模型非常簡易,不能保證足夠的安全。比如Ada語言的動態內存管理雖然是高規格的安全設計,但還是引起了非常重大的安全事故(20世紀90年代,歐洲空間局阿麗亞娜五號運載火箭發射失敗,原因是Ada在將64位浮點數轉換爲16位無符號整數時,發生了溢出)。

所以,GH對這門語言的期望如下。

  • 必須是更加安全、不易崩潰的,尤其在操作內存時,這一點更爲重要。
  • 不需要有垃圾回收這樣的系統,不能爲了內存安全而引入性能負擔。
  • 不是一門僅僅擁有一個主要特性的語言,而應該擁有一系列的廣泛特性,這些特性之間又不乏一致性。這些特性可以很好地相互協作,從而使該語言更容易編寫、維護和調試,讓程序員寫出更安全、更高效的代碼。

總而言之,就是可以提供高的開發效率,代碼容易維護,性能還能與C/C++媲美,還得保證安全性的一門語言。 正因爲GH以這種觀點作爲基石,才使得今天的Rust成爲了一門同時追求安全、併發和性能的現代系統級編程語言。

GH確實找對了本質問題——互聯網發展至今,性能問題已經不再是其發展瓶頸,安全問題纔是阻礙其發展的“重疾”。但憑什麼說Rust就能解決這個問題呢?

1.2  設計哲學

爲了達成目標,Rust語言遵循了三條設計哲學:

  • 內存安全
  • 零成本抽象
  • 實用性

也就是說,Rust語言中所有語法特性都圍繞這三條哲學而設計,這也是Rust語言一致性的基礎。

1.2.1  內存安全

安全是Rust要保證的重中之重。如果不能保證安全,那麼Rust就沒有存在的意義。Rust語言如何設計才能保證安全呢?

現代編程語言早已發展到了“程序即類型證明”的階段,類型系統基本已經成爲了各大編程語言的標配,尤其是近幾年新出現的編程語言。類型系統提供了以下好處:

  • 允許編譯器偵測無意義甚至無效的代碼,暴露程序中隱含的錯誤。
  • 可以爲編譯器提供有意義的類型信息,幫助優化代碼。
  • 可以增強代碼的可讀性,更直白地闡述開發者的意圖。
  • 提供了一定程度的高級抽象,提升開發效率。

一般來說,一門語言只要保證類型安全,就可以說它是一門安全的語言。簡單來說,類型安全是指類型系統可以保證程序的行爲是意義明確、不出錯的。像C/C++語言的類型系統就不是類型安全的,因爲它們並沒有對無意義的行爲進行約束。一個最簡單的例子就是數組越界,在C/C++語言中並不對其做任何檢查,導致發生了語言規範規定之外的行爲,也就是未定義行爲(Undefined Behavior)。而這些未定義行爲恰恰是漏洞的溫牀。所以,像C/C++這種語言就是類型不安全的語言。

Rust語言如果想保證內存安全,首先要做的就是保證類型安全。

在諸多編程語言中,OCamlHaskell是公認的類型安全的典範,它們的類型系統不僅僅有強大的類型論理粗體文本論“背書”,而且在實踐生產環境中也久經考驗。所以,Rust語言借鑑了它們的類型系統來保證類型安全,尤其是Haskell,你能在Rust語言中看到更多Haskell類型系統的影子。

然而,直接使用Haskell的類型系統也無法解決內存安全問題。類型系統的作用是定義編程語言中值和表達式的類型,將它們歸類,賦予它們不同的行爲,指導它們如何相互作用。Haskell是一門純函數式編程語言,它的類型系統主要用於承載其“純函數式”的思想,是範疇論的體現。而對於Rust來說,它的類型系統要承載其“內存安全”的思想。所以,還需要有一個安全內存管理模型,並通過類型系統表達出來,才能保證內存安全。

那麼,什麼是內存安全呢?簡單來說,就是不會出現內存訪問錯誤。

只有當程序訪問未定義內存的時候纔會產生內存錯誤。一般來說,發生以下幾種情況就會產生內存錯誤:

  • 引用空指針。
  • 使用未初始化內存。
  • 釋放後使用,也就是使用懸垂指針。
  • 緩衝區溢出,比如數組越界。
  • 非法釋放已經釋放過的指針或未分配的指針,也就是重複釋放。

這些情況之所以會產生內存錯誤,是因爲它們都訪問了未定義內存。爲了保證內存安全,Rust語言建立了嚴格的安全內存管理模型:

  • 所有權系統。每個被分配的內存都有一個獨佔其所有權的指針。只有當該指針被銷燬時,其對應的內存才能隨之被釋放。
  • 借用和生命週期。每個變量都有其生命週期,一旦超出生命週期,變量就會被自動釋放。如果是借用,則可以通過標記生命週期參數供編譯器檢查的方式,防止出現懸垂指針,也就是釋放後使用的情況。

其中所有權系統還包括了從現代C++那裏借鑑的RAII機制,這是Rust無GC但是可以安全管理內存的基石。

建立了安全內存管理模型之後,再用類型系統表達出來即可。Rust從Haskell的類型系統那裏借鑑了以下特性:

  • 沒有空指針
  • 默認不可變
  • 表達式
  • 高階函數
  • 代數數據類型
  • 模式匹配
  • 泛型
  • trait和關聯類型
  • 本地類型推導

爲了實現內存安全,Rust還具備以下獨有的特性:

  • 仿射類型(Affine Type),該類型用來表達Rust所有權中的Move語義。
  • 借用、生命週期。

藉助類型系統的強大,Rust編譯器可以在編譯期對類型進行檢查,看其是否滿足安全內存模型,在編譯期就能發現內存不安全問題,有效地阻止未定義行爲的發生。

內存安全的Bug和併發安全的Bug產生的內在原因是相同的,都是因爲內存的不正當訪問而造成的。同樣,利用裝載了所有權的強大類型系統,Rust還解決了併發安全的問題。Rust編譯器會通過靜態檢查分析,在編譯期就檢查出多線程併發代碼中所有的數據競爭問題。

1.2.2  零成本抽象

除了安全性,Rust還追求高效開發和性能。

編程語言如果想做到高效開發,就必須擁有一定的抽象表達能力。關於抽象表達能力,最具代表性的語言就是Ruby。Ruby代碼和Rust代碼的對比示意如代碼清單1-1所示。

  1. #Ruby代碼
  2. 2.5.times{ puts “Hello Ruby”}
  3. 2.days.from_now
  4. // Rust代碼
  5. 5.times(|| println!(“Hello Rust”));
  6. 2.days().from_now();
代碼清單1-1:Ruby代碼和Rust代碼對比示意

在代碼清單1-1中,代碼第2行和第3行是Ruby代碼,分別表示“輸出5次"Hello Ruby"”和“從現在開始兩天之後”,代碼的抽象表達能力已經非常接近自然語言。再看第5行和第6行的Rust代碼,它和Ruby語言的抽象表達能力是不相上下的。

但是Ruby的抽象表達能力完全是靠犧牲性能換來的。而Rust的抽象是零成本的,Rust的抽象並不會存在運行時性能開銷,這一切都是在編譯期完成的。代碼清單1-1中的迭代5次的抽象代碼,在編譯期會被展開成和手寫彙編代碼相近的底層代碼,所以不存在運行時因爲解釋這一層抽象而產生的性能開銷。對於一門系統級編程語言而言,運行時零成本是非常重要的。這一點,Rust做到了。Rust中零成本抽象的基石就是泛型和trait。

1.2.3  實用性

如何評價一門編程語言的實用性?事實上並沒有統一的說法,但可以從以下三個方面進行評判:

  • 實踐性,首先必須能夠應用於開發工業級產品,其次要易於學習和使用。
  • 有益性,是指能夠對業界產生積極的效果或影響。
  • 穩定性,是指語言自身要穩定。在解決同一個問題時,不會因爲使用者不同而出現隨機的結果。

那麼Rust語言在這三個方面的表現如何呢?

實踐性

Rust已經爲開發工業級產品做足了準備。

爲了保證安全性,Rust引入了強大的類型系統和所有權系統,不僅保證內存安全,還保證了併發安全,同時還不會犧牲性能。

爲了保證支持硬實時系統,Rust從C++那裏借鑑了確定性析構、RAII和智能指針,用於自動化地、確定性地管理內存,從而避免了GC的引入,因而就不會有“世界暫停”的問題了。這幾項雖然借鑑自C++,但是使用起來比C++更加簡潔。

爲了保證程序的健壯性,Rust重新審視了錯誤處理機制。日常開發中一般有三類非正常情況:失敗、錯誤和異常。但是像C語言這種面向過程的語言,開發者只能通過返回值、goto等語句進行錯誤處理,並且沒有統一的錯誤處理機制。而C++和Java這種高級語言雖然引入了異常處理機制,但沒有專門提供能夠有效區分正常邏輯和錯誤邏輯的語法,而只是統一全局進行處理,導致開發者只能將所有的非正常情況都當作異常去處理,這樣不利於健壯系統的開發。並且異常處理還會帶來比較大的性能開銷。

Rust語言針對這三類非正常情況分別提供了專門的處理方式,讓開發者可以分情況去選擇。

  • 對於失敗的情況,可以使用斷言工具。
  • 對於錯誤,Rust提供了基於返回值的分層錯誤處理方式,比如Option可以用來處理可能存在空值的情況,而Result就專門用來處理可以被合理解決並需要傳播的錯誤。
  • 對於異常,Rust將其看作無法被合理解決的問題,提供了線程恐慌機制,在發生異常的時候,線程可以安全地退出。

通過這樣精緻的設計,開發者就可以從更細的粒度上對非正常情況進行合理處理,最終編寫出更加健壯的系統。

爲了和現有的生態系統良好地集成,Rust支持非常方便且零成本的FFI機制,兼容C-ABI,並且從語言架構層面上將Rust語言分成Safe Rust和Unsafe Rust兩部分。其中Unsafe Rust專門和外部系統打交道,比如操作系統內核。之所以這樣劃分,是因爲Rust編譯器的檢查和跟蹤是有能力範圍的,它不可能檢查到外部其他語言接口的安全狀態,所以只能靠開發者自己來保證安全。Unsafe Rust提供了unsafe關鍵字和unsafe塊,顯式地將安全代碼和訪問外部接口的不安全代碼進行了區分,也爲開發者調試錯誤提供了方便。Safe Rust表示開發者將信任編譯器能夠在編譯時保證安全,而Unsafe Rust表示讓編譯器信任開發者有能力保證安全。

有人的地方就有Bug。Rust語言通過精緻的設計,將機器可以檢查控制的部分都交給編譯器來執行,而將機器無法控制的部分交給開發者自己來執行。Safe Rust保證的是編譯器在編譯時最大化地保障內存安全,阻止未定義行爲的發生。Unsafe Rust用來提醒開發者,此時開發的代碼有可能引起未定義行爲,請謹慎!人和編譯器共享同一個“安全模型”,相互信任,彼此和諧,以此來最大化地消除人產生Bug的可能。

爲了讓開發者更方便地相互協作,Rust提供了非常好用的包管理器Cargo。Rust代碼是以包(crate)爲編譯和分發單位的,Cargo提供了很多命令,方便開發者創建、構建、分發、管理自己的包。Cargo也提供插件機制,方便開發者編寫自定義的插件,來滿足更多的需求。比如官方提供的rustfmt和clippy工具,分別可以用於自動格式化代碼和發現代碼中的“壞味道”。再比如,rustfix工具甚至可以幫助開發者根據編譯器的建議自動修復出錯的代碼。Cargo還天生擁抱開源社區和Git,支持將寫好的包一鍵發佈到crates.io網站,供其他人使用。

爲了方便開發者學習Rust,Rust官方團隊做出瞭如下努力:

  • 獨立出專門的社區工作組,編寫官方Rust Book,以及其他各種不同深度的文檔,比如編譯器文檔、nomicon book等。甚至組織免費的社區教學活動Rust Bridge,大力鼓勵社區博客寫作,等等。
  • Rust語言的文檔支持Markdown格式,因此Rust標準庫文檔表現力豐富。生態系統內很多第三方包的文檔的表現力也同樣得以提升。
  • 提供了非常好用的在線Playground工具,供開發者學習、使用和分享代碼。
  • Rust語言很早就實現了自舉,方便學習者通過閱讀源碼瞭解其內部機制,甚至參與貢獻。
  • Rust核心團隊一直在不斷改進Rust,致力於提升Rust的友好度,極力降低初學者的心智負擔,減緩學習曲線。比如引入NLL特性來改進借用檢查系統,使得開發者可以編寫更加符合直覺的代碼。
  • 雖然從Haskell那裏借鑑了很多類型系統相關的內容,但是Rust團隊在設計和宣傳語言特性的時候,會特意地去學術化,讓Rust的概念更加親民。
  • 在類型系統基礎上提供了混合編程範式的支持,提供了強大而簡潔的抽象表達能力,極大地提升了開發者的開發效率。
  • 提供更加嚴格且智能的編譯器。基於類型系統,編譯器可以嚴格地檢查代碼中隱藏的問題。Rust官方團隊還在不斷優化編譯器的診斷信息,使得開發者可以更加輕鬆地定位錯誤,並快速理解錯誤發生的原因。

雖然Rust官方團隊做了以上諸多努力,但是目前還有一大部分開發者認爲Rust語言學習曲線頗陡。其中最爲詬病的就是Rust目前的借用檢查系統。這其實是因爲Rust語言的設計融合了諸多語言的特點,而當今大部分開發者只是擅長其中一門語言,對其他語言的特性不太瞭解。C語言的開發者雖然對底層內存管理比較熟悉,但是未必熟悉C++的RAII機制;即使熟悉C++,也未必熟悉Haskell的類型系統;即便熟悉Haskell的類型系統,也未必懂得底層內存管理機制。更不用說內置GC的Java、Ruby、Python等面嚮對象語言的開發者了。

要解決這個問題,可以從以下幾點出發來學習Rust:

  • 保持初學者心態。當面對Rust中難以理解的概念時,先不要急於把其他語言的經驗套用其上,而應該從Rust的設計哲學出發,去理解如此設計Rust的語言特性的原因,尋找其內在的一致性。
  • 先學習概念再動手實踐。很多傳統語言開發者在學習Rust的時候,一上來就開始動手寫代碼,結果卻栽了跟頭,連編譯都無法通過。看似符合直覺的代碼,卻因爲借用檢查而導致編譯失敗。這是因爲Rust編譯器在你編寫的代碼中發現了隱藏的錯誤,而你卻未察覺。所以,其實不是Rust學習曲線陡,而是直接動手寫代碼的學習方法有問題。
  • 把編譯器當作朋友。不要忽略Rust編譯器的診斷信息,大多數情況下,這些診斷信息裏已經把錯誤原因闡述得非常明確。這些診斷信息可以幫助你學習Rust,糾正自己的錯誤認知。

俗話說得好,逆境也是機遇。正是因爲Rust有這些特點,學習Rust的過程也是一次自我提升的過程,能夠幫助你成爲更好的程序員。

有益性和穩定性

Rust語言解決了內存安全和併發安全的問題,可以極大地提升軟件的質量。Rust的誕生爲業界提供了一個除C和C++之外的更好的選擇。因爲Rust是對安全、併發和性能都很看重的語言,它可以用於嵌入式系統、操作系統、網絡服務等底層系統,但它並不侷限於此,它還可以用於開發上層Web應用、遊戲引擎和機器學習,甚至基於WebAssembly技術還可以開發前端組件。因爲高的安全性和不遜於C/C++的性能,Rust也被應用於新的前沿領域,比如區塊鏈技術

看得出來,Rust的誕生給業界帶來了非常積極的影響。Rust語言自從發佈了1.0版以來已經進入了穩定期。雖然還在不斷地改進和發佈新的特性,但是Rust的核心是不變的。

綜上所述,Rust在實踐性、有益性和穩定性三方面都做到位了,Rust的實用性毋庸置疑。

1.3  現狀與未來

從2015年Rust發佈1.0版本以來,Rust語言已經被廣泛應用於各大公司及諸多領域。每一年,Rust社區都會聚集在一起制訂路線圖,規劃Rust未來的發展。2018年,Rust團隊推出了新的大版本(edition)計劃:

  • Rust 2015版本,包含Rust 1.0~1.30語義化版本。目標是讓Rust更加穩定。
  • Rust 2018版本,Rust 1.31將是Rust 2018版本的首個語義版本。目標是讓Rust進一步走向生產級。

這個大版本和語義化版本是正交的。大版本的意義在於方便Rust自身的進化。例如,想在Rust中引入新的關鍵字try,但是如果只有語義化版本這一個維度,新的關鍵字可能會破壞現有的Rust生態系統。所以,就需要引入一個大版本,在Rust 2018版本中引入try關鍵字。開發者選擇“edition=2018”,就代表了開發者接受Rust的這種內部變化,接受新的關鍵字try。大版本升級的只是表面的語法功能,Rust的核心概念是不會改變的。如果你使用rustc編譯單獨的文件,就需要增加“–edition 2018”參數。

Rust的編譯器可以方便地管理版本的兼容性:

  • Rust 2015和Rust 2018是彼此兼容的。
  • Rust編譯器知道如何編譯這兩個版本,就像javac知道如何編譯Java 9和Java 10、gcc和clang知道如何處理C++ 14和C++ 17一樣。
  • 可以在Rust 2018版本中依賴Rust 2015的庫,反之亦然。
  • Rust 2015版本並未凍結。

此外,大版本可能是每三年發佈一次,那麼下一次發佈就是在2021年。不過Rust團隊對此還保留修改權。

1.3.1  語言架構

爲了便於學習,筆者針對Rust語言概念的層次結構進行了梳理,如圖1-2所示。
 

圖1-2:Rust中概念層次結構梳理

圖1-2將Rust語言中的概念分成了4個層次。最底層是安全內存管理層,該層主要是涉及內存管理相關的概念。倒數第二層是類型系統層,該層起到承上啓下的作用。類型系統層承載了上層的所有權系統語義和混合編程範式,賦予了Rust語言高級的抽象表達能力和安全性。同時,還保留了對底層代碼執行、數據表示和內存分配等操作的控制能力。

對於開發者而言,只需要掌握類型系統、所有權系統和混合式編程範式即可,不需要操心底層的內存是否安全,因爲有編譯器和類型系統幫忙處理。在這個語言架構之下,人和編譯器共用同一套“心智模型”,這樣可以極大地保證系統的安全和健壯性。

1.3.2  開源社區

Rust語言自身作爲一個開源項目,也是現代開源軟件中的一顆璀璨的明珠。

在Rust之前誕生的所有語言,都僅僅用於商用開發,但是Rust語言改變了這一狀況。對於Rust語言來說,Rust開源社區也是語言的一部分。同時,Rust語言也是屬於社區的。

Rust團隊由Mozilla和非Mozilla成員組成,至今Rust項目貢獻者已經超過了1900人。Rust團隊分爲核心組和其他領域工作組,針對Rust 2018的目標,Rust團隊被分爲了嵌入式工作組、CLI工作組、網絡工作組以及WebAssembly工作組,另外還有生態系統工作組和社區工作組等。

這些領域中的設計都會先經過一個RFC流程,對於一些不需要經過RFC流程的更改,只需要給Rust項目庫提交Pull Request即可。所有過程都是對社區透明的,並且貢獻者都可參與評審,當然,最終決策權歸核心組及相關領域工作組所有。

Rust團隊維護三個發行分支:穩定版(Stable)、測試版(Beta)和開發版(Nightly)。其中穩定版和測試版每6周發佈一次。標記爲不穩定(Unstable)和特性開關(Feature Gate)的語言特性或標準庫特性只能在開發版中使用。

1.3.3  發展前景

根據社區的流行度調查報告,截至2018年7月,由Pull Request統計的GitHub Octoverse報告顯示,Rust語言的總PR數排名第15位,呈上升趨勢。從活躍的項目數來看,Rust語言一共有2604個活躍項目。

目前在商業領域,Rust的重磅商業用戶增長迅速,其中包括:

  • Amazon,使用Rust作爲構建工具。
  • Atlassian,在後端使用Rust。
  • Dropbox,在前後端均使用了Rust。
  • Facebook,使用Rust重寫了源碼管理工具。
  • Google,在Fuchsia項目中部分使用了Rust。
  • Microsoft,在Azure IoT網絡上部分使用了Rust。
  • npm,在其核心服務上使用了Rust。
  • RedHat,使用Rust創建了新的存儲系統。
  • Reddit,使用Rust處理評論。
  • Twitter,在構建團隊中使用Rust。

除了以上羅列的公司,還有很多其他公司,可以在官方Rust之友頁面上找到,包括百度、三星、Mozilla等。Rust覆蓋了數據庫、遊戲、雲計算、安全、科學、醫療保健和區塊鏈等領域,相關的工作崗位越來越多。Rust的前景越來越明朗,未來Rust將大有可爲。

1.4  Rust代碼如何執行

Rust從誕生伊始,就考慮到了平臺移植性問題。通常編譯階段被分爲前端和後端兩部分,Rust作爲編譯語言,也是這樣劃分的。Rust編譯器是一個編譯前端,它的工作是對代碼進行詞法分析、語法分析、類型檢查、生成中間代碼、進行獨立於目標機器的優化等工作。使用LLVM作爲編譯器後端代碼生成框架,則可以利用LLVM兼容多個目標機器的特性,實現跨平臺編譯和優化等工作。所以,用戶在使用Rust時,大多數時候無須考慮各個目標機器平臺的特有性質,基本上可以做到一次編寫,到處運行。而當用戶在需要處理跨平臺兼容性問題的時候,Rust也以第三方crate的形式提供了諸多輔助。

Rust源碼經過分詞和解析,生成AST(抽象語法樹)。然後把AST進一步簡化處理爲HIR(High-level IR),目的是讓編譯器更方便地做類型檢查。HIR會進一步被編譯爲MIR(Middle IR),這是一種中間表示,它在Rust1.12版本中被引入,主要用於以下目的。

  • 縮短編譯時間。MIR可以幫助實現增量編譯,當你修改完代碼重新編譯的時候,編譯器只計算更改過的部分,從而縮短了編譯時間。
  • 縮短執行時間。MIR可以在LLVM編譯之前實現更細粒度的優化,因爲單純依賴LLVM的優化粒度太粗,而且Rust無法控制,引入MIR就增加了更多的優化空間。
  • 更精確的類型檢查。MIR將幫助實現更靈活的借用檢查,從而可以提升Rust的使用體驗。

最終,MIR會被翻譯爲LLVM IR,然後被LLVM的處理編譯爲能在各個平臺上運行的目標機器碼。

1.5  小結

Rust的產生看似偶然,其實是必然。未來的互聯網注重安全和高性能是必然的趨勢。GH看到了這一點,Mozilla也看到了這一點,所以兩者才能一拍即合,創造出Rust。

Rust從2006年誕生之日開始,目標就很明確——追求安全、併發和高性能的現代系統級編程語言。爲了達成這一目標,Rust語言遵循着內存安全、零成本抽象和實用性三大設計哲學。藉助現代化的類型系統,賦予了Rust語言高級的抽象表達能力,與此同時又保留了對底層的控制能力。開發者和Rust編譯器共享着同一套“心智模型”,相互信任,相互協作,最大化地保證系統的安全和健壯性。Rust語言有別於傳統語言的另一點在於,它將開源社區視爲語言的一部分。Rust本身就是開源項目中的典範,非常值得學習。

有人把Rust稱爲”The New C“,我十分認同,Rust是開啓新時代的語言。但Rust可能不像其他語言那樣,突然冒出一個殺手級應用來引領某個領域的一段潮流。Rust改變世界的方式,正好可以用古人的詩詞來形容,”好雨知時節,當春乃發生。隨風潛入夜,潤物細無聲“。

Rust語言不是銀彈,它也不追求完美,它只是在由C和C++構建的舊世界之上,尋求更好的問題解決之道。

所以,你準備好學習Rust了嗎?

作者介紹:
張漢東,80後,資深軟件工程師、企業獨立諮詢師、技術作家和譯者,創業者。愛好讀書、寫作,喜歡研究技術、學習之道、思維認知等領域。曾在互聯網行業沉浮十餘載,先後效力於電商、社交遊戲、廣告和衆籌領域。作爲企業獨立諮詢師,先後爲思科、平安科技和閃迪等公司提供諮詢服務。 2015年開始學習Rust語言,並參與國內Rust社區的管理和運營。在2018年打造了《Rust日報》頻道,深受Rustacean們的喜愛。爲初學者精心打造的Rust必學第一課:知乎Live《如何系統地學習Rust語言》,獲得五星好評。2019年初出版技術暢銷書《Rust編程之道》,深受好評。目前在心智教育及創客領域開疆拓土,努力打造屬於自己的教育品牌。

(本文出自《Rust編程之道》第一章)

圖書鏈接:
https://item.jd.com/12479415.html
https://www.amazon.cn/dp/B07NW95M76/
https://github.com/ZhangHanDong/tao-of-rust-codes

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章