初学rust,对crate和mod的使用总是感到不太顺利,特此记录一下。
当我们用cargo 创建一个新项目时,默认就创建了一个package。
PS D:\test\rust_test> cargo new myproject
Creating binary (application) `myproject` package
note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
PS D:\test\rust_test>
crate:一个模块的树形结构,它形成了库或二进制项目。
module:一个 module
是用来组织代码的逻辑单位,用于拆分一个 crate
中的代码。
大致关系如下:

- 1个Package里,至少要有1种Crate(要么是Library Crate,要么是Binary Crate)
- 1个Package里,最多只能有1个Library Crate
- 1个Package里,可以有0或多个Binary Crate
- 1个Crate里,可以创建0或多个mod
场景一
先看一个最简单的例子:
rust
mod database{
pub fn mysql(){
println!("I am mysql");
}
}
fn main() {
database::mysql();
}
运行:
PS D:\test\rust_test\myproject> cargo run
Compiling myproject v0.1.0 (D:\test\rust_test\myproject)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.59s
Running `target\debug\myproject.exe`
I am mysql
说明:
1、需要加pub关键字将模块内的函数mysql()公开,否则main函数发现不到mysql()的存在。
2、main函数调用mysql时需要加上模块名称,database::mysql()。否则编译器也找不到mysql()。
场景二
再来看一个复杂点的例子:
rust
mod database{
pub fn mysql(){
println!("I am mysql");
}
pub mod action{
pub fn action_mysql(){
super::mysql(); //子模块调用父模块,加super
}
}
pub fn print_mysql(){
mysql();
}
}
fn main() {
database::print_mysql();
use database::action; //使用use简化调用路径
action::action_mysql();
}
运行:
PS D:\test\rust_test\myproject> cargo run
Compiling myproject v0.1.0 (D:\test\rust_test\myproject)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.17s
Running `target\debug\myproject.exe`
I am mysql
I am mysql
说明:
1、可以使用use关键字简化路径。
2、子模块调用父模块时,要加super关键字。
场景三
再来看一下多目录,多文件的场景:
在src目录下建立两个目录,folder_a和folder_b,然后folder_a下创建文件a1.rs, folder_b下创建文件b1.rs。目录结构看起来是下面这个样子的:
├─src
│ │ main.rs
│ ├─folder_a
│ │ a1.rs
│ └─folder_b
│ b1.rs
a1.rs内容如下:
rust
pub mod inner{
pub fn action_a1(){
println!("action_a1");
}
}
b1.rs内容如下:
rust
pub mod b1{
pub fn action_b1(){
println!("action_b1");
}
}
那么main.rs如何才能调用到action_a1()和action_b1()呢?需要做如下操作:
1、在src目录下新建三个文件,分别是lib.rs, folder_a.rs, folder_b.rs。
├─src
│ │ folder_a.rs
│ │ folder_b.rs
│ │ lib.rs
│ │ main.rs
│ ├─folder_a
│ │ a1.rs
│ └─folder_b
│ b1.rs
lib.rs内容如下:
rust
pub mod folder_a;
pub mod folder_b;
folder_a.rs内容如下:
rust
pub mod a1;
folder_b.rs内容如下:
rust
pub mod b1;
2.修改main.rs文件
rust
use myproject::folder_a; //myproject为Cargo.toml里面的package name
use myproject::folder_b;
fn main() {
folder_a::a1::inner::action_a1();
folder_b::b1::b1::action_b1(); //两个b1, 第一个b1把b1.rs认为一个mod,第二个b1是pub mod b1{}
}
运行成功!
PS D:\test\rust_test\myproject> cargo run
Compiling myproject v0.1.0 (D:\test\rust_test\myproject)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.50s
Running `target\debug\myproject.exe`
action_a1
action_b1