Rustdoc 搜索

在搜索栏中输入内容会立即搜索可用的文档,匹配项目的名称和路径,或函数的近似类型签名。

按名称搜索

要按项目的名称搜索(项目包括模块、类型、特征、函数和宏),请写入其名称或路径。作为特殊情况,路径中通常由:: 双冒号分隔的部分可以用空格分隔。例如

  • vec newvec::new 都将函数std::vec::Vec::new 作为结果显示。
  • vecvec vecstd::vecstd::vec::Vec 都将结构体std::vec::Vec 本身包含在结果中(除了最后一个之外,所有结果还包括模块)。

作为快速缩减结果列表的方法,搜索输入下方有一个下拉选择器,标记为“结果在 [std] 中”。单击它可以更改正在搜索的板条箱。

Rustdoc 使用模糊匹配函数,可以容忍此处的拼写错误,但它基于输入的名称长度,因此一个很好的示例是 HahsMap。为避免这种情况,请将项目用引号括起来,搜索"HahsMap"(在此示例中,不会返回任何结果)。

按名称搜索界面中的选项卡

实际上,再次使用 HahsMap 作为示例,它告诉您默认情况下使用“在名称中”,但也列出了板条箱下拉菜单下方的另外两个选项卡:“在参数中”和“在返回值中”。

这两个选项卡是函数列表,定义在与搜索最匹配的类型上(对于HahsMap,它会自动更正为hashmap)。这种自动更正只有在没有找到与字面值匹配的内容时才会生效。

这些选项卡不仅仅是方法。例如,在 alloc 板条箱中搜索 Layout 也会列出接受布局的函数,即使它们是分配器上的方法或自由函数。

按函数的类型签名搜索

如果您更具体地知道要查看的函数的作用,Rustdoc 可以通过一次搜索参数和返回值中的多个类型来进行搜索。多个参数用, 逗号分隔,返回值用-> 箭头分隔。

在更详细地描述语法之前,这里有一些标准库的示例搜索和结果列表中包含的函数

查询结果
usize -> vecslice::repeatVec::with_capacity
vec, vec -> boolVec::eq
option<T>, fnonce -> option<U>Option::mapOption::and_then
option<T>, (fnonce (T) -> bool) -> option<T>Option::filter
option<T>, (T -> bool) -> option<T>Option::filter
option -> defaultOption::unwrap_or_default
stdout, [u8]Stdout::write
any -> !panic::panic_any
vec::intoiter<T> -> [T]IntoIter::as_sliceIntoIter::next_chunk
iterator<T>, fnmut -> TIterator::reduceIterator::find

基于类型的搜索工作原理

在复杂的基于类型的搜索中,Rustdoc 始终将每个项目的名称视为字面值。如果使用了一个名称,并且文档中没有任何内容与单个项目匹配,例如拼写错误的 uize -> vec 搜索,则项目uize 将被视为泛型类型参数(导致vec::from 和其他泛型 vec 构造函数)。

在确定哪些项目是类型参数,哪些是实际类型后,它将通过匹配函数参数(写在-> 之前)和返回值(写在-> 之后)来进行搜索。类型匹配与顺序无关,允许省略查询中的项目,但查询中存在的项目必须存在于函数中才能匹配。self 参数与任何其他参数的处理方式相同,Self 将解析为底层类型的名称。

函数签名搜索可以查询泛型,用尖括号括起来,如果没有任何类型参数与特征匹配,特征将在搜索引擎中像类型一样被规范化。例如,具有签名fn my_function<I: Iterator<Item=u32>>(input: I) -> usize 的函数可以使用以下查询匹配

  • Iterator<Item=u32> -> usize
  • Iterator<u32> -> usize(您可以省略Item= 部分)
  • Iterator -> usize(您可以省略迭代器的泛型)
  • T -> usize(您可以使用泛型参数匹配)

上述每个查询都逐渐变得更宽松,但最后一个查询不会匹配dyn Iterator,因为它不是类型参数。

如果一个边界具有多个关联类型,指定名称允许您选择要匹配的类型。如果未指定名称,则查询将匹配任何关联类型。例如,

#![allow(unused)]
fn main() {
pub trait MyTrait {
    type First;
    type Second;
}

/// This function can be found using the following search queries:
///
///     MyTrait<First=u8, Second=u32> -> bool
///     MyTrait<u32, First=u8> -> bool
///     MyTrait<Second=u32> -> bool
///     MyTrait<u32, u8> -> bool
///
/// The following queries, however, will *not* match it:
///
///     MyTrait<First=u32> -> bool
///     MyTrait<u32, u32> -> bool
pub fn my_fn(x: impl MyTrait<First=u8, Second=u32>) -> bool { true }
}

泛型和函数参数与顺序无关,但对嵌套和匹配数量敏感。例如,具有签名fn read_all(&mut self: impl Read) -> Result<Vec<u8>, Error> 的函数将匹配以下查询

  • Read -> Result<Vec<u8>, Error>
  • Read -> Result<Error, Vec>
  • Read -> Result<Vec<u8>>
  • Read -> u8

但它匹配Result<Vec, u8>Result<u8<Vec>>

要搜索接受函数作为参数的函数,例如Iterator::all,请将嵌套签名用括号括起来,如 Iterator<T>, (T -> bool) -> bool。您也可以搜索特定的闭包特征,例如Iterator<T>, (FnMut(T) -> bool) -> bool,但您需要知道要搜索哪个特征。

具有特殊语法的基本类型

简写显式名称
[]primitive:slice 和/或 primitive:array
[T]primitive:slice<T> 和/或 primitive:array<T>
()primitive:unit 和/或 primitive:tuple
(T)T
(T,)primitive:tuple<T>
!primitive:never
(T, U -> V, W)fn(T, U) -> (V, W)FnFnMutFnOnce

当搜索[] 时,Rustdoc 将返回包含切片或数组的搜索结果。如果您知道要搜索哪种类型,可以使用显式名称语法强制它返回primitive:sliceprimitive:array 的结果。空方括号[] 将匹配任何切片或数组,无论它包含什么,或者可以提供项目类型,例如[u8][T],以明确找到分别对字节切片或泛型切片进行操作的函数。

用括号括起来的单个类型表达式与该类型表达式相同,因为括号充当分组运算符。如果它们为空,则它们将匹配unittuple,如果存在多个类型(或尾随或前导逗号),则它与primitive:tuple<...> 相同。

但是,由于可以省略查询中的项目,因此(T) 仍然会返回与元组匹配的类型的结果,即使它也与类型本身匹配。也就是说,(u32)(u32,) 匹配的原因与它也与Result<u32, Error> 匹配的原因相同。

-> 运算符的优先级低于逗号。如果它没有用括号括起来,它将分隔正在搜索的函数的返回值。要搜索接受函数作为参数的函数,请使用括号。

基于类型的搜索仍然是一个有错误的、实验性的、正在进行的功能。这些限制中的大多数应该在未来的 Rustdoc 版本中得到解决。

  • 无法在泛型参数上编写特征约束。您可以直接命名特征,如果存在具有该边界的类型参数,它将匹配,但option<T> -> T where T: Default 无法精确搜索(使用option<Default> -> Default)。

  • 超特征、类型别名和 Deref 都被忽略。搜索主要针对按字面意思 编写类型签名,而不是它们在编译器中的表示方式。

  • 类型参数匹配类型参数,因此Option<A> 匹配Option<T>,但永远不会匹配函数签名中的具体类型。以特征名称命名的类型,例如Option<Read>,将匹配受该特征约束的类型参数,例如Option<T> where T: Read,以及匹配dyn Traitimpl Trait

  • impl Trait 在参数位置的处理方式与类型参数完全相同,但在返回值位置,它不会匹配类型参数。

  • 在复杂的基于类型的搜索中命名的任何类型,如果找不到与名称完全匹配的类型,都将被假定为类型参数。如果您想强制使用类型参数,请编写generic:T,即使找到匹配的名称,它也将用作类型参数。如果您知道您不想要类型参数,您可以通过赋予它不同的前缀来强制它匹配其他内容,例如struct:T

  • 无法搜索引用或指针。可以搜索包装类型,因此接受&File 的函数可以使用File 找到,但在搜索字段中输入& 时会收到解析错误。

  • 不支持搜索生命周期。

  • 无法根据数组的长度进行搜索。

项目过滤

搜索界面中的名称可以以冒号后缀的项目类型开头(例如mod:)以将结果限制为仅该类型的项目。此外,搜索println! 将搜索名为println 的宏,就像搜索macro:println 一样。完整的可用过滤器列表在 ? 帮助区域和下面的详细语法中给出。

项目过滤器可以在基于名称的搜索和基于类型签名的搜索中使用。

搜索查询语法

ident = *(ALPHA / DIGIT / "_")
path = ident *(DOUBLE-COLON ident) [BANG]
slice-like = OPEN-SQUARE-BRACKET [ nonempty-arg-list ] CLOSE-SQUARE-BRACKET
tuple-like = OPEN-PAREN [ nonempty-arg-list ] CLOSE-PAREN
arg = [type-filter *WS COLON *WS] (path [generics] / slice-like / tuple-like)
type-sep = COMMA/WS *(COMMA/WS)
nonempty-arg-list = *(type-sep) arg *(type-sep arg) *(type-sep) [ return-args ]
generic-arg-list = *(type-sep) arg [ EQUAL arg ] *(type-sep arg [ EQUAL arg ]) *(type-sep)
normal-generics = OPEN-ANGLE-BRACKET [ generic-arg-list ] *(type-sep)
            CLOSE-ANGLE-BRACKET
fn-like-generics = OPEN-PAREN [ nonempty-arg-list ] CLOSE-PAREN [ RETURN-ARROW arg ]
generics = normal-generics / fn-like-generics
return-args = RETURN-ARROW *(type-sep) nonempty-arg-list

exact-search = [type-filter *WS COLON] [ RETURN-ARROW ] *WS QUOTE ident QUOTE [ generics ]
type-search = [ nonempty-arg-list ]

query = *WS (exact-search / type-search) *WS

type-filter = (
    "mod" /
    "externcrate" /
    "import" /
    "struct" /
    "enum" /
    "fn" /
    "type" /
    "static" /
    "trait" /
    "impl" /
    "tymethod" /
    "method" /
    "structfield" /
    "variant" /
    "macro" /
    "primitive" /
    "associatedtype" /
    "constant" /
    "associatedconstant" /
    "union" /
    "foreigntype" /
    "keyword" /
    "existential" /
    "attr" /
    "derive" /
    "traitalias" /
    "generic")

OPEN-ANGLE-BRACKET = "<"
CLOSE-ANGLE-BRACKET = ">"
OPEN-SQUARE-BRACKET = "["
CLOSE-SQUARE-BRACKET = "]"
OPEN-PAREN = "("
CLOSE-PAREN = ")"
COLON = ":"
DOUBLE-COLON = "::"
QUOTE = %x22
COMMA = ","
RETURN-ARROW = "->"
EQUAL = "="
BANG = "!"

ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
DIGIT = %x30-39
WS = %x09 / " "