重新导出
让我们首先解释什么是重新导出。为此,我们将使用一个示例,其中我们正在编写一个库(名为 lib
),其中一些类型在子模块中分发
#![allow(unused)] fn main() { pub mod sub_module1 { pub struct Foo; } pub mod sub_module2 { pub struct AnotherFoo; } }
用户可以像这样导入它们
use lib::sub_module1::Foo;
use lib::sub_module2::AnotherFoo;
但是,如果您希望类型直接在 crate 根目录可用,或者我们不希望模块对用户可见怎么办?这就是重新导出发挥作用的地方
// `sub_module1` and `sub_module2` are not visible outside.
mod sub_module1 {
pub struct Foo;
}
mod sub_module2 {
pub struct AnotherFoo;
}
// We re-export both types:
pub use crate::sub_module1::Foo;
pub use crate::sub_module2::AnotherFoo;
现在用户将能够做到
use lib::{Foo, AnotherFoo};
由于 sub_module1
和 sub_module2
都是私有的,因此用户将无法导入它们。
现在有趣的是,为这个 crate 生成的文档将直接在 crate 根目录显示 Foo
和 AnotherFoo
,这意味着它们已被内联。有一些规则需要知道重新导出的项目是否会被内联。
内联规则
如果公共项目来自私有模块,它将被内联
mod private_module {
pub struct Public;
}
pub mod public_mod {
// `Public` will inlined here since `private_module` is private.
pub use super::private_module::Public;
}
// `Public` will not be inlined here since `public_mod` is public.
pub use self::public_mod::Public;
同样,如果项目从其任何祖先继承 #[doc(hidden)]
,它将被内联
#[doc(hidden)]
pub mod public_mod {
pub struct Public;
}
// `Public` be inlined since its parent (`public_mod`) has `#[doc(hidden)]`.
pub use self::public_mod::Public;
如果项目具有 #[doc(hidden)]
,它将不会被内联(也不会在生成的文档中可见)
// This struct won't be visible.
#[doc(hidden)]
pub struct Hidden;
// This re-export won't be visible.
pub use self::Hidden as InlinedHidden;
同样适用于重新导出本身:如果您有多个重新导出,其中一些具有 #[doc(hidden)]
,那么这些(并且只有这些)将不会出现在文档中
mod private_mod {
/// First
pub struct InPrivate;
}
/// Second
#[doc(hidden)]
pub use self::private_mod::InPrivate as Hidden;
/// Third
pub use self::Hidden as Visible;
在这种情况下,InPrivate
将被内联为 Visible
。但是,它的文档将是 First Third
而不是 First Second Third
,因为具有 Second
作为文档的重新导出具有 #[doc(hidden)]
,因此,它的所有属性都被忽略。
使用 #[doc(inline)]
内联
如果您想强制内联项目,可以使用 #[doc(inline)]
属性
pub mod public_mod {
pub struct Public;
}
#[doc(inline)]
pub use self::public_mod::Public;
使用此代码,即使 public_mod::Public
是公共的并且存在于文档中,Public
类型也将同时存在于 crate 根目录和 public_mod
模块中。
使用 #[doc(no_inline)]
阻止内联
与 #[doc(inline)]
属性相反,如果您想阻止内联项目,可以使用 #[doc(no_inline)]
mod private_mod {
pub struct Public;
}
#[doc(no_inline)]
pub use self::private_mod::Public;
在生成的文档中,您将在 crate 根目录看到一个重新导出,而不是直接看到类型。
属性
当项目被内联时,它的文档注释和大多数属性将与它一起被内联
mod private_mod {
/// First
#[cfg(a)]
pub struct InPrivate;
/// Second
#[cfg(b)]
pub use self::InPrivate as Second;
}
/// Third
#[doc(inline)]
#[cfg(c)]
pub use self::private_mod::Second as Visible;
在这种情况下,Visible
将具有 First Second Third
作为文档,并且还将具有 cfg
:#[cfg(a, b, c)]
。
文档内链接 相对于定义文档注释的位置解析。
但是,有一些属性不会被内联
#[doc(alias="")]
#[doc(inline)]
#[doc(no_inline)]
#[doc(hidden)]
(因为重新导出本身及其属性被忽略)。
所有其他属性在内联时都会被继承,以便文档与内联项目直接定义在显示它的位置的行为相匹配。
这些规则也适用于使用 glob 重新导出内联项目的情况
mod private_mod {
/// First
#[cfg(a)]
pub struct InPrivate;
}
#[cfg(c)]
pub use self::private_mod::*;
否则,显示的属性将来自重新导出的项目,而重新导出本身的属性将被忽略
mod private_mod {
/// First
#[cfg(a)]
pub struct InPrivate;
}
#[cfg(c)]
pub use self::private_mod::InPrivate;
在上述情况下,cfg(c)
不会在文档中显示。