my_project
├── Cargo.toml
└─┬ src
├── main.rs
├── config.rs
├─┬ routes
+ │ ├── mod.rs
│ ├── health_route.rs
│ └── user_route.rs
└─┬ models
└── user_model.rs
// main.rs
mod config;
+ mod routes;
fn main() {
+ routes::health_route::print_health_route();
config::print_config();
println!("main");
}
// routes/mod.rs
+ pub mod health_route;
// routes/health_route.rs
- fn print_health_route() {
+ pub fn print_health_route() {
println!("health_route");
}
下面是模块树的样子:
现在我们可以调用某个目录下文件里定义的函数了。
示例 3
让我们尝试这样的调用main.rs => routes/user_route.rs => models/user_model.rs
(译者注:这里是main.rs
里调用routes/user_route.rs
里的函数,而routes/user_route.rs
里的函数又调用了models/user_model.rs
里的函数)
// main.rs
mod config;
mod routes;
fn main() {
routes::health_route::print_health_route();
config::print_config();
println!("main");
}
// routes/user_route.rs
fn print_user_route() {
println!("user_route");
}
// models/user_model.rs
fn print_user_model() {
println!("user_model");
}
我们想要在main.rs
里调用print_user_route
函数,而print_user_route
函数调用了print_user_model
函数
让我们来进行和之前相同的操作——声明子模块,使函数公开并将子模块添加到mod.rs
文件之中。
my_project
├── Cargo.toml
└─┬ src
├── main.rs
├── config.rs
├─┬ routes
│ ├── mod.rs
│ ├── health_route.rs
│ └── user_route.rs
└─┬ models
+ ├── mod.rs
└── user_model.rs
// main.rs
mod config;
mod routes;
+ mod models;
fn main() {
routes::health_route::print_health_route();
+ routes::user_route::print_user_route();
config::print_config();
println!("main");
}
// routes/mod.rs
pub mod health_route;
+ pub mod user_route;
// routes/user_route.rs
- fn print_user_route() {
+ pub fn print_user_route() {
println!("user_route");
}
// models/mod.rs
+ pub mod user_model;
// models/user_model.rs
- fn print_user_model() {
+ pub fn print_user_model() {
println!("user_model");
}
下面是模块树的样子:
等等,我们还没有真正地在print_user_route
里调用print_user_model
!目前为止,我们仅仅在main.rs
里调用定义在其他模块里的函数,在别的文件里调用其他模块的函数应该怎么做么?
如果我们看一下我们的模块树,print_user_model
位于crate::models::user_model
。所以为了能在非main.rs
的其他文件里使用一个模块,我们应该按照模块树中到达指定模块所需要的路径来进行考虑。
// routes/user_route.rs
pub fn print_user_route() {
+ crate::models::user_model::print_user_model();
println!("user_route");
}
现在我们已经成功地在一个非main.rs
的文件里调用了定义在另一个文件里的函数。
super
如果我们的文件组织包含多级目录,完整的限定名就会变得很长。出于某些原因,我们想要从print_user_route
中调用print_health_route
。它们分别位于crate::routes::health_route
和crate::routes::user_route
。
我们可以使用完整路径的限定名crate::routes::health_route::print_health_route();
, 但是我们也可以使用一个相对路径super::health_route::print_health_route();
pub fn print_user_route() {
crate::routes::health_route::print_health_route();
// can also be called using
super::health_route::print_health_route();
println!("user_route");
}
use
在上面的例子中,无论是使用完整的限定名还是相对路径的限定名都很冗长。为了让限定名变得更短,我们可以使用use
关键字来给路径绑定一个新名字或者别名。
pub fn print_user_route() {
crate::models::user_model::print_user_model();
println!("user_route");
}
上面的代码可以重写为:
use crate::models::user_model::print_user_model;
pub fn print_user_route() {
print_user_model();
println!("user_route");
}
除了使用print_user_model
这个名字,我们还可以给它起个别名:
use crate::models::user_model::print_user_model as log_user_model;
pub fn print_user_route() {
log_user_model();
println!("user_route");
}
外部模块(External modules)
添加到Cargo.toml
里的依赖对于项目内的所有模块都是可以访问的。我们不需要显式地导入或声明任何东西来使用依赖项。
例如,比如说我们在项目中添加了rand这个crate。我们可以像下面这样在代码里直接使用:
pub fn print_health_route() {
let random_number: u8 = rand::random();
println!("{}", random_number);
println!("health_route");
}
我们也可以使用use
来简化路径:
use rand::random;
pub fn print_health_route() {
let random_number: u8 = random();
println!("{}", random_number);
println!("health_route");
}