The Rust Programming Language (第2版)

「Rust 程式設計語言」是一本旨在介紹 Rust 語言的入門書籍,其核心主旨圍繞著 Rust 的設計理念、獨特的安全特性、以及如何使用其提供的工具和語法來建構可靠、高效的程式。根據提供的目錄及前幾章的內容,其主要論點可以歸納為以下幾個層面:

  1. Rust 的核心價值與定位:

    • 安全性 (Safety)、速度 (Speed) 與併發性 (Concurrency): Rust 的首要目標是讓程式設計師能夠編寫兼顧高效能與高安全性的程式碼。它強調記憶體安全,旨在消除諸如空指標引用、資料競爭等常見的執行時期錯誤。同時,作為一門系統程式語言,Rust 不使用垃圾回收器,這使得它在編譯時就能確定記憶體使用情況,從而實現與 C/C++ 相媲美的執行時期速度和資源控制能力。其設計也原生支援併發程式設計,並在編譯時防止許多與併發相關的錯誤。
    • 目標受眾: Rust 適合有 C/C++ 經驗的程式設計師,尋求更安全的系統程式替代方案;也適合有 Python 等高階語言經驗的程式設計師,希望在不犧牲表達性的前提下提升程式效能。
  2. 入門與開發環境:

    • 安裝與工具鏈 (Toolchain): 書中強調了使用官方推薦的 rustup 工具來安裝和管理 Rust 編譯器及其相關工具,這使得安裝和更新變得非常方便。
    • Cargo: 作為 Rust 的官方建構系統和套件管理器,Cargo 在 Rust 開發生態系統中扮演著核心角色。它用於建立專案 (cargo new)、管理依賴項(通過 Cargo.toml 檔案和 crates.io 生態系統)、編譯專案 (cargo build)、執行程式碼 (cargo run) 和執行測試 (cargo test)。Cargo 標準化了 Rust 專案的結構,極大地提高了開發效率和專案的可維護性。書中透過猜數字遊戲等專案範例,展示了如何從零開始使用 Cargo 建立、編寫、建構和執行 Rust 程式。
  3. 基本程式設計概念:

    • 變數與可變性: Rust 中的變數預設是不可變的 (immutable),這有助於編寫更安全的程式碼。要使變數可變,需要使用 mut 關鍵字。書中解釋了不可變性在編譯時提供的安全性保障。
    • 資料類型: Rust 具有豐富的內建資料類型,包括各種類型的整數(有號和無號,不同位元大小)、浮點數、布林值以及代表 Unicode 純量值的字元。Rust 是一種靜態類型語言,編譯器會進行嚴格的類型檢查,但在許多情況下可以通過類型推斷 (type inference) 自動確定類型。
    • 函式: 使用 fn 關鍵字定義。函式參數必須標註類型。函式可以返回值,返回值類型在參數列表後用 -> 標註。
    • 控制流程: 包括 ifelse ifelse 進行條件分支,以及 loopwhilefor 進行迴圈。書中強調 if 也是一個表達式,其結果可以賦值給變數。for 迴圈遍歷集合是 Rust 中常見且高效的方式。
  4. Rust 的核心特性:所有權 (Ownership):

    • 這是 Rust 最核心、最獨特的記憶體管理機制,無需垃圾回收器即可保證記憶體安全。所有權有三個基本規則:每個值都有一個所有者;同一時間只能有一個所有者;所有者離開作用域時,值會被丟棄。
    • 堆疊 (Stack) 與堆 (Heap): 書中解釋了 Rust 中值在堆疊和堆上的儲存方式對所有權行為的影響。大小已知且固定的值儲存在堆疊上,而大小可能變化或編譯時未知的值(如 String 的資料)儲存在堆上。所有權規則主要用於管理堆上的資料。
    • 移動 (Move) 與複製 (Copy): 預設情況下,將一個變數的值賦予另一個變數會發生「移動」,原變數失效,避免雙重釋放。對於實作了 Copy 特性的類型(如純量類型),賦值是「複製」,原變數仍然有效。
    • 借用 (Borrowing): 允許在不取得所有權的情況下使用值的引用(&&mut)。借用檢查器在編譯時強制執行借用規則,防止資料競爭和懸垂引用 (dangling reference)。借用是 Rust 安全併發和高效能的基礎之一。
    • 切片 (Slices): 是一種特殊的引用,允許引用集合(如 String 或陣列)中連續的部分,提供了安全訪問集合元素的機制。
  5. 結構化資料與行為:structenum

    • 結構體 (struct): 允許定義自訂的複合類型,將相關的、不同類型或相同類型的資料以具名欄位 (fields) 組合在一起,提高程式碼的清晰度和組織性。可以為結構體定義方法 (impl 區塊中的函式,第一個參數為 self 或其變體) 和關聯函式 (不接受 self 的函式)。
    • 列舉 (enum): 允許定義一個類型,其值限定於一組預先定義的變體 (variants) 之一。列舉變體可以有關聯資料,且不同變體可以有關聯不同類型和數量的資料。
    • 模式匹配 (match) 與 if let match 是一個強大的控制流程結構,用於將值與一系列模式進行比較,並根據匹配的模式執行對應程式碼。它常用於處理列舉變體並安全地存取其關聯資料。match 必須是窮盡的。if letmatch 的語法糖,用於只需匹配一個特定模式並忽略其他情況時,提供更簡潔的寫法。
  6. 錯誤處理 (Error Handling):

    • Rust 區分可恢復 (recoverable) 和不可恢復 (unrecoverable) 錯誤。不可恢復錯誤通常表示程式 bug,通過 panic! 宏停止執行。可恢復錯誤通常是預期可能發生的情況(如檔案未找到),通過 Result<T, E> 列舉來處理,ResultOk 變體表示成功並攜帶結果,Err 變體表示失敗並攜帶錯誤資訊。
    • 書中展示了如何使用 match 語句處理 Result,以及使用 unwrapexpect (在失敗時引起 panic!) 和 unwrap_or_else 等方法來簡化 Result 處理。
    • 錯誤傳播 (? 運算子): 介紹了 ? 運算子,用於在函式內部簡化錯誤處理並將錯誤傳播給呼叫者,前提是函式的返回值類型必須是 Result
  7. 模組系統 (Module System):

    • 使用 mod 關鍵字將程式碼組織成模組,建立命名空間。模組可以巢狀。
    • 可見性 (Visibility): Rust 中的項目(函式、類型、模組等)默認是私有的 (private)。使用 pub 關鍵字使其成為公開的 (public),可在其父模組外部被訪問。這支持了資訊隱藏和封裝。
    • 導入 (use): 使用 use 關鍵字將模組或模組內的特定項目引入當前作用域,簡化對這些項目的引用。pub use 可以將項目從一個模組重新導出到另一個模組(通常是父模組),以提供更方便的公共 API 結構。
  8. 集合 (Collections):

    • 介紹了 Rust 標準函式庫中的三個常用集合類型:
      • 向量 (Vec<T>): 可變大小、在堆上分配記憶體、儲存相同類型元素的有序列表。
      • 字串 (String): 在堆上分配記憶體、可變、可增長的 UTF-8 編碼字串類型。與 &str (字串切片,通常是不可變的引用,可能儲存在程式二進位檔案或堆上) 不同。Rust 不允許直接對 String 進行索引,以避免 UTF-8 編碼的複雜性帶來的錯誤。
      • 雜湊映射 (HashMap<K, V>): 在堆上分配記憶體、儲存鍵值對的集合,通過雜湊函數實現快速查找。鍵和值必須分別具有相同的類型。

總體而言,這本書的初期內容著重於建立 Rust 程式設計的基礎,從認識語言本身、使用其核心工具,到掌握其獨特的所有權系統和記憶體管理機制,再到學習如何使用結構體和列舉來建構自訂資料類型和行為,以及處理錯誤和組織程式碼。這些構成了編寫安全、高效、可靠 Rust 程式碼的堅實基礎。