通过名称链接到条目
Rustdoc 能够使用项的路径作为链接直接链接到其他 rustdoc 页面。这被称为“文档内链接”。
例如,在以下代码中,所有链接都将链接到 Bar
的 rustdoc 页面
#![allow(unused)] fn main() { /// This struct is not [Bar] pub struct Foo1; /// This struct is also not [bar](Bar) pub struct Foo2; /// This struct is also not [bar][b] /// /// [b]: Bar pub struct Foo3; /// This struct is also not [`Bar`] pub struct Foo4; /// This struct *is* [`Bar`]! pub struct Bar; }
与普通的 Markdown 不同,[bar][Bar]
语法也支持,无需 [Bar]: ...
引用链接。
链接周围的反引号将被去除,因此 [`Option`]
将正确链接到 Option
。
有效的链接
你可以引用作用域内的任何内容,并使用路径,包括 Self
、self
、super
和 crate
。支持关联项(函数、类型和常量),但不支持 blanket trait 实现。Rustdoc 还支持链接到标准库文档中列出的所有基本类型。
你还可以引用带有泛型参数的项,如 Vec<T>
。该链接将解析为如同你写了 [`Vec<T>`](Vec)
。完全限定的语法(例如,<Vec as IntoIterator>::into_iter()
)尚不支持。
#![allow(unused)] fn main() { use std::sync::mpsc::Receiver; /// This is a version of [`Receiver<T>`] with support for [`std::future`]. /// /// You can obtain a [`std::future::Future`] by calling [`Self::recv()`]. pub struct AsyncReceiver<T> { sender: Receiver<T> } impl<T> AsyncReceiver<T> { pub async fn recv() -> T { unimplemented!() } } }
Rustdoc 允许使用 URL 片段说明符,就像普通的链接一样
#![allow(unused)] fn main() { /// This is a special implementation of [positional parameters]. /// /// [positional parameters]: std::fmt#formatting-parameters struct MySpecialFormatter; }
命名空间和消除歧义
Rust 中的路径有三个命名空间:类型、值和宏。项名称在其命名空间内必须是唯一的,但可以与其他命名空间中的项重叠。如果存在歧义,rustdoc 将警告该歧义并建议一个消除歧义器。
#![allow(unused)] fn main() { /// See also: [`Foo`](struct@Foo) struct Bar; /// This is different from [`Foo`](fn@Foo) struct Foo {} fn Foo() {} }
这些前缀在文档中显示时将被删除,因此 [struct@Foo]
将被渲染为 Foo
。以下前缀可用:struct
、enum
、trait
、union
、mod
、module
、const
、constant
、fn
、function
、field
、variant
、method
、derive
、type
、value
、macro
、prim
或 primitive
。
你还可以通过在函数名称后添加 ()
来消除函数的歧义,或通过在宏名称后添加 !
来消除宏的歧义。宏 !
后可以跟 ()
、{}
或 []
。示例
#![allow(unused)] fn main() { /// This is different from [`foo!()`]. fn foo() {} /// This is different from [`foo()`] macro_rules! foo { () => {} } }
有一种情况会自动执行消除歧义:如果一个文档内链接同时解析为一个 trait 和一个 derive proc-macro。在这种情况下,它将始终生成指向该 trait 的链接,而不会发出“缺少消除歧义”的警告。这种情况的一个很好的例子是当你链接到 Clone
trait 时:还有一个 Clone
proc-macro,但在这种情况下它会被忽略。如果你想链接到 proc-macro,你可以使用 macro@
消除歧义器。
警告、重新导出和作用域
链接在定义项的模块的作用域内解析,即使该项被重新导出。如果来自另一个 crate 的链接无法解析,则不会发出警告。
#![allow(unused)] fn main() { mod inner { /// Link to [f()] pub struct S; pub fn f() {} } pub use inner::S; // the link to `f` will still resolve correctly }
当重新导出一个项时,rustdoc 允许为其添加额外的文档。该额外文档将在重新导出的作用域内解析,而不是原始作用域,允许你链接到新 crate 中的项。如果新链接无法解析,仍然会发出警告。
#![allow(unused)] fn main() { /// See also [foo()] pub use std::process::Command; pub fn foo() {} }
这对于 proc-macros 尤其有用,它们必须始终在自己的专用 crate 中定义。
注意:由于 macro_rules!
宏在 Rust 中的作用域方式,macro_rules!
宏的文档内链接将相对于 crate 根目录解析,而不是定义它的模块。
如果链接看起来“不够像”文档内链接,它们将被忽略,并且不会发出警告,即使该链接无法解析。例如,任何包含 /
或 []
字符的链接都将被忽略。
如果无法生成文档内链接会发生什么
在某些情况下(例如,cfg
后面的项),无法生成指向项的文档内链接。有不同的方法可以在 markdown 中创建链接,根据你使用的方法,在这种情况下它的渲染方式会有所不同
1. [a]
2. [b][c]
3. [d](e)
4. [f]
[f]: g
1.
和 2.
将按原样显示在渲染的文档中(即,[a]
和 [b][c]
),而 3.
和 4.
将被替换为指向 e
的链接(对于 [d](e)
)和指向 g
的链接(对于 [f]
)。