编写 Rust 文档

更新于 2026-01-17

Maksim Gritchin 2024-06-12

编写有效的文档对于任何编程语言都至关重要,Rust 也不例外。良好的文档能帮助用户理解如何使用你的代码、它的功能以及为何它如此重要。在本指南中,我将带你了解在 Rust 中编写文档的最佳实践,确保你的代码不仅功能完善,而且易于访问和使用。

Rust 文档简介

Rust 文档通常使用 rustdoc 工具编写,该工具可以从源代码中的注释生成 HTML 格式的文档。rustdoc 的主要目标是让像你我这样的开发者能够以一种全面且易于理解的方式为代码编写文档。

为什么文档很重要

文档具有以下几个关键作用:

  • 沟通:解释你的代码做了什么、如何工作以及如何使用。
  • 维护:帮助未来的开发者(包括你自己)理解代码库,使其更易于维护和扩展。
  • 入职培训:帮助新团队成员快速熟悉项目。
  • 社区支持:让更广泛的社区能够使用并贡献你的项目。

在 Rust 中编写文档

为代码添加注释

Rust 使用三种类型的注释来编写文档:

  • 行注释:以 // 开头,用于简短的单行注释。
  • 块注释:用 /* ... */ 包裹,可以跨越多行。
  • 文档注释
    • /// 开头,用于项级别(item-level)文档;
    • //! 开头,用于模块级别(module-level)文档。

项级别文档

项级别文档注释(///)用于描述函数、结构体、枚举、trait 以及其他项。这些注释应直接放在所描述项的上方。

在这个例子中,add 函数通过简要描述和使用示例进行了文档说明。# Examples(示例)部分是 Rust 文档中的常见约定,提供了一种清晰简洁的方式来演示用法。

模块级别文档

模块级别文档注释(//!)用于描述模块的整体目的和功能。这些注释应放在模块文件的顶部。

在这里,模块级别的注释提供了模块用途的高层概述,而项级别的注释则描述了各个函数。

组织你的文档结构

好的文档结构清晰、易于导航。以下是一些组织 Rust 文档的建议:

  • 使用章节:使用标题将文档划分为多个章节。常见章节包括 # Examples(示例)、# Panics(恐慌)、# Errors(错误)和 # Safety(安全性)。
  • 提供示例:示例是展示如何使用代码最有效的方式之一。尽可能包含它们。
  • 解释边界情况:记录用户需要注意的任何边界情况或特殊条件。
  • 链接相关项:使用内联文档链接(intra-doc links)连接文档中的相关项,帮助用户更轻松地浏览文档。

使用章节

章节有助于组织文档,使其更易于阅读。以下是你可能包含的一些常见章节:

  • Examples:展示如何使用该项。
  • Panics:描述可能导致该项发生 panic 的条件。
  • Errors:解释可能返回的错误。
  • Safety:对于不安全代码,解释为何它是安全的。

在这个例子中,divide 函数的文档包含一个 # Examples 章节来展示函数的使用方法,以及一个 # Panics 章节来描述会导致函数 panic 的条件。

提供示例

示例对于帮助用户理解如何使用你的代码至关重要。它们应当简单、清晰,并展示最常见的使用场景。

这个示例展示了如何计算一个数的阶乘,为 factorial 函数的使用提供了清晰简洁的演示。

解释边界情况

边界情况是指在正常操作条件之外发生的情形。记录这些情况有助于用户理解你的代码在不太常见场景下的行为。

在这个例子中,fibonacci 函数的文档包含一个 # Panics 章节,解释当输入值过大时函数会 panic。

链接到相关项

内联文档链接(intra-doc links)允许你在文档中创建指向其他项的超链接。这有助于用户更轻松地浏览你的文档。

在这个例子中,addsubtract 函数通过内联文档链接相互引用,使用户可以轻松在相关项之间导航。

使用 #[doc] 属性

Rust 中的 #[doc] 属性为编写文档提供了额外的灵活性。你可以用它以更程序化的方式为项添加文档。当你需要动态生成文档,或者希望包含与特定项无直接关联的文档时,这个属性特别有用。

基本用法

#[doc] 属性可用于为任何项添加文档。以下是一个简单示例:

#[doc = "Adds two numbers together."]
fn add(a: i32, b: i32) -> i32 {
    a + b
}

这等价于使用 /// 注释风格,但允许处理更复杂的场景。

包含外部文件

你可以使用 #[doc] 属性从外部文件包含文档。如果你有大量文档内容希望与代码分离,这非常有用。

#[doc = include_str!("docs/add_function.md")]
fn add(a: i32, b: i32) -> i32 {
    a + b
}

在此示例中,add 函数的文档是从一个外部 Markdown 文件中包含进来的。

条件性文档

#[doc] 属性还可以用于根据编译时条件有条件地包含文档。这对于记录平台特定的行为或特性非常有用。

#[cfg(target_os = "windows")]
#[doc = "This function is only available on Windows."]
fn windows_only_function() {
    // Windows-specific code
}

#[cfg(target_os = "linux")]
#[doc = "This function is only available on Linux."]
fn linux_only_function() {
    // Linux-specific code
}

在此示例中,根据目标操作系统不同,会包含不同的文档。

编写文档的最佳实践

以下是编写 Rust 文档时应牢记的一些最佳实践:

  • 清晰简洁:用清晰简洁的方式写作。避免不必要的术语,保持句子简短明了。
  • 语法和拼写正确:确保文档没有语法和拼写错误。这有助于保持专业的外观。
  • 保持一致性:在整个文档中使用一致的术语和格式。这使用户更容易理解和遵循。
  • 保持更新:定期更新文档以反映代码的变化。过时的文档可能比没有文档更有害。
  • 使用代码示例:尽可能包含代码示例。它们是展示如何使用代码最有效的方式之一。
  • 为所有公共项编写文档:确保所有公共项(函数、结构体、枚举等)都有文档。这有助于用户理解如何使用你的库或应用程序。

综合文档示例

让我们通过一个综合示例将上述内容整合起来:

在此示例中,模块级注释提供了模块的概述,每个函数都配有描述、示例以及相关的 panic 说明。

文档测试

Rust 文档系统的一个强大功能是在文档注释中直接包含测试。这些被称为文档测试(documentation tests),具有双重作用:它们既提供了代码使用示例,又确保随着代码演进,这些示例始终保持正确。

编写文档测试

要编写文档测试,只需在文档注释中使用三个反引号(```)包裹代码示例即可。当你运行 cargo test 时,Rust 的 rustdoc 工具会自动提取这些示例并作为测试运行。

以下是一个基本示例:

/// Adds two numbers together.
///
/// # Examples
///
/// ```
/// let result = add(2, 3);
/// assert_eq!(result, 5);
/// ```
fn add(a: i32, b: i32) -> i32 {
    a + b
}

在此示例中,三个反引号内的代码就是一个文档测试。当你运行 cargo test 时,这段代码会被编译并执行,以确保产生预期结果。

文档测试的好处

  • 确保准确性:文档测试确保你的示例始终准确且最新。如果你更改代码导致示例失效,测试将失败,提醒你存在问题。
  • 提供可工作的示例:用户可以确信文档中的示例确实有效,因为它们会随代码一起测试。
  • 减少维护成本:通过将测试嵌入文档,你减少了对单独示例代码文件的需求,从而更容易保持代码与其文档之间的一致性。

高级用法

你还可以在文档测试中包含多个示例和更复杂的场景。此外,你可以使用属性来控制这些测试的行为。

例如,你可能希望忽略某些测试,或仅在特定条件下运行它们:

/// # Examples
///
/// ```
/// let result = divide(10, 2);
/// assert_eq!(result, 5);
/// ```
///
/// ```should_panic
/// // This test demonstrates a panic scenario and is marked to expect a panic.
/// divide(10, 0);
/// ```
fn divide(a: i32, b: i32) -> i32 {
    if b == 0 {
        panic!("Division by zero!");
    }
    a / b
}

在此示例中,第二个测试被标记为 should_panic,因为它演示了一个 panic 场景。你可以使用 ignore 属性防止某些测试默认运行。

运行文档测试

要运行文档测试,只需使用 cargo test 命令。这将编译并运行所有测试,包括嵌入在文档注释中的测试。

cargo test

通过将文档测试纳入你的工作流程,你可以确保文档始终保持准确和有用,为代码用户提供真正的价值。

结论

编写良好的文档是每位 Rust 开发者必备的重要技能。通过遵循本指南中概述的最佳实践,你可以创建清晰、简洁且对用户有帮助的文档。记住使用 rustdoc 生成文档,并在代码演进过程中保持其更新。有了精心编写的文档,你的代码将更加易于访问、维护和使用。