重新导出
让我们从解释什么是重新导出开始。为此,我们将使用一个例子,其中我们正在编写一个库(名为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)
将不会显示在文档中。