用 cargo doc 生成文档
本教程共 78 篇 · 第 58 篇 · 更新于 2026-08-08 · 约 9 分钟阅读
本节目标:学会用
///和//!写文档注释,用cargo doc生成 HTML 文档并在浏览器查看,掌握常用文档标题,并理解文档里的示例代码会作为”文档测试”被真正运行。
好代码会说话,但用户不会去翻你的源码。他们看的是文档。Rust 把文档当成语言的一部分:你写注释,工具链就把注释变成网页。更妙的是,文档里的示例能当测试跑,代码改了文档示例会跟着报错——再也不用担心示例过期。
1-1 三类注释
Rust 的注释分三种:代码注释(给协作者看)、文档注释(给用户看,支持 Markdown 和示例)、包/模块注释(也是文档注释,说明整个包或模块)。本章重点在文档注释。
代码注释你早会了:// 行注释、/* ... */ 块注释。它们和别的语言没区别,写的时候记住八个字——围绕目标,言简意赅。
1-2 文档行注释 ///
文档注释用 ///,写在被注释项的上方。它支持 Markdown,还能内嵌可运行的示例代码:
/// 把传入的值加 1
///
/// # Examples
///
/// ```
/// let arg = 5;
/// let answer = my_crate::add_one(arg);
///
/// assert_eq!(6, answer);
/// ```
pub fn add_one(x: i32) -> i32 {
x + 1
}
几点要注意:
- 文档注释要写在
lib类型的包里(比如src/lib.rs或其子模块),二进制包main.rs里的文档不会被cargo doc重点收集。 - 注释里能用 Markdown,比如
# Examples是个标题,代码块会高亮。 - 被注释的对象要
pub对外可见。文档是给用户看的,内部实现细节不该暴露。
还有块形式的文档注释 /** ... */,内容多时少写几个 ///:
/** 把传入的值加 2
# Examples
```rust
let arg = 5;
let answer = my_crate::add_two(arg);
assert_eq!(7, answer);
```rust
*/
pub fn add_two(x: i32) -> i32 {
x + 2
}
1-3 生成并查看文档
写了注释,自然想看看网页长啥样。一行命令搞定:
cargo doc
它把 HTML 文档生成到 target/doc 目录。想生成完直接弹浏览器看,用:
cargo doc --open
Tip初次发库前,强烈建议
cargo doc --open自己审一遍文档。很多拼写错误、示例路径错、链接断,肉眼扫网页比扫源码容易发现。
1-4 包和模块级注释
除了函数、结构体,还能给整个包或模块加注释,而且注释要写在包/模块的最上方。用 //!(行)或 /*! ... */(块):
//! # Art
//!
//! 未来的艺术建模库,现在的调色库
pub mod kinds {
//! 定义颜色的类型
/// 主色
pub enum PrimaryColor {
Red,
Yellow,
Blue,
}
}
//! 注释的是”它所在的这个包或模块本身”,/// 注释的是”它下面的那一项”。这一上一下别搞反:模块说明用 //!,模块里某个函数用 ///。
1-5 常用文档标题
除了 # Examples,还有几个约定俗成的标题,建议在合适时写上:
- Panics:说明函数在什么情况下会 panic,让调用者提前规避。
- Errors:描述可能返回的错误及触发条件,方便调用者分情况处理。
- Safety:如果函数含
unsafe代码,说明调用者必须满足的前提条件。
这些标题是惯例不是强制,用中文也行,但团队内最好统一风格。
1-6 文档测试(Doc Test)
注意前面示例里的 assert_eq!——它不只是摆设,Rust 会把文档注释里的代码块当成单元测试运行。用 cargo test 时,输出里会有一栏 Doc-tests:
Doc-tests my_crate
running 2 tests
test src/lib.rs - add_one (line 3) ... ok
test src/lib.rs - add_two (line 9) ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.50s
这意味着:你的文档示例永远和代码同步。代码一改、示例不对,测试立刻红。这是 Rust 文档质量高的核心秘密。
Note文档测试在独立的线程里运行,所以示例代码里调用函数要用完整路径,比如
my_crate::add_one(arg),不能只写add_one(arg),否则找不到。
示例里也可以写会 panic 的代码,用 should_panic 标注让它通过:
/// # Panics
///
/// 除数为零时 panic。
///
/// ```rust,should_panic
/// my_crate::div(10, 0);
/// ```
pub fn div(a: i32, b: i32) -> i32 {
if b == 0 {
panic!("除以零");
}
a / b
}
想保留测试、但把某些辅助代码从文档里藏起来,用 # 开头那行:
/// ```
/// # fn try_main() -> Result<(), String> {
/// let res = my_crate::try_div(10, 2)?;
/// # Ok(())
/// # }
/// # fn main() { try_main().unwrap(); }
/// ```
# 开头的行依然会参与文档测试,但用户在网页上看不到,只看到那行没隐藏的 let res = ...。
1-7 文档里的链接跳转
文档注释还支持指向标准库或自己代码的链接。比如写 [Option] 会自动链到标准库的 Option;写 [crate::MyType] 会链到你自己的类型。遇到同名项,用 struct@Foo、fn@Foo、macro@foo 标明类型。再配合 #[doc(alias = "x")] 还能给类型设搜索别名,命中时排搜索结果第一位。
Tip写库时把文档和文档测试当”会跑的说明书”来写。用户第一眼看到的就是它,质量直接决定别人愿不愿意用你的包。
1-8 写好文档的几点建议
文档质量直接决定别人用不用你的库。几条实在的建议:
第一,示例优先。用户最想看的是”怎么用”,一段能跑的 Examples 比三段散文管用。而且因为文档示例会被当测试跑,它永远不会过期——这正是 Rust 文档口碑好的根本原因。
第二,公开的才写文档,私有的不写。文档是给用户看的,内部实现细节写了反而增加维护负担,还暴露不该暴露的东西。函数、结构体、枚举、trait、模块这些对外项,配上 /// 或 //! 就够。
第三,善用 Panics / Errors / Safety 标题。调用者最关心”什么情况下会崩""出错长啥样""unsafe 有啥前提”。把这些写清楚,能挡掉一大半 issue。
Tip文档测试失败会算进
cargo test的结果里。所以 CI 里跑cargo test其实同时验证了单元、集成、文档三类测试——一份命令,三重保险。
第四,别怕文档长。比起”太啰嗦”,新手更常犯的是”太省”。一个关键函数,把参数含义、返回值、边界情况都讲明白,用户在别处就少踩坑、也少来打扰你。
1-9 文档生成的位置与离线查看
生成的文档都在 target/doc 下,每个包一个子目录,入口是 index.html。如果你的包依赖了别的库,cargo doc 默认只生成你自己的文档;想连依赖的文档一起生成本地看,加 --no-deps 的反面——其实直接跑 cargo doc --open 最省事,它会一并处理好依赖文档的链接。
Note发布到 crates.io 后,docs.rs 会自动帮你构建并托管文档,别人不用下载你的源码就能在线看。所以本地
cargo doc主要是给你自己审稿用,确保示例能跑、链接不断、标题齐全,再发布就万无一失。
文档这件事,短期看是”给别人看的说明书”,长期看是”给未来的自己看的备忘录”。今天写得清楚的文档,三个月后救的可能是你自己的命。把文档测试当保险绳,代码一变它就叫,这种安全感值得养成。
下一章我们看两个陪你写代码的工具:rustfmt 和 clippy。