rust模块系统

2023-04-09

技术

参考文章: https://www.sheshbabu.com/posts/rust-module-system/

另外,rust虽然可能不错,但rust的基金会经常会搞出一些骚操作,让我犹豫要不要继续学

https://www.zhihu.com/question/594913275

https://rustcc.cn/article?id=37017d56-bf8d-4395-9359-3f996a81f7f7

https://rustcc.cn/article?id=2db1b8b9-fe59-4069-97bd-0c4343860ffc


使用cargo创建新项目rust_demo,在rust_demo/src下建立如下项目结构

│  config.rs
│  main.rs
│
├─models
│       mod.rs
│       user_model.rs
│      
└─routes
        mod.rs
        health_route.rs
        user_route.rs

对于该项目结构,模块系统如下

crate
│  
├─config
│
├─models  
│   │
│   └─ user_model
│
└─routes
    │
    ├─ health_route
    │
    └─ user_route

接下来会循序渐进地讲解

main.rs调用同层级

│  config.rs
│  main.rs

在config.rs中定义了print_config()函数·

pub fn print_config(){
    println!("我是config")
}

函数默认为私有,使用pub关键字声明为共有,才能在外部使用

在main.rs使用

// mod 关键字声明为一个模块
// cargo new创建的项目,以 src 为默认的根模块,名称为 crate

mod  config;    // 与要引用的 config.rs 文件名同名

fn main() {
    // 完整路径为:  crate::config::print_config();
    // 因为 main.rs 与 config.rs 所处为根模块 crate,所以 crate 可省略
    config::print_config();
}

main.rs调用不同层级

│  config.rs
│  main.rs
│
└─models
        mod.rs
        user_model.rs

models/user_model.rs

pub fn print_user_model() {
    println!("我是user_model");
}

新建models/mod.rs,在mod.rs中声明模块 mod

// 文件 mod.rs 表明所处的目录 models 为一个 mod
pub mod user_model;// 子 mod 名称与其文件名相同

在main.rs中调用

mod  config;
mod  models;

fn main() {
    config::print_config();
    models::user_model::print_user_model();
    // `一级mod` :: `二级mod` :: ... :: `函数`
}
  1. mod.rs表明了该文件所处的目录models为一个mod
  2. 在mod.rs中声明公有的子mod:user_model
  3. 在main.rs中使用models/user_model.rs中的函数

不同层级的rs文件调用

最后的文件层级如下:

│  config.rs
│  main.rs
│
├─models
│      mod.rs
│      user_model.rs
│      
└─routes
        mod.rs
        user_route.rs

routes/mod.rs

pub mod user_models

在routes/user_routes.rs中调用models/user_model的函数

pub fn print_user_route() {
    println!("print_user_model被调用了!");
    crate::models::user_model::print_user_model();
}

main.rs中使用

mod  config;
mod  routes;
mod  models;

fn main() {
    println!("我是main");
    config::print_config();
    models::user_model::print_user_model();
    routes::user_route::print_user_route();
}

对于该文件层级定义的各个mod模块,其模块系统如下

crate
│  
├─config
│
├─models  
│   │
│   └─ user_model
│
└─routes
    │
    └─ user_route

crate为根模块,在上述routes/user_routes.rs中使用crate的绝对路径调用:

crate::models::user_model::print_user_model();

路径太长在编写代码时不易阅读,使用use关键字 修改routes/user_routes.rs

// 使用 use 引入模块的函数,后续只需要写函数名即可
use crate::models::user_model::print_user_model;
pub fn print_user_route() {
    println!("print_user_model被调用了!");
    print_user_model();
}

使用 as 关键字重新自定义调用的函数名并使用,可解决名称冲突的问题

use crate::models::user_model::print_user_model as aa;
pub fn print_user_route() {
    println!("print_user_model被调用了!");
    aa();
}

上面的crate为绝对路径调用,下面使用supper进行相对路径调用: 在routes中再新建一个health_route.rs

│  config.rs
│  main.rs
│
├─models
│      mod.rs
│      user_model.rs
│      
└─routes
        mod.rs
        user_route.rs
        health_route.rs

routes/health_route.rs

pub fn print_health_route() {
  println!("我是health_route");
}

要想在外部调用,不要忘记先在routes/mod.rs中声明

pub mod health_route;
pub mod user_route;

routes/user_route.rs

use crate::models::user_model::print_user_model as aa;
pub fn print_user_route() {
    println!("print_user_model被调用了!");
    aa();

    println!("print_health_route被调用了!");
    super::health_route::print_health_route();
}

super是上一层级的mod,对于user_routes来说上一级为:crate::models