为了从图书馆 crate 中导出item,必须至少有一条通向它的路径,其中every组件是公共的.这意味着,你只需要将一个物品在你的 crate 中公开,而不是从 crate 中导出(从现在起,为了模仿C#术语,我将其称为"内部")就可以将其放在 crate 根目录下的一个私有模块中.
然而,这种解决方案是相当有限的.如果你想要一个包含导出函数和and个内部函数的模块呢?为了导出一些函数,我们需要将模块公开,这意味着该模块中的所有公共项也将被导出.
自Rust 1.18年以来,有一种解决方案适应了这种情况:pub(restricted)
年.此功能允许您指定项目的"公开程度".语法非常灵活(您可以使一个项目对特定的模块树而不是整个 crate 可见),但如果您想保持简单,pub(crate)
将使一个项目在 crate 中的任何位置都可以访问,但对其他 crate 不可以访问(相当于C#中的internal
).
例如,假设我们想要一个模块util
,其中foo
被导出(作为mycrate::util::foo
),bar
是内部的,baz
是模块专用的.代码可能如下所示:
pub mod util {
pub fn foo() {
unimplemented!()
}
pub(crate) fn bar() {
unimplemented!()
}
fn baz() {
unimplemented!()
}
}
如果你被困在1.18之前的铁 rust 上,有一个解决办法,但它有点笨重.它涉及在私有模块中定义所有项,并在包含再导出的公共模块中仅重新导出那些想要公开的项(pub use
个).下面是上面的例子:
pub mod util {
pub use util_impl::foo;
}
mod util_impl {
pub fn foo() {
unimplemented!()
}
pub fn bar() {
unimplemented!()
}
fn baz() {
unimplemented!()
}
}
这不仅不容易阅读和理解,而且还不能涵盖所有可以使用pub
的情况.例如,如何使导出的 struct 的某些字段可以在同一 crate 中的其他模块中访问,而不必同时导出它们?唯一的 Select 是公开一个带有单个私有字段的包装器,其类型是具有公共字段的 struct ;如果您想对其他 crate 隐藏所有字段,那么这很好,但如果您想在同一个 struct 中公开一些字段,使其他一些字段成为内部字段,那么这就不行了.