跨多个 files/modules 拆分实现并尽可能保持所有内容的私密性
Split implementation across multiple files/modules and keep everything as private as possible
考虑我的库中的以下代码:
pub struct Foo;
impl Foo {
fn helper(&self) { /* .. */ }
}
pub fn do_something(foo: &Foo) {
foo.helper();
}
我图书馆的用户应该能够使用 Foo
和 do_something()
,但 永远不会 调用 helper()
。上面的代码一切正常。但现在假设代码变得庞大,我想将这些定义分离到它们自己的 files/modules 中——然后它们被拉回具有 pub use
的根命名空间。看这里:
mod foo { // module contents in `src/foo.rs`
pub struct Foo;
impl Foo {
fn helper(&self) { /* .. */ }
}
}
mod do_something { // module contents in `src/do_something.rs`
use super::Foo;
pub fn do_something(foo: &Foo) {
foo.helper();
}
}
pub use foo::Foo;
pub use do_something::do_something;
现在编译器抱怨说 helper()
是私有的。的确如此,但我还是希望do_something()
能够使用它。但我不希望我的用户使用它。我该怎么做?
我尝试的解决方案归结为 "How to access private items of sibling modules?"。所以回答这个问题对我有帮助。但提供替代 solution/a 解决方法也很棒!
假设一个 cargo 项目的文件结构如下:
src\lib.rs
src\foo\mod.rs
src\foo\do_something.rs
src\bin\test.rs
test.rs
只是为了证明它可以按图书馆用户的预期工作。
在src\lib.rs:
mod foo;
pub use foo::*;
在src\foo\mod.rs:
mod do_something;
pub use self::do_something::*;
pub struct Foo;
impl Foo {
fn helper(&self) { /* .. */ }
}
在src\foo\do_something.rs:
use super::Foo;
pub fn do_something(foo: &Foo) {
foo.helper();
}
在src\bin\test.rs
extern crate mylibname;
use mylibname::*;
fn main() {
let foo = Foo;
do_something(&foo);
// foo.helper(); //Uncommenting gives an error.
}
这是为我编译的。
从 Rust 1.18 开始,您可以使用 pub(crate)
语法在整个 crate 中公开某些内容,但不能在 crate 之外公开:
mod foo { // module contents in `src/foo.rs`
pub struct Foo;
impl Foo {
pub(crate) fn helper(&self) { /* .. */ }
}
}
编译器建议的所有可能性包括:
pub(crate)
: 仅在当前 crate 可见
pub(super)
: 仅在当前模块的父级可见
pub(in path::to::module)
: 仅在指定路径可见
考虑我的库中的以下代码:
pub struct Foo;
impl Foo {
fn helper(&self) { /* .. */ }
}
pub fn do_something(foo: &Foo) {
foo.helper();
}
我图书馆的用户应该能够使用 Foo
和 do_something()
,但 永远不会 调用 helper()
。上面的代码一切正常。但现在假设代码变得庞大,我想将这些定义分离到它们自己的 files/modules 中——然后它们被拉回具有 pub use
的根命名空间。看这里:
mod foo { // module contents in `src/foo.rs`
pub struct Foo;
impl Foo {
fn helper(&self) { /* .. */ }
}
}
mod do_something { // module contents in `src/do_something.rs`
use super::Foo;
pub fn do_something(foo: &Foo) {
foo.helper();
}
}
pub use foo::Foo;
pub use do_something::do_something;
现在编译器抱怨说 helper()
是私有的。的确如此,但我还是希望do_something()
能够使用它。但我不希望我的用户使用它。我该怎么做?
我尝试的解决方案归结为 "How to access private items of sibling modules?"。所以回答这个问题对我有帮助。但提供替代 solution/a 解决方法也很棒!
假设一个 cargo 项目的文件结构如下:
src\lib.rs
src\foo\mod.rs
src\foo\do_something.rs
src\bin\test.rs
test.rs
只是为了证明它可以按图书馆用户的预期工作。
在src\lib.rs:
mod foo;
pub use foo::*;
在src\foo\mod.rs:
mod do_something;
pub use self::do_something::*;
pub struct Foo;
impl Foo {
fn helper(&self) { /* .. */ }
}
在src\foo\do_something.rs:
use super::Foo;
pub fn do_something(foo: &Foo) {
foo.helper();
}
在src\bin\test.rs
extern crate mylibname;
use mylibname::*;
fn main() {
let foo = Foo;
do_something(&foo);
// foo.helper(); //Uncommenting gives an error.
}
这是为我编译的。
从 Rust 1.18 开始,您可以使用 pub(crate)
语法在整个 crate 中公开某些内容,但不能在 crate 之外公开:
mod foo { // module contents in `src/foo.rs`
pub struct Foo;
impl Foo {
pub(crate) fn helper(&self) { /* .. */ }
}
}
编译器建议的所有可能性包括:
pub(crate)
: 仅在当前 crate 可见pub(super)
: 仅在当前模块的父级可见pub(in path::to::module)
: 仅在指定路径可见