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

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

Rust
Rust: 設計, 历史, 生态系统
编程范型編譯語言並行计算
函数式指令式
物件導向结构化
設計者Graydon Hoare
實作者Mozilla
发行时间2010年
当前版本
  • 1.77.2 (2024年4月9日;穩定版本)
編輯維基數據鏈接
型態系統靜態類型強型別
類型推論結構類型英语Structural type system
操作系统LinuxmacOSWindows
FreeBSDAndroidiOS
許可證Apache许可证2.0及MIT許可證
文件扩展名.rs、.rlib
網站rust-lang.org
啟發語言
Alef英语Alef (programming language)C#C++Cyclone英语Cyclone (programming language)
ErlangHaskellHermes英语Hermes (programming language)Limbo
NewsqueakNIL英语NIL (programming language)OCamlRuby
SchemeStandard MLSwift
影響語言
C# 7ElmIdrisSwiftCarbon

Rust語言原本是Mozilla員工Graydon Hoare的個人專案,而Mozilla於2009年開始贊助這個專案 ,並且在2010年首次公開。也在同一年,其編譯器原始碼開始由原本的OCaml語言轉移到用Rust語言,進行自我編譯工作,稱做「rustc」,並於2011年實際完成。這個可自我編譯的編譯器在架構上採用了LLVM做為它的後端。

第一個有版本號的Rust編譯器於2012年1月釋出。Rust 1.0是第一個穩定版本,於2015年5月15日釋出。

Rust在完全公開的情況下開發,並且相當歡迎社区的回饋。在1.0穩定版之前,語言設計也因為透過撰寫Servo網頁瀏覽器排版引擎和rustc編譯器本身,而有進一步的改善。它雖然由Mozilla資助,但其實是一個共有專案,有很大部分的程式碼是來自於社区的貢獻者。

設計

Rust的設計目標之一,是要使設計大型的網際網路客户端伺服器的任務變得更容易。因此更加強調安全性、記憶體配置、以及並行處理等方面的特性。

性能

在效能上,具有額外安全保證的代碼會比C++慢一些,例如Rust对数组进行操作时会進行边界检查(尽管可以通过一些方式绕过),而C++则不会,但是如果等價的C++代碼作手工检查,則兩者效能上是相似的。

编译报错

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

編譯速度

由於其編譯器會做出額外的安全檢查,Rust的編譯速度有時低於C/C++。

语法

Rust的語法設計,與C語言C++相當相似,區塊(block)使用大括號隔開,控制流程的關鍵字如ifelsewhile等等。在保持相似性的同時,Rust也加進了新的關鍵字,如用於模式匹配match(與switch相似)則是使用C/C++系統程式語言的人會相對陌生的概念。儘管在語法上相似,Rust的語義(semantic)和C/C++非常不同。

内存安全

為了提供内存安全,它的設計不允許空指標懸空指標。指針只能透過固定的初始化形態來建構,而所有這些形態都要求它們的輸入已經分析過了。Rust有一個檢查指標生命期間和指標凍結的系統,可以用來預防在C++中許多的型別錯誤,甚至是用了智能指针功能之後會發生的型別錯誤。

所有权

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

内存管理

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

类型与多态

它的型別系統直接地模仿了Haskell語言的类型类概念,並把它稱作「traits」,可以把它看成是一種特设多态。Rust的作法是透過在宣告型別變數(type variable)的時候,在上面加上限制條件。至於Haskell的高階型別變數(Higher-kinded polymorphism)則還未支援。

型別推導也是Rust提供的特性之一,使用let語法宣告的變數可以不用宣告型別,亦不需要初始值來推斷型別。但如果在稍後的程式中從未指派任何值到該變數,編譯器會發出編譯時(compile time)錯誤。函數可以使用泛型化參數(generics),但是必須綁定Trait。不能使用方法或運算子而不声明它們的型別,每一項都必確明確定義。

Rust的物件系統是基於三樣東西之上的,即實作(implementation)、Trait以及結構化資料(如struct)。實作的角色類似提供Class關鍵字的程式語言所代表的意義,並使用impl關鍵字。繼承和多型則通过Trait實現,它們使得方法(method)可以在實作中被定義。結構化資料用來定義欄位。實作和(trait)都無法定義欄位,並且只有(trait)可以提供繼承,藉以躲避C++的「鑽石繼承問題」(菱型缺陷)。

历史

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

2009年,Graydon Hoare成为Mozilla雇员。

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

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

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

2013年4月4日,Mozilla基金會宣布將與三星集團合作開發瀏覽器排版引擎Servo,此引擎将由Rust來實作。

2015年5月16日,Rust 1.0.0发布。

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

2021年2月8日,AWS華為Google微軟以及Mozilla宣布成立Rust基金會,并承诺在两年时间里每年投入不少于 100 万美元的预算,以用于 Rust 项目的开发、维护和推广。

2022年9月19日,Linux初始開發者林纳斯·托瓦兹表示在Linux核心6.1版中會有對Rust的初步支援。

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

生态系统

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

Cargo

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

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

代码示例

下面的代码在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();     } } 

參考資料

参閱

外部链接

Tags:

Rust 設計Rust 历史Rust 生态系统Rust 代码示例Rust 參考資料Rust 参閱Rust 外部链接RustMozilla函數程式語言并行计算编译型语言过程式编程通用编程语言面向对象程序设计

🔥 Trending searches on Wiki 中文:

美国各国家和地区人口列表吳樾 (演員)Signal (電視劇)表藝珍Jisoo (歌手)非常律師禹英禑文在寅愛·逆轉鄧月平我內心的糟糕念頭金多美王后傘下許瑋甯GCS職業聯賽格杀福顺龍與地下城:盜賊榮耀席琳·狄翁人選之人-造浪者86—不存在的戰區—林重威神探大戰BilibiliRei朝鮮律師全智賢Running Man点燃我,温暖你陳子玄浪漫醫生金師傅第59屆百想藝術大獎黃金週 (中國)布莱顿足球俱乐部蔡依林朱紫緹侯友宜李俊昊曾志偉周杰倫關於我轉生變成史萊姆這檔事角色列表千与千寻琉球群岛水晶宫足球俱乐部狄倫·布魯克斯崔勝哲甄詠蓓瓦格纳集团殺破狼 (電影)柳俊烈女神咖啡廳格鲁吉亚杀破狼2死屍死時四十四我的英雄学院角色列表范丞丞呂雪鳳劉賜蕙各国人均名义国内生产总值列表KLG乘风破浪的姐姐 (第一季)包偉銘肖戰汤唯毒梟聖徒何鴻燊絕命毒師梅艷芳竇驍漫长的季节文俊輝李聖旻以家人之名隆宸翰企鵝妹李宗伟五十音戴立忍和平歸來🡆 More