Rust

重視記憶體安全性與並行處理的程式語言

Rust是由Mozilla[11]主导开发的通用编译型编程语言。设计准则为“安全、并发、实用”[12][13],支持函数式并发式过程式以及面向对象的编程风格。

Rust
编程范型编译语言并发计算
函数式指令式
面向对象结构化
设计者Graydon Hoare
实现者Mozilla
发行时间2010年
当前版本
  • 1.82.0(2024年10月17日;稳定版本)[1]
编辑维基数据链接
类型系统静态类型强类型
类型推论结构类型英语Structural type system
操作系统LinuxmacOSWindows
FreeBSDAndroidiOS[2]
许可证Apache许可证2.0及MIT许可证[3]
文件扩展名.rs、.rlib
网站rust-lang.org
启发语言
Alef英语Alef (programming language)[4]C#[4]C++[4]Cyclone英语Cyclone (programming language)[4][5]
Erlang[4]Haskell[4]Hermes英语Hermes (programming language)[4]Limbo[4]
Newsqueak[4]NIL英语NIL (programming language)[4]OCaml[4]Ruby[4]
Scheme[4]Standard ML[4]Swift[4][6]
影响语言
C# 7[7]Elm[8]Idris[9]Swift[10]Carbon

Rust语言原本是Mozilla员工Graydon Hoare的个人项目,而Mozilla于2009年开始赞助这个项目 [14],并且在2010年首次公开[15]。也在同一年,其编译器原始码开始由原本的OCaml语言转移到用Rust语言,进行自我编译工作,称做“rustc”[16],并于2011年实际完成[17]。这个可自我编译的编译器在架构上采用了LLVM做为它的后端。

第一个有版本号的Rust编译器于2012年1月发布[18]。Rust 1.0是第一个稳定版本,于2015年5月15日发布[19]

Rust在完全公开的情况下开发,并且相当欢迎社区的反馈。在1.0稳定版之前,语言设计也因为透过撰写Servo网页浏览器排版引擎和rustc编译器本身,而有进一步的改善。它虽然由Mozilla资助,但其实是一个共有项目,有很大部分的代码是来自于社区的贡献者[20]

设计

Rust的设计目标之一,是要使设计大型的互联网客户端伺服器的任务变得更容易[21]。因此更加强调安全性、存储器配置、以及并发处理等方面的特性。

性能

在性能上,具有额外安全保证的代码会比C++慢一些,例如Rust对数组进行操作时会进行边界检查(尽管可以通过一些方式[22]绕过[23]),而C++则不会,但是如果等价的C++代码作手工检查,则两者性能上是相似的[24]

编译报错

比起C/C++,Rust编译器的对于代码中错误的提示更清晰明了,开发者可根据提示轻松地修复代码中的错误。

编译速度

由于其编译器会做出额外的安全检查,Rust的编译速度有时低于C/C++。

语法

Rust的语法设计,与C语言C++相当相似,区块(block)使用大括号隔开,控制流程的关键字如ifelsewhile等等。在保持相似性的同时,Rust也加进了新的关键字,如用于模式匹配match(与switch相似)则是使用C/C++系统编程语言的人会相对陌生的概念。尽管在语法上相似,Rust的语义(semantic)和C/C++非常不同。

内存安全

为了提供内存安全,它的设计不允许空指针悬空指针[25][26]。指针只能透过固定的初始化形态来建构,而所有这些形态都要求它们的输入已经分析过了[27]。Rust有一个检查指针生命期间和指针冻结的系统,可以用来预防在C++中许多的类型错误,甚至是用了智慧指针功能之后会发生的类型错误。

所有权

Rust设计了一个所有权系统,其中所有值都有一个唯一的所有者,并且值的作用域与所有者的作用域相同。值可以通过不可变引用(&T)、可变引用(&mut T)或者通过值本身(T)传递。任何时候,一个变量都可以有多个不可变引用或一个可变引用,这实际上是一个显式的读写锁。Rust编译器在编译时强制执行这些规则,并检查所有引用是否有效。[28][29]

内存管理

早期的Rust虽然有垃圾回收系统,但非如Java.NET平台的全自动垃圾回收。Rust 1.0已不再使用垃圾回收器,而是全面改用基于引用计数的智慧指针来管理内存。

类型与多态

它的类型系统直接地模仿了Haskell语言的类型类概念,并把它称作“traits”,可以把它看成是一种特设多态。Rust的作法是透过在宣告类型变量(type variable)的时候,在上面加上限制条件。至于Haskell的高阶类型变量(Higher-kinded polymorphism)则还未支持。

类型推导也是Rust提供的特性之一,使用let语法宣告的变量可以不用宣告类型,亦不需要初始值来推断类型。但如果在稍后的程序中从未指派任何值到该变量,编译器会发出编译时(compile time)错误[30]。函数可以使用泛型化参数(generics),但是必须绑定Trait。不能使用方法或运算符而不声明它们的类型,每一项都必确明确定义。

Rust的物件系统是基于三样东西之上的,即实现(implementation)、Trait以及结构化资料(如struct)。实现的角色类似提供Class关键字的编程语言所代表的意义,并使用impl关键字。继承和多态则通过Trait实现,它们使得方法(method)可以在实现中被定义。结构化资料用来定义字段。实现和(trait)都无法定义字段,并且只有(trait)可以提供继承,藉以躲避C++的“钻石继承问题”(菱型缺陷)。

历史

2006年,Rust作为Graydon Hoare的个人项目首次出现。

2009年,Graydon Hoare成为Mozilla雇员[14]

2010年,Rust首次作为Mozilla官方项目出现[15]。同年,Rust开始从初始编译(由OCaml写成)转变为自编译[16]

2011年,Rust成功的完成了移植[17]。Rust的自编译器采用LLVM作为其编译后端。

2012年1月20日,第一个有版本号的预览版Rust编译器发布[18]

2013年4月4日,Mozilla基金会宣布将与三星集团合作开发浏览器排版引擎Servo,此引擎将由Rust来实现[31]

2015年5月16日,Rust 1.0.0发布[32]

2020年3月27日,Rust核心团队成员Steve Klabnik在官方部落格发表了一篇名为《Goodbye, docs team》的文章,叙述了Rust文档的现状[33]

2021年2月8日,AWS华为Google微软以及Mozilla宣布成立Rust基金会[34][35],并承诺在两年时间里每年投入不少于 100 万美元的预算,以用于 Rust 项目的开发、维护和推广[36]

2022年9月19日,Linux初始开发者林纳斯·托瓦兹表示在Linux核心6.1版中会有对Rust的初步支持[37]

2023年4月6日,Rust基金会发布了新商标政策草案,修订了关于如何使用Rust标志和名称的规则,导致了Rust用户社区的负面反应和抗议。[38]

生态系统

除了编译器和标准库,Rust生态系统还包括用于软件开发的额外组件。官方推荐使用Rustup,一个Rust工具链安装程序来管理这些组件。

Cargo

Cargo是Rust的软件包管理器,用来下载和构建依赖关系。Cargo还充当了Clippy和其他Rust组件的封装器。它要求项目遵循一定的目录结构。[39]

Cargo.toml文件指定了项目所需的依赖和版本要求,告诉Cargo哪些版本的依赖关系与该包兼容。Cargo默认从crates.io中获取依赖,但Git仓库和本地文件系统中的包也可以作为依赖。[40]

集成开发环境支持

rust-analyzer 是一系列工具,可以通过语言伺服器协议集成开发环境(IDE)和文本编辑器提供有关某一Rust项目的资讯。利用它,开发者可以在编辑Rust代码时使用自动完成和编译错误显示等功能。[41]

代码示例

下面的代码在Rust 1.3中测试通过。

Hello World

fn main() {
    println!("Hello, World!");
}

如果不想使输出包含换行符(\n),可以使用print!代替println!宏。

阶乘

下面是三个不同版本的阶乘函数,分别以递归循环迭代器的方法写成:

// 這個函數的if-else語句中展示了Rust中可選的隱式返回值,可用於寫出更像函數式程式設計風格的代碼
// 與C++和其他類似的語言不同,Rust中的if-else結構不是語句而是運算式,有返回值
fn recursive_factorial(n: u32) -> u32 {
    if n <= 1 {
        1
    } else {
        n * recursive_factorial(n - 1)
    }
}

fn iterative_factorial(n: u32) -> u32 {
    // 變數用`let`定義,`mut`關鍵字使得變數可以變化
    let mut i = 1u32;
    let mut result = 1u32;
    while i <= n {
        result *= i;
        i += 1;
    }
    result // 顯式返回值,與上一個函數不同
}

fn iterator_factorial(n: u32) -> u32 {
    // 迭代器有多種用於變換的函數
    // |accum, x| 定義了一個匿名函數
    // 內聯展開等最佳化方法會消去區間和fold,使本函數的運行效率和上一個函數相近
    (1..n + 1).fold(1, |accum, x| accum * x)
}

fn main() {
    println!("Recursive result: {}", recursive_factorial(10));
    println!("Iterative result: {}", iterative_factorial(10));
    println!("Iterator result: {}", iterator_factorial(10));
}

一个简单的Rust并发计算例子:

use std::thread;

// 這個函數將創建十個同時並行的執行緒
// 若要驗證這一點,可多次運行這個程式,觀察各執行緒輸出順序的隨機性
fn main() {
    // 這個字串是不可變的,因此可以安全地同時被多個執行緒訪問
    let greeting = "Hello";

    let mut threads = Vec::new();
    // `for`迴圈可用於任何實現了`iterator`特性的類型
    for num in 0..10 {
        threads.push(thread::spawn(move || {
            // `println!`是一個可以靜態檢查格式字串類型的巨集
            // Rust的巨集是基於結構的(如同Scheme)而不是基於文本的(如同C)
            println!("{} from thread number {}", greeting, num);
        }));
    }

    // 收集所有執行緒,保證它們在程式退出前全部結束
    for thread in threads {
        thread.join().unwrap();
    }
}

参考资料

  1. ^ Announcing Rust 1.82.0. 2024年10月17日 [2024年10月17日] (英语). 
  2. ^ Rust Platform Support. [2017-03-17]. (原始内容存档于2018-02-13). 
  3. ^ COPYRIGHT. Rust compiler source repository. [2012-12-17]. 
  4. ^ 4.00 4.01 4.02 4.03 4.04 4.05 4.06 4.07 4.08 4.09 4.10 4.11 4.12 4.13 4.14 The Rust Reference: Appendix: Influences. [2015-03-25]. (原始内容存档于2015-03-26). Rust is not a particularly original language, with design elements coming from a wide range of sources. Some of these are listed below (including elements that have since been removed): SML, OCaml [...] C++ [...] ML Kit, Cyclone [...] Haskell [...] Newsqueak, Alef, Limbo [...] Erlang [...] Swift [...] Scheme [...] C# [...] Ruby [...] NIL, Hermes 
  5. ^ Note Research: Type System. 2015-02-01 [2015-03-25]. (原始内容存档于2019-02-17). Papers that have had more or less influence on Rust, or which one might want to consult for inspiration or to understand Rust's background. [...] Region based memory management in Cyclone [...] Safe memory management in Cyclone 
  6. ^ RFC for `if let` expression. [2014-12-04]. (原始内容存档于2016-03-04). The `if let` construct is based on the precedent set by Swift, which introduced its own `if let` statement. 
  7. ^ Discussion - Patterns and Records. 2015-03-25 [2015-03-25]. (原始内容存档于2015-08-19). Sources of Inspiration: [...] Rust 
  8. ^ Command Optimizations?. 2014-06-26 [2014-12-10]. (原始内容存档于2019-07-08). I just added the outline of a Result library that lets you use richer error messages. It's like Either except the names are more helpful. The names are inspired by Rust's Result library. 
  9. ^ Uniqueness Types. 2014-08-22 [2014-10-27]. (原始内容存档于2014-12-25). They are inspired by linear types, Uniqueness Types in the Clean programming language, and ownership types and borrowed pointers in the Rust programming language. 
  10. ^ Lattner, Chris. Chris Lattner's Homepage. Chris Lattner. 2014-06-03 [2014-06-03]. (原始内容存档于2018-12-25). The Swift language is the product of tireless effort from a team of language experts, documentation gurus, compiler optimization ninjas, and an incredibly important internal dogfooding group who provided feedback to help refine and battle-test ideas. Of course, it also greatly benefited from the experiences hard-won by many other languages in the field, drawing ideas from Objective-C, Rust, Haskell, Ruby, Python, C#, CLU, and far too many others to list. 
  11. ^ Noel. The Rust Language. Lambda the Ultimate. 2010-07-08 [2010-10-30]. (原始内容存档于2015-11-18). 
  12. ^ The Rust Programming Language. [2012-10-21]. (原始内容存档于2016-06-18). 
  13. ^ Doc language FAQ. [2012-10-21]. (原始内容存档于2020-07-20). 
  14. ^ 14.0 14.1 Project FAQ. 2010-09-14 [2012-01-11]. (原始内容存档于2020-07-20). 
  15. ^ 15.0 15.1 Future Tense. 2011-04-29 [2012-02-06]. (原始内容存档于2012-09-18). At Mozilla Summit 2010, we launched Rust, a new programming language motivated by safety and concurrency for parallel hardware, the “manycore” future which is upon us. 
  16. ^ 16.0 16.1 Hoare, Graydon. Rust Progress. 2010-10-02 [2010-10-30]. (原始内容存档于2014-08-15). 
  17. ^ 17.0 17.1 Hoare, Graydon. [rust-dev] stage1/rustc builds. 2011-04-20 [2011-04-20]. (原始内容存档于2011-07-20). After that last change fixing the logging scope context bug, looks like stage1/rustc builds. Just shy of midnight :) 
  18. ^ 18.0 18.1 catamorphism. Mozilla and the Rust community release Rust 0.1 (a strongly-typed systems programming language with a focus on memory safety and concurrency). 2012-01-20 [2012-02-06]. (原始内容存档于2012-01-24). 
  19. ^ rust/RELEASES.md at master · rust-lang/rust · GitHub. GitHub. [2015-07-26]. (原始内容存档于2015-05-15). 
  20. ^ Rust Contributors. [2015-05-17]. (原始内容存档于2020-05-26). 
  21. ^ Avram, Abel. Interview on Rust, a Systems Programming Language Developed by Mozilla. InfoQ. 2012-08-03 [2013-08-17]. (原始内容存档于2013-07-24). GH:在其他编程语言中有很多好的、讨人喜爱的想法,没有被广泛采用的系统编程语言采纳...在1970和80年代时,有些相当不错的竞争者同时存在,我想要把它们所有的某些特性再拿出来,因为现况已经改变:互联网是并发性非常强的系统,也更加重视安全性,所以以往独钟C以及C++的优势不再成立。 
  22. ^ How to avoid bounds checking?. The Rust Programming Language Forum. 2016-01-26 [2021-02-08]. (原始内容存档于2021-02-08) (英语). 
  23. ^ 范, 范长春. 数组和字符串. 深入浅出Rust 2018年8月第一版. 北京: 机械工业出版社. 2018: 72-73. ISBN 9787111606420. OCLC 1097888310. 
  24. ^ Walton, Patrick. C++ Design Goals in the Context of Rust. 2010-12-05 [2011-01-21]. (原始内容存档于2010-12-09). ...想要维持和C一样快又同时保证安全是不可能的...C++在设计上允许各种低层操作,大部分与回避类型系统有关,借此C++有了几乎无限制的优化能力。不过在实际上,C++工程师在自己的代码中只使用某些特定的工具或技巧,例如透过pass by alias传递stack变量、独特拥有的物件(通常是auto_ptr或C++0x的unique_ptr)、使用shared_ptr来达成“引用计数”、COM等等。Rust的类型系统的设计目标之一,就是在语言中融入这些安全性设计,并且强迫实行这些原则。这样的话,性能可以与C++比较,又能同时保持存储器安全... 
  25. ^ Rosenblatt, Seth. Samsung joins Mozilla's quest for Rust. 2013-04-03 [2013-04-05]. (原始内容存档于2013-04-04). [Brendan Eich]提出,每一年,浏览器都会在Pwn2Own竞赛上发现新的漏洞。他说,Rust“不允许自由读取存储器”,但C++则可以。这些便是“导致浏览器弱点”,也是能够自编译的Rust要解决的问题。 
  26. ^ Brown, Neil. A taste of Rust. 2013-04-17 [2013-04-25]. (原始内容存档于2013-04-26). ...当然,为了更大程度的存储器分享,用户可以实现更复杂的数据结构,并同时保持接口只由被拥有和被管理的引用所组成。如此便解决了竞争存取和悬空指针的问题。 
  27. ^ Language FAQ. 2015-05-17 [2015-05-17]. (原始内容存档于2015-05-15). 
  28. ^ Klabnik, Steve; Nichols, Carol. Chapter 4: Understanding Ownership. The Rust Programming Language. San Francisco, California: No Starch Press. June 2018: 44 [2019-05-14]. ISBN 978-1-593-27828-1. (原始内容存档于2019-05-03) (英语). 
  29. ^ The Rust Programming Language: What is Ownership. Rust-lang.org. [2019-05-14]. (原始内容存档于2019-05-19) (英语). 
  30. ^ Walton, Patrick. Rust Features I: Type Inference. 2010-10-01 [2011-01-21]. (原始内容存档于2011-07-08). 
  31. ^ Peter Bright. Samsung teams up with Mozilla to build browser engine for multicore machines. 2013-04-03 [2013-04-04]. (原始内容存档于2016-12-16). 
  32. ^ The Rust Core Team. Announcing Rust 1.0. May 15, 2015 [2015-12-11]. (原始内容存档于2015-05-15). 
  33. ^ Goodbye, docs team. [2022-10-10]. (原始内容存档于2022-12-01) (英语). 
  34. ^ Rust Foundation. foundation.rust-lang.org. 2021-02-08 [2021-02-09]. (原始内容存档于2021-02-09) (英语). 
  35. ^ Mozilla Welcomes the Rust Foundation. Mozilla Blog. 2021-02-09 [2021-02-09]. (原始内容存档于2021-02-08) (美国英语). 
  36. ^ 抛弃 C / C++!微软官宣:请用 Rust 编写 Windows 驱动!. CSDNnews. 2023-10-08 [2023-10-09]. (原始内容存档于2023-10-09) (中文(中国大陆)). 
  37. ^ Linus Torvalds: Rust will go into Linux 6.1. ZDNET. [2022-10-06]. (原始内容存档于2023-01-19) (英语). 
  38. ^ Claburn, Thomas. Rust Foundation apologizes for trademark policy confusion. The Register. 2023-04-17 [2023-05-07]. (原始内容存档于2023-05-07) (英语). 
  39. ^ Why Cargo Exists - The Cargo Book. doc.rust-lang.org. [2022-02-01]. (原始内容存档于2022-04-07). 
  40. ^ Specifying Dependencies - The Cargo Book. doc.rust-lang.org. [2022-02-01]. (原始内容存档于2022-04-07). 
  41. ^ Klabnik, Steve; Nichols, Carol. The Rust programming language. San Francisco: No Starch Press. San Francisco: 623. ISBN 978-1-7185-0310-6. 

参阅

外部链接