Rust 語言的應用已不再侷限於傳統的系統程式設計,其安全、高效的特性使其在網頁開發、嵌入式系統、雲端運算和區塊鏈等領域嶄露頭角。伺服器端渲染網站開發中,Rust 框架如 Actix-web、Axum 和 Rocket 提供了高效能的解決方案。在行動裝置應用開發方面,Rust 能夠與 Java/Kotlin 和 Objective-C/Swift 等語言互動,開發高效能的原生應用程式。嵌入式系統開發中,Rust 的 embedded-hal 提供了硬體抽象層,方便開發可攜式驅動程式和韌體。雲端服務供應商如 AWS 也開始採用 Rust 開發核心服務,例如 Firecracker VM 和 Bottlerocket 等,提升了服務的效能和安全性。區塊鏈領域,Rust 也被用於開發新的區塊鏈平台和智慧合約,例如 Solana 和 NEAR Protocol 等。

使用 Rust 的更多可能性

新的開始

我們已經一起踏上了 Rust 這個精彩的世界。我們學習瞭如何建立 CLI、GUI、網頁應用程式前端、REST API、使用 AWS 的無伺服器網站、遊戲、控制硬體的程式以及機器學習模型。接下來你可以採取什麼步驟?你還可以使用 Rust 建立哪些令人興奮的應用程式?我們將簡要介紹一些本文未涵蓋的其他領域。

伺服器端渲染網站

在前面的章節中,你學習瞭如何在 Rust 中建立單頁應用程式(SPA)前端和 REST API。這種組合,有時被稱為客戶端渲染,是目前現代網頁開發中最流行的架構。然而,有一種較舊的動態網站架構稱為伺服器端渲染,仍然可行且在某些地方重新受到青睞。在伺服器端渲染的網站中,後端負責構建 HTML 並將其傳送回前端。伺服器端渲染仍然具有多種優勢:

  • 簡單性:對於簡單的網站,使用者介面(HTML 和 CSS)與商業邏輯寫在同一個地方。前端也不需要向後端發出複雜的 API 請求來接收資料。
  • 效能:由於瀏覽器直接從後端接收 HTML,因此不需要等待 JavaScript 載入並等待 JavaScript 渲染螢幕。這樣可以提高效能。雖然一些使用同構渲染的框架也可以加速客戶端渲染頁面的效能,但這會增加複雜度,而保持程式碼函式庫簡單通常是更好的選擇(目前還沒有可供生產使用的 Rust 程式函式庫)。
  • 搜尋引擎最佳化(SEO):搜尋引擎使用稱為爬蟲的程式來掃描網頁並建立搜尋索引。一些爬蟲可能無法執行 JavaScript,因此伺服器端渲染的網站對瀏覽器引擎爬蟲更友好。如今,主要的搜尋引擎都具備處理客戶端渲染網站的能力,但在設計新網站時仍需要考慮 SEO。

你可以在第五章中使用的 actix-web 框架用於伺服器端渲染。其他支援伺服器端渲染的框架包括 Axum 和 Rocket。

網頁瀏覽器與爬蟲

當人們討論網頁的前端和後端時,他們經常忽略了中間的部分:網頁瀏覽器。人們之所以經常忽略它,是因為市場上只有少數瀏覽器可用,因此它們被視為理所當然。你可能會反駁說,維基百科上有數百種瀏覽器,但事實上,大多數現代瀏覽器都由三種瀏覽器引擎驅動:

  • Blink:驅動 Chromium、Google Chrome、Microsoft Edge 和 Opera
  • Gecko:驅動 Firefox
  • WebKit:驅動 Safari

Rust 的歷史與瀏覽器引擎密切相關。從頭開始用 Rust 編寫的瀏覽器引擎原型稱為 Servo。Servo 是歷史上最重要的 Rust 專案之一。Servo 專案始於 2012 年,現在大約有 260 萬行程式碼(並非全部都是 Rust,但仍然令人印象深刻)。Servo 最初是 Mozilla 的研究專案。2017 年,Servo 的 CSS 引擎成熟並被合併到 Gecko 中,即 Mozilla 的 Firefox 瀏覽器引擎。Servo 的渲染元件 WebRender 後來也被整合到 Firefox 中。因此,如果你現在正在使用 Firefox,你也在執行大量的 Rust 程式碼。

Servo 對 Rust 本身產生了重大影響。這兩個專案分享一些核心開發人員,核心貢獻者之間密切合作,因為它們都是在 Mozilla Research 下啟動的研究專案。Servo 的許多需求推動了 Rust 新功能的開發,Rust 的設計也對 Servo 的架構產生了重大影響。如果你對在大規模專案中看到 Rust 感興趣,Servo 絕對是一個值得深入研究的專案。2020 年,Servo 專案從 Mozilla 轉移到 Linux Foundation。

作為 Rust 在網頁瀏覽器中成功的證明,Chromium 專案決定正式支援從其 C++ 程式函式庫呼叫 Rust 程式碼。

瀏覽器是為人類設計的。然而,還有很多其他程式也會消耗網頁內容。這些程式通常被稱為網頁爬蟲、抓取工具或蜘蛛。它們會「爬行」網頁並從中提取資訊。例如,當你想要比較不同電子商務網站上的價格,但這些網站不提供 API 時,我們可以使用爬蟲來爬行它們的網頁並從 HTML 中提取價格資訊。有一些框架可以用於建立網頁爬蟲,例如 spider 和 website-crawler。如果你想要對爬行和解析過程進行更精細的控制,可以使用 reqwest 函式庫。

使用 Plantuml 圖表呈現瀏覽器引擎架構

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Rust 應用程式開發探索無限可能

package "安全架構" {
    package "網路安全" {
        component [防火牆] as firewall
        component [WAF] as waf
        component [DDoS 防護] as ddos
    }

    package "身份認證" {
        component [OAuth 2.0] as oauth
        component [JWT Token] as jwt
        component [MFA] as mfa
    }

    package "資料安全" {
        component [加密傳輸 TLS] as tls
        component [資料加密] as encrypt
        component [金鑰管理] as kms
    }

    package "監控審計" {
        component [日誌收集] as log
        component [威脅偵測] as threat
        component [合規審計] as audit
    }
}

firewall --> waf : 過濾流量
waf --> oauth : 驗證身份
oauth --> jwt : 簽發憑證
jwt --> tls : 加密傳輸
tls --> encrypt : 資料保護
log --> threat : 異常分析
threat --> audit : 報告生成

@enduml

此圖示展示了主要的瀏覽器引擎及其驅動的瀏覽器。

爬蟲框架的選擇

在選擇爬蟲框架時,需要考慮多個因素,例如目標網站的複雜度、所需資料的型別以及效能需求。以下是一些常見的爬蟲框架:

  • spider:一個簡單易用的爬蟲框架,支援多種資料提取方式。
  • website-crawler:一個功能強大的爬蟲框架,支援多執行緒和分散式爬取。
爬蟲框架比較
框架簡單度功能效能
spider易用多種資料提取方式良好
website-crawler複雜多執行緒和分散式爬取優秀
程式碼範例:使用 reqwest 函式庫進行 HTTP 請求
use reqwest;

async fn fetch_data(url: &str) -> Result<String, reqwest::Error> {
    let response = reqwest::get(url).await?;
    let body = response.text().await?;
    Ok(body)
}

#[tokio::main]
async fn main() {
    let url = "https://example.com";
    match fetch_data(url).await {
        Ok(data) => println!("Fetched data: {}", data),
        Err(err) => println!("Error fetching data: {}", err),
    }
}

內容解密:

  1. reqwest 函式庫用於進行 HTTP 請求。
  2. fetch_data 函式是非同步的,使用 reqwest::get 傳送 GET 請求。
  3. response.text().await? 用於讀取回應的主體內容。
  4. main 函式中,使用 tokio::main 宏啟用非同步執行。
  5. fetch_data 函式被呼叫,並處理可能的錯誤。

這個範例展示瞭如何使用 reqwest 函式庫進行 HTTP 請求,並處理回應資料。

使用 Rust 開發行動裝置應用程式

在前面的章節中,我們討論瞭如何為桌面環境建立 GUI。然而,並未探討如何為行動裝置(即應用程式)建立使用者介面。目前的主流行動裝置平台為 Google 的 Android 和 Apple 的 iOS。Android 應用程式主要使用 Java 或 Kotlin 開發,而 iOS 應用程式則使用 Objective-C 或 Swift。

在 Android 上使用 Rust

要在 Android 上使用 Rust,需要經過以下步驟:

  1. 安裝 Android Studio:這是官方的 Android 應用程式開發環境,包含了 Android SDK。
  2. 安裝 Android NDK:這個工具包允許我們將 Rust 編譯成可以在 Android 上執行的函式庫,並且可以與 Java/Kotlin 互動。
  3. 使用 rustup 安裝 Android 目標平台:例如 armv7-linux-androideabi
  4. 建立 Rust 函式庫專案並編譯成函式庫檔案:需要透過 JNI(Java Native Interface)將 Rust 程式碼暴露給 Java。可以使用 jni crate 來簡化這個過程。
  5. 將 Rust 函式庫匯入到 Java/Kotlin 的 Android 應用程式專案中,並在 Java/Kotlin 程式碼中呼叫該函式庫。

程式碼範例:建立 Rust 函式庫

// lib.rs
use jni::JNIEnv;
use jni::objects::{JClass, JString};
use jni::sys::jsize;

#[no_mangle]
pub extern "system" fn Java_com_example_myapp_MainActivity_greeting(
    env: JNIEnv,
    _class: JClass,
    input: JString
) -> jsize {
    // 將 JString 轉換為 Rust 的 String
    let input: String = env.get_string(input).unwrap().into();
    // 簡單的問候語邏輯
    let output = format!("Hello, {}!", input);
    // 將輸出轉換為 JString 並傳回其長度
    let output = env.new_string(output).unwrap();
    output.into_raw() as jsize
}

內容解密:

  1. 使用 jni crate:首先,我們需要引入 jni crate,它提供了與 JNI 互動的功能。
  2. Java_com_example_myapp_MainActivity_greeting 函式:這個函式是給 Java 呼叫的入口點。它的名稱遵循特定的格式,以便 Java 可以透過 JNI 找到它。
  3. 引數處理:函式接收 JNIEnvJClassJString 作為引數。JNIEnv 是 JNI 環境的參照,用於進行 JNI 操作;JClass 是當前類別的參照,在這裡沒有被使用;JString 是從 Java 傳遞過來的字串。
  4. 字串轉換:將 JString 轉換為 Rust 的 String,進行簡單的問候語處理後,再轉換回 JString
  5. 傳回結果:最終,將處理後的字串長度傳回給 Java。

在 iOS 上使用 Rust

在 iOS 上使用 Rust 的步驟與 Android 類別似,主要區別在於使用的工具和介面不同。

  1. 安裝 Xcode:這是官方的 iOS 應用程式開發環境。
  2. 使用 rustup 安裝 iOS 目標平台:例如 armv7-apple-ios
  3. 建立 Rust 函式庫專案並編譯成函式庫檔案:需要生成 C 風格的標頭檔案,以便 iOS 可以像呼叫 C 函式庫一樣呼叫 Rust 函式庫。
  4. 將 Rust 函式庫匯入到 Xcode 專案中,並在 Objective-C/Swift 程式碼中呼叫該函式庫。

使用 Tauri 建立跨平台應用程式

Tauri 提供了一個引擎,可以執行根據 JavaScript 和 WASM 的 UI,不僅可以在桌面環境,也可以在行動裝置上執行。利用 Tauri,可以將原本使用 WebAssembly 編寫的單頁網頁應用程式,稍加修改後轉換成桌面或行動裝置應用程式。

嵌入式系統與作業系統

在第8章的結尾,我們提到了在硬體層級上可以做的遠不止是讓LED燈閃爍。由於硬體平台和周邊裝置的種類別繁多,從零開始為每個平台編寫裸機Rust程式幾乎是不可能的。幸運的是,在不同的層級上已經定義了一些軟體抽象層。最底層是周邊存取程式函式庫(peripheral-access crates),它們包含了微控制器的暫存器定義和低階細節。在其上層,是embedded-hal層。「-hal」字尾代表硬體抽象層(Hardware Abstraction Layer)。embedded-hal是一組特性(traits),定義了特定的HAL實作和驅動程式之間的硬體無關介面。驅動程式可以根據embedded-hal特性編寫,而不必擔心硬體特定的細節。這使得開發者可以在這個抽象層上建立可攜式的驅動程式、韌體和應用程式。你可以在crates.io上搜尋關鍵字「embedded-hal」或「embedded-hal-impl」來找到許多embedded-hal程式函式庫及其實作。

在embedded-hal之上,有驅動程式函式庫(driver crates)和板級支援程式函式庫(board-support crates)。驅動程式函式庫為特定的裝置類別(如感測器、資料機、LCD控制器等)提供平台無關的支援。板級支援程式函式庫則為特定的開發板提供支援。

許多Rust開發者也接受了用Rust建立或擴充套件作業系統的挑戰。其中一個相對成熟的作業系統是Redox OS(圖10-1),它採用了微核心架構。目前已經有GUI和一些有用的應用程式在其上執行。還有Tock,它針對的是具有低記憶體和低功耗限制的物聯網(IoT)裝置。另一個最近的低階開源Rust-based OS是Oxide Computer Company開發的Hubris。最後(也可能是最重要的),Rust已經成為繼C之後第一個被加入Linux核心的語言,從編寫驅動程式開始。

使用Rust進行作業系統開發

有多個使用Rust開發的作業系統,例如用於教學目的Blog OS,還有一些較不活躍的作業系統採用了根據語言的方法,也就是專注於建立一個能夠執行Rust程式的最小作業系統。

雲端運算

在第6章中,你使用Rust在AWS雲端建立了一個應用程式。但你知道嗎,構成AWS雲端的一部分服務也是用Rust建立的?例如,Firecracker VM,一種輕量級虛擬化技術,為AWS Lambda和AWS Fargate提供支援,就是用Rust編寫的。Firecracker中啟動的微虛擬機器(microVMs)具有快速啟動時間和低記憶體開銷,而不會犧牲安全或效率。

AWS還開發了Bottlerocket,一個根據Linux的作業系統,專門用於執行容器。你可以在執行容器的主機上使用它。它只包含了執行容器所需的必要軟體,因此減少了攻擊面並提高了安全性。它也是用Rust編寫的。

AWS Nitro Enclaves是另一個使用Rust的服務。AWS Nitro Enclaves允許你在Amazon Elastic Compute Cloud(Amazon EC2)例項中建立隔離的運算環境。透過在Nitro Enclave中執行最敏感的資料處理應用程式,如涉及個人可識別資訊(PII)、財務和醫療保健詳細資訊的應用程式,你可以提高應用程式的安全性。

正如你所見,Rust在建立雲端運算的安全應用程式方面扮演著重要的角色。其他服務,如Amazon Simple Storage Service(Amazon S3)、Amazon Elastic Compute Cloud(Amazon EC2)和Amazon CloudFront也在內部使用Rust。

區塊鏈和加密貨幣

由於Rust的安全性和效能,它在區塊鏈和加密貨幣領域引起了廣泛關注。在區塊鏈中使用Rust有兩個層級:使用Rust建立區塊鏈本身,或使用Rust在區塊鏈上編寫智慧合約。

有多個知名區塊鏈是用Rust建立的:Solana、Polkadot和Hyperledger Sawtooth。失敗的加密貨幣Diem(前身為Libra,由Meta建立)也是用Rust建立的。

這些區塊鏈也允許你用Rust編寫智慧合約。這些智慧合約在區塊鏈的虛擬機器中執行,大多數時候需要將其跨編譯成WebAssembly或自定義位元組碼格式。例如,NEAR Protocol允許你使用ink!,一種嵌入式領域特定語言(DSL),讓你可以用Rust編寫智慧合約。Solana也允許你用Rust編寫其智慧合約(稱為Programmes)。

Rust 的無限可能性

除了前幾章討論的主題外,Rust 還有許多其他應用。以下是一個非詳盡的清單:

  • 壓縮
  • 密碼學與安全:ring、openssl、sodiumoxide
  • 資料函式庫實作
  • 模擬器:遊戲主機和其他硬體
  • 多媒體:影像、音訊和視訊處理;2D/3D 內容渲染
  • 語言解析器
  • 科學應用:數學、生物資訊學(例如 Rust-Bio)、地理資訊、物理和化學模擬

Rust 是一個用於建構幾乎任何型別應用的絕佳工具。雖然目前某些領域可能尚未擁有成熟的生產就緒 Rust 函式庫或使用者基礎,但憑藉熱情友善的社群支援,我們可以期待看到更多 Rust 的應用。從在低功耗微控制器上執行的迷你物聯網感測器,到在龐大超級電腦上執行的尖端人工智慧,Rust 的未來是廣闊且光明的。

區塊鏈與 Rust

區塊鏈是一個快速發展的領域。你可以透過 Rust 區塊鏈專案的精選清單 Awesome Blockchain Rust 和新聞通訊(如 Rust in Blockchain)關注最新的發展。

Rust 在不同領域的應用

人工智慧與機器學習

Rust 可以用於建構人工智慧和機器學習模型,例如人工神經網路(ANN)模型。

網頁開發

Rust 可以用於建構網頁應用,例如使用 Actix-web 框架。

遊戲開發

Rust 可以用於建構遊戲,例如使用 Bevy 遊戲引擎。

命令列介面

Rust 可以用於建構命令列介面(CLI)工具,例如使用 Clap 函式庫。

程式碼範例:使用 Bevy 建構遊戲
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_startup_system(setup)
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn(Camera2dBundle::default());
}

內容解密:

  • use bevy::prelude::*;:匯入 Bevy 的預設模組。
  • fn main() { ... }:定義程式的入口點。
  • App::new():建立一個新的 Bevy 應用。
  • .add_plugins(DefaultPlugins):新增預設的外掛程式。
  • .add_startup_system(setup):新增一個啟動系統,該系統將在應用啟動時執行。
  • commands.spawn(Camera2dBundle::default());:產生一個 2D 相機。

這個範例展示瞭如何使用 Bevy 建構一個簡單的遊戲。Bevy 是一個強大的遊戲引擎,提供了許多功能,例如圖形渲染、輸入處理和音訊播放。這個範例建立了一個新的 Bevy 應用,並新增了一個 2D 相機。