Day 04 - Package Crate Module

本贴最后更新于 600 天前,其中的信息可能已经时移俗易

image

img

📚 Package Crate Module 简介

创建时间:2023-03-30 22:28 星期四


代码组织

  • 代码组织主要包括:

    • 那些细节可以暴露 那些细节是可以私有的
    • 作用域哪些名称有效
  • 模块系统

    • package: Cargo 的特性 让你构建测试共享 crate
    • crate: 一个模块树 他可产生一个 library 或者可执行文件
    • module: 控制代码的组织 作用域 私有路径 还有 use 关键字
    • Path: 条目

Crate

crate 有两种形式:二进制项和库。

  • 二进制项 可以被编译为可执行程序它们必须有一个 main​ 函数来定义当程序被执行的时候所需要做的事情。目前我们所创建的 crate 都是二进制项。
  • library 并没有 main​ 函数,它们也不会编译为可执行程序,它们提供一些诸如函数之类的东西,使其他项目也能使用这些东西.

crate root 是一个源文件,Rust 编译器以它为起始点,并构成你的 crate 的根模块

默认的情况下:

  • src/main.rs - 就是 binarycrate 的 root
  • src/lib.rs - 当 package 存在这个文件的时候,这 package 就包含一个 library crate

在包(crate)的上层就是 package package 存在一个 cargo.toml 组成我们的 Crate 根 module。包中可以包含至多一个库 crate(library crate)。包中可以包含任意多个二进制 crate(binary crate),但是必须至少包含一个 crate(无论是库的还是二进制的)。

Package

其实 Package 可以是一个项目 我们可以通过指令 cargo new packagename​ 来创建一个,也可以是一个包含 cargo.toml 的文件夹

Module

在一个 crate 中将代码进行分组增加可读性易于复用

  • Module 在代码中用 mod 进行定义
  • mod 里面可以存在多个子 mod(嵌套)
mod user_manager {
    mod admin_user_manager {
        fn add_admin_user(username: String) {}
    }
    mod guest_user_manager {
        fn add_guest_user(username: String) {}
    }
}

pub fn show_all_user()  {
  
}

比如我们在 lib.rs 中写入代码 也就是 crate 的 library crate​中进行创建

路径

路径有绝对和相对两种:

pub mod user_manager {
    pub mod admin_user_manager {
        pub fn add_admin_user(username: String) {
            println!("添加了admin用户: {}", username);
        }

        fn private_func() {
            println!("这是私有函数");
        }
    }
    pub mod guest_user_manager {
        pub fn add_guest_user(username: String) {
            println!("添加了guest用户: {}", username);
        }
    }
}

pub fn show_all_user() {
    // 因为都在同一个crate中  隐式出现了一个crate的模块
    crate::user_manager::admin_user_manager::add_admin_user(String::from("你好"));
    // 绝对路径引用

    user_manager::guest_user_manager::add_guest_user(String::from("你好"));
    // 相对路径引用
}

父模块不可以调用子模块私有条目, 子模块可以调用父模块的私有条目。

关于结构与枚举的公共字段的定义如下:

pub mod user_manager {
    fn get_all(){

    }

    pub struct User{
        pub username: String, //  pub 可以公开到字
        pub password: String
    }

    pub enum Status { // 公共的枚举 里面的字段都是公用的
        Login,
        UnLogin      
    }

    impl User{
        fn get_user(username:String , password:String) -> User{
            let mut user_instance = crate::user_manager::User{
                username,
                password
            };
          
            if user_instance.username == String::from("刘博源"){
                user_instance.username = String::from("刘X源");
            }

            user_instance
        }
    }

    pub mod admin_user_manager {
        pub fn add_admin_user(username: String) {
            println!("添加了admin用户: {}", username);
        }

        fn private_func() {
            println!("这是私有函数");
        }
    }
    pub mod guest_user_manager {
        pub fn add_guest_user(username: String) {
            println!("添加了guest用户: {}", username);
            super::get_all(); // 相对路径 获得上一层mod的函数
            crate::user_manager::get_all(); // 绝对路径 从 crate 中开始拿
        }
    }
}

pub fn show_all_user() {
    // 因为都在同一个crate中  隐式出现了一个crate的模块
    crate::user_manager::admin_user_manager::add_admin_user(String::from("你好"));
    // 绝对路径引用

    user_manager::guest_user_manager::add_guest_user(String::from("你好"));
    // 相对路径引用
}

Summary:

  • 公共的枚举 字段就是公共的不需要额外的设置
  • 公共的结构 字段默认是私有的 需要手动设置公共的

关于路径:

  • 在同一个文件下(也就是一个 crate 中)默认有一个 crate 参数表示根,使用 crate 获取某个 mod 的 成员就是绝对路径
  • 相对路径可以使用 super 拿到上一级。

use 关键字

我们可以用 use 拿到一些 mod 的成员

还是上一层的代码我们可以使用 use

use crate::user_manager::User;

pub fn show_all_user() {
    let user = User::get_user(String::from("名称"), String::from("密码"));
}

相对路径也可以.

image

如果你希望你模块 A 中导入的某些模块在别人导入模块 A 的时候可以不要导入其他模块的时候 你可以使用 pub use 进行导入.

使用外部包

我们只需要在 toml 中的 dependencies​ 中进行修改即可

嵌套导入

当我们像使用某个包下的多个模块的时候我们会:

use std::cmp::Eq;
use std::cmp::Ordering;

直接这么着:

use std::cmp::{Eq,Ordering};

地道~

use std::cmp;
use std::cmp::Ordering;

如果是这样那么就:

use std::cmp::{self,Ordering};

导入其他文件的 mod

比如我们有一个 rs 文件叫做:worker.rs

pub mod WorkerMod{
    pub struct Worker{
        pub username: String,
    }
}

我们如何在 main.rs 中导入呢?可以这么做:


mod Worker; // mod + 文件名称不要后缀

fn main() {
    let uer = Worker::WorkerMod::Worker{
         username : String::from("你好啊")
    };
}

即可

子模块的分离

pub mod worker_mod {
    pub struct worker {
        pub username: String,
    }
    pub mod worker_type {
        pub struct dustman {
            pub id: i32,
        }

        pub struct programmer {
            pub id: i32
        }
    }
}

我们有一个模块有很多的子模块现在我们需要把这些子模块进行分离:

我们先让 worker 的代码修改为:

pub mod worker_mod;

然后按照目录做成:

image

接着我们就在 worker_mod.js 中加上我们的子 mod:

pub struct worker {
    pub username: String,
}
pub mod worker_type {
    pub struct dustman {
        pub id: i32,
    }

    pub struct programmer {
        pub id: i32,
    }
}

  • Rust

    Rust 是一门赋予每个人构建可靠且高效软件能力的语言。Rust 由 Mozilla 开发,最早发布于 2014 年 9 月。

    58 引用 • 22 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...