Rust

Rust是由Mozilla主導開發的通用、編譯型程式語言。設計準則為“安全、併發、實用”，支援函式式、並行式、過程式以及面向物件的程式設計風格。Rust語言原本是Mozilla員工Graydon Hoare的個人專案，而Mozilla於2009年開始贊助這個專案 ，並且在2010年首次公開。也在同一年，其編譯器原始碼開始由原本的OCaml語言轉移到用Rust語言，進行自我編譯工作，稱做「rustc」，並於2011年實際完成。這個可自我編譯的編譯器在架構上採用了LLVM做為它的後端。第一個有版本號的Rust編譯器於2012年1月釋出。Rust 1.0是第一個穩定版本，於2015年5月15日釋出。Rust在完全公開的情況下開發，並且相當歡迎-{zh-hans:社群;zh-hant:社群}-的回饋。在1.0穩定版之前，語言設計也因為透過撰寫Servo網頁瀏覽器排版引擎和rustc編譯器本身，而有進一步的改善。它雖然由Mozilla資助，但其實是一個共有專案，有很大部分的程式碼是來自於-{zh-hans:社群;zh-hant:社群}-的貢獻者。設計.Rust的設計目標之一，是要使設計大型的網際網路客戶端和伺服器的任務變得更容易。因此更加強調安全性、記憶體配置、以及並行處理等方面的特性。效能.在效能上，具有額外安全保證的程式碼會比C++慢一些，例如Rust對陣列進行操作時會進行邊界檢查，而C++則不會，但是如果等價的C++程式碼作手工檢查，則兩者效能上是相似的。編譯報錯.比起C/C++，Rust編譯器的對於程式碼中錯誤的提示更清晰明瞭，開發者可根據提示輕鬆地修復程式碼中的錯誤。編譯速度.由於其編譯器會做出額外的安全檢查，Rust的編譯速度有時低於C/C++。語法.Rust的語法設計，與C語言和C++相當相似，區塊和C／C++非常不同。記憶體安全.為了提供記憶體安全，它的設計不允許空指標和懸空指標。指標只能透過固定的初始化形態來建構，而所有這些形態都要求它們的輸入已經分析過了。Rust有一個檢查指標生命期間和指標凍結的系統，可以用來預防在C++中許多的型別錯誤，甚至是用了智慧指標功能之後會發生的型別錯誤。所有權.Rust設計了一個所有權系統，其中所有值都有一個唯一的所有者，並且值的作用域與所有者的作用域相同。值可以透過不可變引用傳遞。任何時候，一個變數都可以有多個不可變引用或一個可變引用，這實際上是一個顯式的讀寫鎖。Rust編譯器在編譯時強制執行這些規則，並檢查所有引用是否有效。記憶體管理.早期的Rust雖然有垃圾回收系統，但非如Java或.NET平臺的全自動垃圾回收。Rust 1.0已不再使用垃圾回收器，而是全面改用基於引用計數的智慧指標來管理記憶體。型別與多型.它的型別系統直接地模仿了Haskell語言的型別類概念，並把它稱作「traits」，可以把它看成是一種特設多型。Rust的作法是透過在宣告型別變數則還未支援。型別推導也是Rust提供的特性之一，使用codice_9語法宣告的變數可以不用宣告型別，亦不需要初始值來推斷型別。但如果在稍後的程式中從未指派任何值到該變數，編譯器會發出編譯時，但是必須繫結Trait。不能使用方法或運運算元而不-{zh-tw: 宣告; zh-hans: 宣告}-它們的型別，每一項都必確明確定義。Rust的物件系統是基於三樣東西之上的，即實作。歷史.2006年，Rust作為Graydon Hoare的個人專案首次出現。2009年，Graydon Hoare成為Mozilla僱員。2010年，Rust首次作為Mozilla官方專案出現。同年，Rust開始從初始編譯轉變為自編譯。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基金會。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)，可以使用codice_11巨集代替codice_12巨集。階乘.下面是三個不同版本的階乘函式，分別以遞迴、迴圈和迭代器的方法寫成：// 這個函式的if-else語句中展示了Rust中可選的隱式返回值，可用於寫出更像函式式程式設計風格的程式碼// 與C++和其他類似的語言不同，Rust中的if-else結構不是語句而是運算式，有返回值fn recursive_factorial(n: u32) -&gt; u32 {if n  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的巨集是基於結構的println!("{} from thread number {}", greeting, num);// 收集所有執行緒，保證它們在程式退出前全部結束for thread in threads {thread.join().unwrap();