Rust的模块系统实际上非常灵活,可以让你公开任何你想要的 struct ,同时隐藏代码在文件中的 struct .
我认为这里的关键是使用pub use
,这将允许您从其他模块重新导出标识符.Rust的std::io
crate 中有这样的先例,其中一些子模块的类型是re-exported for use in std::io
.
Edit(2019-08-25):答案的以下部分是很久以前写的.它解释了如何设置这样一个模块 struct ,仅使用rustc
个.今天,人们通常会在大多数用例中使用Cargo .虽然以下内容仍然有效,但其中的某些部分(例如#![crate_type = ...]
)可能看起来很奇怪.这不是推荐的解决方案.
为了适应您的示例,我们可以从以下目录 struct 开始:
src/
lib.rs
vector.rs
main.rs
这是你的main.rs
:
extern crate math;
use math::vector;
fn main() {
println!("{:?}", vector::VectorA::new());
println!("{:?}", vector::VectorB::new());
}
还有你的src/lib.rs
:
#[crate_id = "math"];
#[crate_type = "lib"];
pub mod vector; // exports the module defined in vector.rs
最后,src/vector.rs
:
// exports identifiers from private sub-modules in the current
// module namespace
pub use self::vector_a::VectorA;
pub use self::vector_b::VectorB;
mod vector_b; // private sub-module defined in vector_b.rs
mod vector_a { // private sub-module defined in place
#[derive(Debug)]
pub struct VectorA {
xs: Vec<i64>,
}
impl VectorA {
pub fn new() -> VectorA {
VectorA { xs: vec![] }
}
}
}
这就是魔法发生的地方.我们定义了一个子模块math::vector::vector_a
,它实现了一种特殊的向量.但我们不希望你们图书馆的客户关心有vector_a
子模块.相反,我们想让它在math::vector
模块中可用.这是通过pub use self::vector_a::VectorA
完成的,pub use self::vector_a::VectorA
在当前模块中重新导出vector_a::VectorA
标识符.
但您询问了如何做到这一点,以便可以将特殊的向量实现放在不同的文件中.这就是mod vector_b;
线的功能.它指示Rust编译器为该模块的实现查找vector_b.rs
文件.果然,这是我们的src/vector_b.rs
文件:
#[derive(Debug)]
pub struct VectorB {
xs: Vec<i64>,
}
impl VectorB {
pub fn new() -> VectorB {
VectorB { xs: vec![] }
}
}
从客户的Angular 来看,VectorA
和VectorB
在两个不同的模块中定义在两个不同的文件中,这一事实是完全不透明的.
如果你和main.rs
在同一个目录下,你应该能够运行它:
rustc src/lib.rs
rustc -L . main.rs
./main
总的来说,铁 rust 书里的"Crates and Modules" chapter是相当不错的.有很多例子.
最后,Rust编译器还会自动查找子目录.例如,上面的代码将在这个目录 struct 下工作:
src/
lib.rs
vector/
mod.rs
vector_b.rs
main.rs
编译和运行的命令也保持不变.