#[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 个查询参数:code
和 edition
,分别用于文档中的代码和 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]
属性用于单个项目,以控制它们是如何记录的。
inline
和 no_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)]
相同;Bar
在 Structs
部分,就像它在顶层定义一样。如果我们添加 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
。