文档是任何旨在被程序员社区广泛采用的、开源软件的一个非常重要的东西。若你的 代码是可读的,则能够告诉用户它的工作原理,但是文档应该告诉用户软件设计决策的原 因和方式,以及公共 API 的示例用法。文档化良好的代码和介绍全面的 README.md 页面 可以大大提高项目的可发现性。

Rust 社区非常重视文档,并提供各种级别的工具,以便编写代码文档。它对用户也 非常友好,生成的文档简洁、美观。对于编写文档,它支持 markdownmarkdown 是一 种非常流行的标记语言,是现在编写文档的标准。Rust 有一个名为 rustdoc 的专用工具, 可以解析 markdown 的文档注释,将它们转换成超文本标记语言(HyperText Markup Language,HTML)格式,并生成精美且可搜索的文档页面。


编写文档

为了编写文档,Rust 提供了表示文档注释开头的特殊符号。文档采用类似的方式编写, 但与普通代码文档注释相比,它们的处理方式不同,并且由 rustdoc 解析。文档注释分为两个层级,并使用单独的符号来标记文档注释的开头。

  • 元素级:这些注释适用于模块中的元素,例如结构体、枚举声明、函数及特征常量 等。它们应该出现在元素的上方。对于单行注释,它们以“///”开头,而对于多行 注释,则以“/*”开头,以“*/”结尾。
    • 这些注释直接应用于代码的具体元素,如函数、结构体、枚举、特征(trait)和常量等。它们通常用来解释单个元素的作用和使用方法。
  • 模块级:这些是出现在根层级的注释,例如 main.rslib.rs,以及其他任意模块, 可使用“//!”表示单行注释的开始,使用“/*!”表示多行注释的开始,并将“*/” 作为结尾标记。它们适用于概述软件包和某些示例。
    • 这些注释用于描述整个模块的功能和用途,比如在 **<font style="color:rgb(13, 13, 13);background-color:#FBDE28;">main.rs</font>****<font style="color:rgb(13, 13, 13);background-color:#FBDE28;">lib.rs</font>** 或任何自定义模块的顶部。它们为阅读源代码的人提供了关于模块整体功能和设计的高级概述。

在文档注释中,你可以使用通常的 markdown 语法编写文档。它还支持在倒引号中编 写有效的 Rust 代码(‘’’let a= 23 ; ‘’’),这将成为文档测试的一部分。

用于编写注释的上述表示方法实际上是#[doc="your doc comment"]属性的语法糖,它们 被称为文档属性(doc attribute)。当 rustdoc 解析包含“///”或“/*”符号的代码行时,将会 把它们转换成文档属性。此外,你也可以使用这些文档属性编写文档。


生成和查看文档

要生成文档,我们可以在项目目录中使用 cargo doc 命令。它使用一堆 HTML 文件和 预定义的样式表在 target/doc/目录中生成文档。默认情况下,它也会为软件包的依赖项生成 文档。我们可以通过运行 cargo doc --no-deps 命令告诉 Cargo 忽略生成依赖项的文档。

要查看文档,可以通过导航到 target/doc 目录下生成 HTTP 服务器来实现。Python 的简 单 HTTP 服务器在这里可以派上用场。但是,还有一个更好的办法来做到这一点,如将--open 参数传递给 cargo doc 命令将会在用户默认的浏览器中打开文档页面。

:::info 提示

可以将 cargo doccargo watch 搭配使用,以获得无缝 编写文档的体验,并在生成的页面上获得对项目中任 何文档更改的实时反馈。

:::

在你的项目目录中,使用下面的命令来启动 cargo watch,并让它在检测到文件变化时自动运行 cargo doc

<font style="color:rgb(13, 13, 13);">cargo watch -s "cargo doc"</font>

托管文档

生成文档后,你需要将其托管在某个地方供公众查看和使用。这里存在 3 种可能性。

  • docs.rs:托管在 crates.io 上的程序会自动生成说明文档,并托管到 docs.rs 上。
  • GitHub 页面:如果你的程序是托管在 GitHub 上的,那么可以将相关的说明文档作 为分支托管到 GitHub 页面上。
  • 外部网站:你可以管理自己的 Web 服务器用于托管文档。Rust 的标准库文档就是 一个很好的例子。

此外,如果你的项目文档多于两页,并需要详细介绍,那么生成类似书籍的文档更好。 这是通过使用 mdbook 项目完成的,与之有关的详情,可以访问其主页。

文档属性

之前我们提到编写的文档注释会转换成文档属性的形式。除此之外,还有其他文档属 性可以用于调整已生成的文档页面,这些属性可以应用在程序库级或元素级,可以写成 #[doc(key = value)]这样的形式。一些非常有用的文档属性如下所示。

软件包级属性

  • #![doc(html_logo_url = "image url"):用于在文档页面的左上角添加徽标(logo)。
  • #![doc(html_root_url = "https://docs.rs/slotmap/0.2.1")]:用于设置文档页面的统一资 源定位器(Uniform Resource Locator,URL)。
  • #![doc(html_playground_url = "https://play.rust-lang.org/")]:用于在文档中的代码示例 附近放置一个“Run”按钮,以便能够通过在线 Rust 工作台运行它。

元素级属性

  • #[doc(hidden)]:假定你已经为公共函数 foo 编写了文档作为自己的注释,但是不希 望该函数的使用者查看这些文档,那么可以使用此属性告知 rustdoc 忽略为 foo 生 成文档。
  • #[doc(include)]:用于引用来自其他文件的文档。如果文档很长,这有助于你将文 档和代码分开。