Rust 是一門系統編程語言,專注于安全,尤其是并發安全,支持函數式和命令式以及泛型等編程范式的多范式語言。
Rust 最初是由Mozilla研究院的 Graydon Hoare 設計創造,然后在 Dave Herman,Brendan Eich 以及很多其他人的貢獻下逐步完善的。第一個有版本號的Rust編譯器于2012年1月發布。Rust1.0是第一個穩定版本,于2015年5月15日發布。Rust現在由Rust項目開發者社區維護,Rust基金會贊助支持。
截至2023年8月,最新版本為Rust 1.72.0。全世界已有數百家公司在生產環境中使用Rust,例如Firefox、 Dropbox和Cloudflare都在使用Rust。Rust作為C和 C++ 的一種更安全的替代語言,現在由Rust項目開發者社區維護,Rust基金會贊助支持。
歷史演進
Rust語言的起源
Rust語言是一種現代的系統編程語言,它注重性能、安全性和并發。Rust最初由Mozilla研究院的Graydon Hoare于2006年開始設計,最早的目標是為了解決C++在系統編程領域的一些痛點。在2010年,Mozilla Application Suite正式開始支持這個項目,從那時起,Rust開始迅速發展并逐漸成為一個強大的編程語言。
Rust是在完全開放的情況下進行開發,在開發過程中,Rust建立了一個強大且活躍的社區,形成一整套完善穩定的項目貢獻機制。在1.0穩定版之前,語言設計也因為通過撰寫Servo網頁瀏覽器排版引擎和rustc編譯器本身,而有進一步的改善。雖然它由Mozilla資助,但它其實是一個共有項目,有很大部分的代碼是來自于社區的貢獻者。Rust現在由Rust項目開發者社區維護,Rust基金會贊助支持。
發展歷程
2006 年,軟件開發人員 Graydon Hoare 在 Mozilla 工作期間,將 Rust 作為個人項目啟動了。根據《麻省理工科技評論》的采訪,Rust 的靈感來自 Hoare 公寓樓里一部壞掉的電梯。當時電梯操作系統的軟件崩潰了,Hoare 明白,類似的問題通常來自程序內存的問題。通常,這類設備的軟件都是用 C 或 C++ 編寫的,但這些語言需要大量的內存管理,很容易導致錯誤,造成系統崩潰。因此,Hoare 開始著手研究如何創建一種既緊湊又無內存錯誤的編程語言。后來,他向一位經理展示了這個項目 ,這也讓 Mozilla 在 2009 年贊助了這個項目,作為將 Rust 語言納入一項實驗性瀏覽器引擎開發的長期努力的一部分。
Rust語言得到Mozilla研究院的資助后,項目于2010年對外公布,在2010年-2011年間實現自舉,第一個有版本號的Rust編譯器于2012年1月發布。經過幾年的開發,Rust 達到了穩定和成熟的狀態,于2015年5月發布了 Rust 1.0。2016年,Rust社區逐漸發展壯大。兩年后,WebAssembly的推廣使得Rust成為一個受歡迎的前端編程語言。2021年2月,Rust Core團隊宣布成立 Rust基金會,創始成員包括微軟、谷歌、華為、亞馬遜、Mozilla 。2022年9月,Linux初始開發者林納斯·托瓦茲表示在Linux核心6.1版中會對Rust的初步支持。
2023年6月,Rust 項目出現內訌,審核團隊為了抗議核心團隊而集體辭職,而核心團隊自身因為事務繁多,導致忙不過來,反映到項目本身致使軟件開發周期延長,Bug 增多,包括漏洞追蹤等基本運維工作,也受到相當嚴重的影響。同年8月,在經歷了多次治理風波后,Rust各團隊成員合力創建了一份“Rust 領導理事會”的RFC草案,該草案主要內容是移除Rust核心團隊,然后由先前的各團隊出一個代表,成立一個類似“議會”的領導委員會。領導委員會將會舉行定期會議、提出下一輪議程項目,建立團隊存儲庫,并完成舊體系到新體系之間的過渡。
基本語法
變量綁定
在Rust中,變量綁定(變量綁定)是通過let關鍵字聲明的:
其中變量類型如i32一般都是可以簡潔的,因為Rust使用了類型推斷(類型推斷)。Rust還通過模式匹配(模式匹配)對變量進行解構,這允許我們同時對多個變量進行變量。
有幾點需要特別注意的:
原始類型
Rust內置的原始類型(primitive types)有以下幾類:
結構體
結構體 (struct) 是一種記錄類型,所包含的每個域 (field) 都有一個名稱。每個結構體也都有一個名稱,通常以大寫字母開頭,使用駝峰命名法。 (tuple struct) 是由元組和結構體混合構成,元組結構體有名稱,但它的域沒有。當元組結構體只有一個域時,稱為新類型(newtype)。沒有任何域的結構體,稱為類單元結構體(unit-like struct)。結構體中的值默認是不可變的,需要使用自定義可變mut。
一個包含..的struct可以用來從其他結構體復制一些值或者在解構時忽略一些域:
需要注意,Rust 在語言級別不支持域可變性(字段可變性),所以不能這么寫:
這是因為可變性是綁定的一個屬性,而不是結構體本身的。可以使用Cell
另外,結構體的域默認是私有的,可以使用pub關鍵字將其設置成公開。
枚舉
Rust有一個集合類型,稱為枚舉(enum),對于一個指定的名稱有一組可替代的值,其中子數據結構可以存儲也可以不存儲數據,需要使用語法來獲得每個元素的名稱。
與結構體相同,枚舉中的元素默認不能使用關系運算符進行比較 (如==, !=, >=),也不支持像+和*這樣的雙目運算符,需要自己實現,或者使用match進行匹配。
枚舉默認也是默認公有的,如果使用pub默認公有的,則它的元素也都是默認公有的。這一點是與結構體不同的:即使結構體是公有的,它的域仍然是默認公有的。另外,枚舉和結構體也可以是遞歸的(recursive)。
函數
其中函數參數的類型不能簡潔,可以有多個參數,但最多只能返回一個值,提前返回使用return關鍵字。Rust編譯器對未使用的函數提出警告,可以使用屬性#[allow(dead_code)]取消無效代碼檢查。
其中panic!是一個宏,使當前執行線程崩潰并打印給定信息。返回類型!可設置任何類型:
注釋
Rust 有清晰的注釋:
所有權與生命周期
所有權與生命周期是Rust語言非常核心的內容,在C/C++ 中也一樣是存在的。內存安全問題源于對所有權和生命周期的錯誤使用。只要是不采用垃圾回收來管理內存的程序語言,都會有這個問題。Rust在語言級明確了這兩個概念,并提供了相關的語言特性讓用戶可以顯式控制所有權的轉移與生命周期的聲明。同時編譯器會對各種錯誤使用進行檢查,提高了程序的內存安全性。
依賴關系
依賴是UML中最基礎的關系語義。以帶箭頭的虛線表示,A依賴與B表達如下圖。直觀理解可以是A“看的見”B,而B可以對A一無所知。比如在代碼中結構體A中有結構體B的成員變量,或者A的實現代碼中有B的局部變量。這樣如果找不到B,A是無法編譯通過的。
關聯關系
一條實線連接表示兩個類型直接有關聯,有箭頭表示單向"可見",無箭頭表示相互之間可見。關聯關系也是一種依賴,但是更具體。有時候兩個類型之間的關聯關系太復雜,需要用一個類型來表達,叫做關聯類型。
聚合與組成
聚合與組成都是表示的是整體和部分的關系。差別在于“聚合”的整體與部分可以分開,部分可以在多個整體之間共享。而“組成”關系中整體對部分有更強的獨占性,部分不能被拆開,部分與整體有相同的生命周期。
繼承與接口實現
繼承與接口實現都是一種泛化關系,C繼承自A,表示A是更泛化的概念。統一建模語言中各種關系語義也可以用UML自身來表達,“關聯”和“繼承”都是“依賴”的具體體現方式。
組件
編譯器
Rust 語言是基于 LLVM 后端實現的編程語言。在編譯器層面來說,Rust編譯器僅僅是一個編譯器前端,它負責從文本代碼一步步編譯到LLVM中間碼(LLVM IR),然后再交給LLVM來最終編譯生成機器碼,所以LLVM就是編譯后端。
編譯流程
將文本語法中的元素,識別為對 Rust 編譯器有意義的”詞條”,即token。
一般來說,語義分析是為了檢查源程序是否符合語言的定義。在 Rust 中,語義分析階段將會持續在兩個中間碼層級中進行。
HIR 是抽象語法樹(AST)對編譯器更友好的表示形式,很多 Rust 語法糖在這一階段,已經被脫糖(desugared)處理。比如 for 循環在這個階段會被轉為loop,if let 被轉為match,等等。HIR 相對于 AST 更有利于編譯器的分析工作,它主要被用于“類型檢查(type check)、推斷(type inference)”。
MIR 是 Rust 代碼的中級中間代表,基于 HIR 進一步簡化構建。MIR 是在RFC 1211中引入的。
MIR 主要用于借用檢查。早期在沒有 MIR 的時候,借用檢查是在 HIR 階段來做的,所以主要問題就是生命周期檢查的粒度太粗,只能根據詞法作用域來進行判斷,導致很多正常代碼因為粗粒度的借用檢查而無法通過編譯。Rust 2018 edition 中引入的 非詞法作用域生命周期(NLL)就是為來解決這個問題,讓借用檢查更加精細。NLL 就是因為 MIR 的引入,將借用檢查下放到 MIR 而出現的一個術語,這個術語隨著 Rust 的發展終將消失。
MIR 這一層其實擔負的工作很多,除了借用檢查,還有代碼優化、增量編譯、UDSAFE 代碼中 UB 檢查、生成LLVM IR等等。關于 MIR 還需要了解它的三個關鍵特性:
標準庫
RUST 語言的設計目標是操作系統內核級的系統編程語言,使用靜態編譯,并且不采用 GC 機制,保證開發出的應用極高性能。同時又具備現代編程語言的語法特點,在編譯階段就保證內存安全,并發安全,分支安全等安全性。
現代高級語言的標準庫是語言的一個緊密的組成部分,語言的很多特性實際是標準庫實現。RUST 的庫也是如此,但與其他采用 GC 方案的語言不同,其他語言編程目標是在操作系統之上運行的用戶態程序,只需要考慮一種模型。RUST 的編程目標要加上操作系統內核,需要考慮內核與用戶態兩種模型。C 語言在解決這個問題的方法是只提供用戶態的標準庫,操作系統內核的庫由個操作系統自行實現。
RUST 的現代語言特性決定了標準庫無法象 C 語言那樣把操作系統內核及用戶態程序區分成完全獨立的兩個部分,所以只能更細致的設計,做模塊化的處理。RUST 標準庫體系分為三個模塊:語言核心庫–core; alloc 庫;用戶態 std 庫。
core 庫
RUST 語言核心庫,適用于操作系統內核及用戶態,包括 RUST 的基礎類型,基本 Trait, 類型方法函數,其他函數等內容。core 庫是硬件架構和操作系統無關的可移植庫。主要內容:
編譯器內置intrinsics函數
包括內存操作函數,計算數函數,位操作函數,原子變量操作函數等,這些函數通常與CPU硬件架構緊密相關,并且一般需要提供最佳性能。內在函數實際上也對CPU指示的發光層。
基本數據類型
包括整數類型,浮點類型,布爾類型,字符類型,單元類型,內容主要是實現運算符Trait,類型轉換Trait,生宏Trait派等,字符類型包括對unicode,ascii的不同編碼的處理。整數類型有大小端轉換的處理。
alloc 庫
alloc 庫主要實現需要進行動態堆內存申請的智能指針類型,集合類型及他們的方法,函數,Trait 等內容,這些僅需要建立在 core 庫模塊之上,std 會對 alloc 模塊庫的內容做重新的封裝。alloc 庫適用于操作系統內核及用戶態程序。
包括:
1. 基本內存申請;Allocator Trait; Allocator 的實現結構 Global
2. 基礎智能指針:Box, Rc,
3. 動態數組內存類型: RawVec, Vec
4. 字符串類型:&str, String
5. 并發編程指針類型: Arc
6. 指針內訪問類型: Cell, RefCell
用戶態 std 庫
std 是在操作系統支撐下運行的只適用于用戶態程序的庫,core 庫實現的內容基本在 std 庫也有對應的實現。其他內容主要是將操作系統系統調用封裝為適合 rust 特征的結構和 Trait, 包括:
1. 進程,線程庫
2. 網絡庫
3. 文件操作庫
4. 環境變量及參數
5. 互斥與同步庫,讀寫鎖
6. 定時器
7. 輸入輸出的數據結構,
8. 系統事件,對 epoll,kevent 等的封裝
可以將 std 庫看做基本常用的容器類型及操作系統封裝庫。
IDE/編輯器
目前還沒有單獨的一款專門給 Rust 用的編輯器,但是各種編輯器都有支持 Rust 的插件:
代碼示例
Hello World
默認情況下,main.rs文件中已經包含了一個簡單的hello_world程序,代碼如下:
其中,main函數是Rust程序的入口;而println!則是一個Rust宏(而非函數),用于在標準輸出上打印一行文本。
階乘
下面是三個不同版本的階乘函數,分別以遞歸、循環和迭代器的方法寫成:
并發計算
一個簡單的Rust并發計算例子:
Rust語言優勢
內存安全
Rust 的所有權和借用系統可以在編譯時檢查內存安全問題,避免了常見的內存錯誤,如空指針、野指針、緩沖區溢出等。Rust語言的所有權和借用模型可以避免內存泄漏、空指針和野指針等問題,從而提供更加安全的編程環境。這對于需要處理敏感數據的公司來說尤為重要。
并發安全
Rust 的所有權和借用系統還可以檢查并發安全問題,避免了數據競爭等問題。
高效性
Rust 的編譯器可以生成高效的本地代碼,與 C 和 C++ 相當。Rust語言可以提供與C++相當的性能,而且具有更好的內存安全性和并發性能。這對于需要處理大量數據和請求的公司來說尤為重要。
生態系統
Rust 擁有一個龐大的生態系統,包括豐富的庫和工具,可以幫助開發者更快地開發高質量的軟件。
Rust語言特點
零成本抽象
Rust語言可以提供高級抽象,而且不需要任何運行時支持。這意味著你可以在不影響性能的情況下使用高級語言特性,比如抽象數據類型、模板、閉包等。
內存安全
Rust語言中的內存管理模型可以避免內存泄漏、空指針和野指針等問題。這種內存管理模型是通過所有權和借用模型來實現的。Rust的所有權模型是指每個值都有一個獨特的所有者,當這個所有者離開作用域時,這個值就會被自動釋放。借用模型則是指通過引用來訪問值,而不是直接擁有它們。
零成本線程
Rust語言支持線程的創建和管理,而且不需要任何額外的開銷。這是通過將線程管理移交給操作系統來實現的。
Rust語言的應用
Web瀏覽器
Firefox瀏覽器是由Mozilla開發的,它是使用Rust語言編寫的。Rust語言提供了一個安全的系統編程環境,可以讓Firefox更加安全,同時還提高了其性能。
數據庫
CockroachDB是一個分布式數據庫系統,它是使用Go語言和Rust語言開發的。Rust語言在CockroachDB中主要用于實現復雜的算法和數據結構。
操作系統
Redox是一個類Unix操作系統,它是使用Rust語言編寫的。Rust語言在Redox中主要用于實現內核和用戶空間的代碼。
虛擬機
Cranelift是一個JIT編譯器,它是使用Rust語言編寫的。Rust語言在Cranelift中主要用于實現底層代碼生成器和JIT編譯器。
版本記錄
年
以上參考:
年
以上參考:
年
以上參考:
年
以上參考:
年
以上參考:
2019年
以上參考:
2020年
以上參考:
2021年
以上參考:
年
以上參考:
年
以上參考:
設計特色
Rust致力于成為優雅解決高并發和高安全性系統問題的編程語言,適用于大型場景,即創造維護能夠保持大型系統完整的邊界。這就導致了它強調安全,內存布局控制和并發的特點。
參考資料 >
Rust.Rust.2023-09-08
main Rust blog.main Rust blog.2023-09-08
為什么 Rust 是最受開發者推崇的語言.搜狐網.2023-09-08
Licenses - Rust Programming Language.Rust .2023-09-11
常見問題解答 · Rust 程序設計語言.Rust .2023-09-11
進入 Rust 編程世界.Rust語言圣經(Rust Course).2023-09-12
Rust.Rust.2023-09-08
微軟谷歌華為AWS和Mozilla合力組建Rust基金會.Rust語言中文社區.2023-09-25
Linus Torvalds: Rust will go into Linux 6.1.ZDNET.2023-09-12
Rust 項目內訌塵埃落定:原核心團隊解散,成立領導委員會.IT之家.2023-09-25
項目內訌塵埃落定,Rust 基金會發布首份《安全計劃報告》.IT之家.2023-09-25
基本語法.Rust語言學習筆記.2023-09-12
學習園地 | 圖解 Rust 所有權與生命周期.Rust精選.2023-09-12
Rust編譯器專題 | 圖解 Rust 編譯器與語言設計 Part 1.Rust精選.2023-09-12
Rust標準庫.Rust.2023-09-12
std - Rust.Rust.2023-09-12
core - Rust.Rust.2023-09-12
alloc - Rust.Rust.2023-09-12
rust-analyzer.Visual Studio Marketplace.2023-09-12
GitHub - rust-lang/rust-enhanced: The official Sublime Text 3 package for the Rust Programming Language.GitHub.2023-09-12
Rust - IntelliJ IDEs Plugin.Marketplace.2023-09-12
GitHub - rust-lang/rust.vim: Vim configuration for Rust..GitHub .2023-09-12
Eclipse IDE for Rust Developers (includes Incubating components) .Eclipse Packages.2023-09-12
Hello, World! - Rust 程序設計語言 簡體中文版.Rust .2023-09-12
Running Code on Cleanup with the Drop Trait.Rust.2023-09-08