本文 AI 產出,尚未審核

Rust 課程:測試與文件

主題:發布文件(cargo doc


簡介

在軟體開發的全生命週期中,文件往往是最容易被忽視卻又最關鍵的部份。對於 Rust 專案而言,良好的 API 文件不僅能協助團隊成員快速上手,也能提升開源套件的可見度與使用率。Rust 官方提供的 cargo doc 指令,能自動從程式碼中的註解產生完整、可瀏覽的 HTML 文件,讓開發者只需要撰寫 doc comment///)即可得到專業的文件。

本篇文章將帶你從 安裝、產生、客製化部署 的完整流程,並提供實作範例與最佳實踐,幫助你在日常開發中自然養成撰寫文件的好習慣。


核心概念

1. 為什麼要使用 cargo doc

  • 自動化:一次指令即可從程式碼產生完整文件,省去手動撰寫 Markdown 或 HTML 的時間。
  • 同步性:文件與程式碼同時演進,避免「文件過時」的常見問題。
  • 標準化:產出的文件遵循 Rust 官方的風格,支援搜尋、交叉連結與程式碼範例高亮。

2. 基本使用方式

在專案根目錄執行:

cargo doc --open
  • --open 會在產生完畢後自動開啟瀏覽器。
  • 預設會產生 所有依賴套件 的文件,若只想產生本專案的文件,可加上 --no-deps

3. 撰寫 Doc Comment

Rust 使用三種形式的註解產生文件:

註解形式 說明 範例
/// 行內文件,會被視為該項目的說明。 /// 計算兩數相加的結果。
//! 模組或 crate 層級文件,放在檔案最上方。 //! 這是一個簡易的數學函式庫。
/** */ 多行文件,較少使用。 /** 多行說明 */

4. 常見的 Doc Comment 標記

  • 程式碼範例:使用三個反引號包住 Rust 程式碼,會自動在 cargo test 時執行驗證。
  • 標題:使用 Markdown 標題 (#, ## …) 形成層級結構。
  • 列表、表格:支援完整的 Markdown 語法。

5. 範例:從簡單函式到完整模組的文件

以下示範三個實用範例,說明如何在不同情境下撰寫文件,並搭配 cargo doc 產生結果。

範例 1️⃣ 基本函式的文件

/// 計算兩個 `i32` 數字的和。
///
/// # 範例
///
/// ```
/// let sum = my_crate::add(2, 3);
/// assert_eq!(sum, 5);
/// ```
///
/// # 錯誤處理
///
/// 此函式不會產生錯誤,只是簡單的加法運算。
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}
  • 說明:使用 /// 撰寫說明,加入 範例 區塊,讓讀者能直接看到使用方式。
  • 實務價值:範例會在 cargo test 時自動編譯,確保文件與程式碼同步。

範例 2️⃣ 模組層級文件與公開結構

//! 這個模組提供基本的向量運算功能,適用於 2D/3D 圖形程式設計。

/// 2 維向量
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Vec2 {
    /// X 座標
    pub x: f32,
    /// Y 座標
    pub y: f32,
}

impl Vec2 {
    /// 建立一個新的 `Vec2`。
    ///
    /// # 範例
    ///
    /// ```
    /// let v = my_crate::vec::Vec2::new(1.0, 2.0);
    /// assert_eq!(v.x, 1.0);
    /// assert_eq!(v.y, 2.0);
    /// ```
    pub fn new(x: f32, y: f32) -> Self {
        Self { x, y }
    }

    /// 計算向量的長度(歐氏距離)。
    ///
    /// # 範例
    ///
    /// ```
    /// let v = my_crate::vec::Vec2::new(3.0, 4.0);
    /// assert_eq!(v.length(), 5.0);
    /// ```
    pub fn length(&self) -> f32 {
        (self.x * self.x + self.y * self.y).sqrt()
    }
}
  • 說明:檔案最上方使用 //! 為模組提供概觀說明,結構體與方法各自使用 ///
  • 實務價值:對外公開的 API 必須有完整說明,讓使用者不必閱讀原始碼即可了解每個欄位與方法的意圖。

範例 3️⃣ 使用 #[doc(hidden)] 隱藏內部實作

/// 公開的函式,會顯示在文件中。
pub fn public_api() -> &'static str {
    "這是公開 API"
}

/// 內部使用的函式,不希望出現在文件中。
#[doc(hidden)]
fn internal_helper() -> i32 {
    42
}
  • 說明#[doc(hidden)] 可避免將不想讓使用者看到的實作細節曝光。
  • 實務價值:保持文件的乾淨與聚焦,避免混淆使用者。

6. 客製化文件產出

參數 功能 範例
--no-deps 只產生本 crate 的文件 cargo doc --no-deps
--features <list> 指定要啟用的 feature cargo doc --features "serde"
--document-private-items 也產生私有項目的文件(除非使用 #[doc(hidden)] cargo doc --document-private-items
--open 完成後自動開啟瀏覽器 cargo doc --open

小技巧:在 Cargo.toml 中加入 [package.metadata.docs.rs],可以在 docs.rs 上自動套用相同的設定,確保線上文件與本機產出一致。


常見陷阱與最佳實踐

陷阱 說明 解決方式
範例未編譯 cargo test 會執行文件中的程式碼範例,若範例錯誤會導致測試失敗。 務必在本機執行 cargo test,確保每段範例都能通過。
過度曝光私有實作 未加 #[doc(hidden)] 的私有函式仍會出現在文件中,增加噪音。 使用 #[doc(hidden)]#[allow(dead_code)] 只保留必要的說明。
忘記更新文檔 改動 API 後忘記同步更新 doc comment。 將文件更新列入 Pull Request 的必檢項目,或使用 CI 檢查 cargo doc --no-deps --quiet 是否成功。
文件過於冗長 把整個程式碼直接貼進說明,導致閱讀困難。 遵循「說明 + 範例」的結構,說明文字保持簡潔,範例僅展示關鍵步驟。
未使用 Markdown 直接寫純文字,失去標題、列表、表格等排版優勢。 熟悉基本 Markdown 語法,讓文件更易讀。

最佳實踐

  1. 在撰寫程式碼前先寫 doc comment:先思考使用者會怎麼呼叫,寫完再實作。
  2. 使用 cargo test --doc:專門測試文件中的範例,確保文件永遠不會過時。
  3. 分層文件:crate 層級 (//!)、模組層級 (//!) 與項目層級 (///) 分別說明,形成清晰的結構。
  4. 自動化 CI:在 GitHub Actions、GitLab CI 等加入 cargo doc --no-deps --quiet,失敗即阻止合併。
  5. 善用 feature:若 crate 有可選功能,使用 #[cfg(feature = "foo")] 並在文檔中說明啟用方式。

實際應用場景

場景 需求 cargo doc 的貢獻
開源套件發佈 讓使用者快速查閱 API。 產生可直接部署到 docs.rs,提供完整搜尋與交叉參照。
內部工具庫 團隊成員需要快速了解函式簽名與使用方式。 產生離線 HTML,放入內部 Wiki 或 CI 產出的 artefact。
教育訓練 教學範例必須保證可編譯。 使用文件範例自動測試,保證教材不會因版本升級而失效。
跨語言綁定 產出給其他語言的 FFI 介面說明。 #[doc = include_str!("...")] 中嵌入外部說明文件,保持一致性。
自動化部署 每次發佈都要同步更新文件。 結合 GitHub Actions:cargo doc --no-deps && gh-pages,自動發布至 GitHub Pages。

總結

  • cargo doc 是 Rust 生態系統中最強大的文件生成工具,只要撰寫 doc comment,就能得到 完整、可搜尋、支援程式碼範例的 HTML
  • 透過 Markdown程式碼範例 以及 #[doc(hidden)] 等技巧,我們可以讓文件保持 易讀、精準且不易過時
  • 常見陷阱 如範例未測試、私有項目過度曝光等,只要遵守 最佳實踐(先寫文件、CI 測試、分層說明),就能有效避免。
  • 無論是 開源發佈內部工具,或是 教學教材,適當運用 cargo doc 都能大幅提升開發效率與使用者體驗。

行動呼籲:從今天開始,為每一個公開的函式、結構體或模組加上完整的 doc comment,並在 CI 中加入 cargo test --doccargo doc --no-deps,讓你的 Rust 專案在文件品質上與程式碼品質同樣出色!