本文 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 語法,讓文件更易讀。 |
最佳實踐
- 在撰寫程式碼前先寫 doc comment:先思考使用者會怎麼呼叫,寫完再實作。
- 使用
cargo test --doc:專門測試文件中的範例,確保文件永遠不會過時。 - 分層文件:crate 層級 (
//!)、模組層級 (//!) 與項目層級 (///) 分別說明,形成清晰的結構。 - 自動化 CI:在 GitHub Actions、GitLab CI 等加入
cargo doc --no-deps --quiet,失敗即阻止合併。 - 善用 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 --doc與cargo doc --no-deps,讓你的 Rust 專案在文件品質上與程式碼品質同樣出色!