Rust的mod管理
首先明确几个Rust的概念
- Packages: 可以理解为是一个工程project,包含了cargo.toml,描述了几个crate应该怎么组织在一起,包含test,build等功能。可以包含一个或零个二进制执行文件,可以包含若干个crate库。
- Crates: 是一个二进制可执行文件(binary executor)或是一个库(library)。
- Modules and use: 可以理解为mod,控制模块内的范围,私有公有,范围等。
- Item:即functions, methods, structs, enums, modules, and constants,这些items可以被设计成private或pub,在不同mod中传递的就是这些item。
- Paths: 也就是::,用来找到一个item。也可以用self,super等相对路径来索引。
如何同一个文件中引用mod?
在同一个文件中引用很简单,只要定义好mod即可
mod grandfather{
pub mod father {
pub mod son {
pub fn play(){
println!("I am playing")
}
}
}
}
fn main(){
grandfather::father::son::play();
}
需要注意的是其中的pub。在struct中默认item是private。在enum中默认是public。所以想要在mod之外引用要加上pub。还有一点要注意的是在pub mod操作不能使得mod内部的item成为pub,必须逐个定义。
如何在不同的文件中引用mod?
在不同的文件中引用稍稍麻烦一下,方法有两个
第一种
是在main文件夹目录下新建mod文件
同时在main中声明mod
//main.rs
mod grandfather;
fn main(){
grandfather::father::son::play();
}
在grandfather中去掉grandfather
//grandfather.rs
pub mod father {
pub mod son {
pub fn play(){
println!("I am playing")
}
}
}
第二种
是新建一个文件夹。文件夹的名字就是mod的名字,文件夹下有一个mod.rs,名称固定,代码与第一种一样。在这个文件夹下也可以声明和father同级别的兄弟mod。还可以再新建文件夹声明子孙mod。
使用use简化代码
使用use可以简化代码,比如
//main.rs
mod grandfather;
use grandfather::father::son;
fn main(){
son::play();
}
另外需要注意的一点就是如果在use前加上pub,那么就可以让use具备传递性。比如father中使用了use,那么grandfather中就相当于自动有了这个use。
深层次的解释
mod的模型其实就是把所有的mod挂载到根crate上,叫做module tree。使用mod就是把不同层级的模块组合在一起。根目录就是crate。所以现在也能很容易的理解PATH这个名词的概念,类似于磁盘的文件夹,用path的::也是一层层递进的关系。