#[doc] 属性

#[doc] 属性允许您控制 rustdoc 完成其工作方式的各个方面。

#[doc] 的最基本功能是处理实际的文档文本。也就是说,///#[doc] 的语法糖。这意味着这两个是相同的

#![allow(unused)]
fn main() {
/// This is a doc comment.
#[doc = r" This is a doc comment."]
fn f() {}
}

(注意属性版本中的前导空格和原始字符串文字。)

在大多数情况下,///#[doc] 更易于使用。在宏中生成文档时,后者更容易使用的一种情况是;collapse-docs 传递将多个 #[doc] 属性合并为单个文档注释,让您生成如下代码

#![allow(unused)]
fn main() {
#[doc = "This is"]
#[doc = " a "]
#[doc = "doc comment"]
fn f() {}
}

这可能感觉更灵活。请注意,这将生成以下内容

#![allow(unused)]
fn main() {
#[doc = "This is\n a \ndoc comment"]
fn f() {}
}

但鉴于文档是通过 Markdown 渲染的,它将删除这些换行符。

另一个用例是将外部文件作为文档包含在内

#![allow(unused)]
fn main() {
#[doc = include_str!("../../README.md")]
fn f() {}
}

doc 属性还有更多选项!这些不涉及输出文本,而是输出呈现的各个方面。我们已将它们分为以下两种类型:在板条箱级别有用的属性,以及在项目级别有用的属性。

在板条箱级别

这些选项控制文档在板条箱级别的外观。

html_favicon_url

这种形式的 doc 属性允许您控制文档的 favicon。

#![allow(unused)]
#![doc(html_favicon_url = "https://example.com/favicon.ico")]
fn main() {
}

这将在您的文档中放入 <link rel="icon" href="{}">,其中属性的字符串将进入 {}

如果您不使用此属性,则不会有 favicon。

html_logo_url

这种形式的 doc 属性允许您控制文档左上角的徽标。

#![allow(unused)]
#![doc(html_logo_url = "https://example.com/logo.jpg")]
fn main() {
}

这将在您的文档中放入 <a href='../index.html'><img src='{}' alt='logo' width='100'></a>,其中属性的字符串将进入 {}

如果您不使用此属性,则不会有徽标。

html_playground_url

这种形式的 doc 属性允许您控制文档示例中的“运行”按钮向何处发出请求。

#![allow(unused)]
#![doc(html_playground_url = "https://playground.example.com/")]
fn main() {
}

现在,当您按下“运行”时,该按钮将向该域发出请求。请求 URL 将包含 2 个查询参数:codeedition,分别用于文档中的代码和 Rust 版本。

如果您不使用此属性,则不会有运行按钮。

issue_tracker_base_url

这种形式的 doc 属性主要仅对标准库有用;当一个功能不稳定时,必须给出跟踪该功能的 issue 号码。rustdoc 使用此号码加上此处给出的基本 URL 来链接到跟踪 issue。

#![allow(unused)]
#![doc(issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
fn main() {
}

html_root_url

#[doc(html_root_url = "…")] 属性值指示用于生成指向外部板条箱的链接的 URL。当 rustdoc 需要生成指向外部板条箱中项目的链接时,它将首先检查外部板条箱是否已在本地磁盘上进行过文档化,如果是,则直接链接到它。如果没有,它将使用 --extern-html-root-url 命令行标志给出的 URL(如果可用)。如果不可用,则它将使用外部板条箱中的 html_root_url 值(如果可用)。如果不可用,则不会链接外部项目。

#![allow(unused)]
#![doc(html_root_url = "https://docs.rs/serde/1.0")]
fn main() {
}

html_no_source

默认情况下,rustdoc 将包含程序的源代码,并在文档中链接到它。但是,如果您包含以下内容

#![allow(unused)]
#![doc(html_no_source)]
fn main() {
}

它不会。

test(no_crate_inject)

默认情况下,rustdoc 将自动在每个 doctest 中添加一行 extern crate my_crate;。但是,如果您包含以下内容

#![allow(unused)]
#![doc(test(no_crate_inject))]
fn main() {
}

它不会。

test(attr(...))

这种形式的 doc 属性允许您向所有 doctest 添加任意属性。例如,如果您希望 doctest 在产生任何警告时失败,您可以添加以下内容

#![allow(unused)]
#![doc(test(attr(deny(warnings))))]
fn main() {
}

在项目级别

这些形式的 #[doc] 属性用于单个项目,以控制它们是如何记录的。

inlineno_inline

这些属性用于 use 语句,并控制文档显示的位置。例如,考虑以下 Rust 代码

pub use bar::Bar;

/// bar docs
pub mod bar {
    /// the docs for Bar
    pub struct Bar;
}
fn main() {}

该文档将生成一个“重新导出”部分,并说 pub use bar::Bar;,其中 Bar 是指向其页面的链接。

如果我们像这样更改 use

#[doc(inline)]
pub use bar::Bar;
pub mod bar { pub struct Bar; }
fn main() {}

相反,Bar 将出现在 Structs 部分,就像 Bar 在顶层定义一样,而不是 pub use'd。

让我们通过将 bar 设置为私有来更改原始示例

pub use bar::Bar;

/// bar docs
mod bar {
    /// the docs for Bar
    pub struct Bar;
}
fn main() {}

在这里,因为 bar 不是公共的,所以 bar 不会有自己的页面,因此没有地方可以链接到。rustdoc 将内联这些定义,因此我们最终与上面的 #[doc(inline)] 相同;BarStructs 部分,就像它在顶层定义一样。如果我们添加 no_inline 形式的属性

#[doc(no_inline)]
pub use bar::Bar;

/// bar docs
mod bar {
    /// the docs for Bar
    pub struct Bar;
}
fn main() {}

现在我们将有一行 Re-exports,并且 Bar 不会链接到任何地方。

一个特殊情况:在 Rust 2018 及更高版本中,如果您 pub use 您的依赖项之一,rustdoc 不会急切地将其内联为模块,除非您添加 #[doc(inline)]

如果您想了解更多关于内联规则的信息,请查看 re-exports 章节

hidden

任何使用 #[doc(hidden)] 注释的项目都不会出现在文档中,除非 strip-hidden 传递被删除。重新导出的项目,其中其祖先之一具有 #[doc(hidden)],将被视为与私有项目相同。

您可以在 re-exports 章节 中找到更多信息。

alias

此属性在搜索索引中添加别名。

让我们举个例子

#![allow(unused)]
fn main() {
#[doc(alias = "TheAlias")]
pub struct SomeType;
}

因此,现在,如果您在搜索中输入“TheAlias”,它将显示 SomeType。当然,如果您输入 SomeType,它将按预期返回 SomeType

FFI 示例

此文档属性在编写 C 库的绑定时特别有用。例如,假设我们有一个看起来像这样的 C 函数

int lib_name_do_something(Obj *obj);

它接受指向 Obj 类型的指针并返回一个整数。在 Rust 中,它可能写成这样

pub struct Obj {
    inner: *mut ffi::Obj,
}

impl Obj {
    pub fn do_something(&mut self) -> i32 {
        unsafe { ffi::lib_name_do_something(self.inner) }
    }
}

该函数已转换为方法,以使其更方便使用。但是,如果您想查找 lib_name_do_something 的 Rust 等效项,您将无能为力。

为了解决此限制,我们只需在 do_something 方法上添加 #[doc(alias = "lib_name_do_something")],然后一切就都好了!用户现在可以直接在我们的板条箱中查找 lib_name_do_something 并找到 Obj::do_something