学习Rust的第11天:模块系统

news2025/2/24 7:41:33

Today we are taking a look at the module system of rust. We can use this to manage growing projects and keep track of what modules is stored where…
今天我们来看看Rust的模块系统。我们可以使用它来管理不断增长的项目,并跟踪 modules 存储在何处。

Rust’s module system is an effective tool for organizing code into logical pieces, hence enabling code maintenance and reuse. Modules support hierarchical organization, privacy management, and code encapsulation. Rust offers developers versatile and scalable methods for managing project complexity with features such as the use keyword, nested paths, and the ability to divide modules into independent files.
Rust的模块系统是将代码组织成逻辑片段的有效工具,因此可以实现代码维护和重用。模块支持分层组织、隐私管理和代码封装。Rust为开发人员提供了多功能和可扩展的方法来管理项目复杂性,其功能包括use关键字,嵌套路径以及将模块划分为独立文件的能力。

Introduction 介绍

In Rust, the module system helps keep code organized by grouping related functions, types, and other items together, making it easier to manage and reuse code in a project.
在Rust中,模块系统通过将相关的函数、类型和其他项分组在一起来帮助组织代码,从而更容易在项目中管理和重用代码。

For example: 举例来说:

Let’s say a part of your code is working with managing the database, you don’t really want it to be accessed by an image renderer. So we store them in different locations, in different modules
假设你的一部分代码是用来管理数据库的,你并不真的希望它被图像渲染器访问。所以我们把它们存放在不同的地方,不同的 modules

We can use the use keyword to access certain parts of a different modules.
我们可以使用 use 关键字来访问不同 modules 的某些部分。

When we run the cargo new command, we are technically creating a package and a package stores crates. There are two types of crates
当我们运行 cargo new 命令时,我们在技术上创建了一个包和一个包存储 crates 。有两种板条箱

  1. Binary crate : Can be executed directly
    Binary crate:可以直接执行
  2. Library crate : Can be used by other programs/packages
    Library crate:可以被其他程序/包使用

Each crate stores modules, That organize the code and control the privacy of your rust program.
每个箱子里都有模块,用来组织代码并控制生锈程序的隐私.

Let’s take a deeper look into it.
让我们深入了解一下。

Create a new package by running :
通过运行以下命令创建新包:

$ cargo new module_system
$ cd module_system
$ ls
Cargo.toml
src/

Reading the Cargo.toml file we can see :
阅读 Cargo.toml 文件,我们可以看到:

[package]
name = "module_system"
version = "0.1.0"
edition = "2021"

[dependencies]

Due to the rust convention, We cannot really see any crates we have in this file but we do have a main.rs file. Which means that there is a binary crate named module_system in our package by default.
由于rust约定,我们在这个文件中看不到任何 crates ,但我们确实有一个 main.rs 文件。这意味着在我们的包中默认有一个名为 module_system 的二进制crate。

The same convention is followed for library crates, if lib.rs is present in out src directory, It will automatically create a library crate named module_system.
对于库crate也遵循相同的约定,如果 lib.rs 存在于 src 目录中,则会自动创建一个名为 module_system. 的库crate

Rules of packages and crates
包装和板条箱规则

  1. A package must have atleast one crate.
    一个包必须至少有一个板条箱。
  2. A package can either contain 0 library crates or 1 library crate
    一个包可以包含0个库箱或1个库箱
  3. A package can have n numbers of binary crates.
    一个包可以有 n 个二进制板条箱。

Modules 模块

Modules are library crates, defined with the mod keyword. They are used to structure a Rust application better, let’s take a look at an example to better understand it.
模块是用 mod 关键字定义的库箱。它们用于更好地构建Rust应用程序,让我们看一个例子来更好地理解它。

To create a library crate, we can use this command
要创建库crate,我们可以使用以下命令

cargo new --lib user
//File : src/lib.rs

mod user{
  mod authentication{
    fn create_account(){}
    fn login(){}
    fn forgot_password(){}
  }

  mod edit_profile{
    fn change_username(){}
    fn chang_pfp(){}
    fn change_email(){}
  }
}

This is what a module would look like.
这就是模块的样子。

A module can have multiple modules inside of it, we can define, structs, enums, functions and more inside a module.
一个模块里面可以有多个模块,我们可以在一个模块里面定义,结构,枚举,函数等等。

This method helps a lot with managing and maintaining code-bases. In future if we had to change a certain something with the forgot_password function. We would know exactly where to find it…
这种方法对管理和维护代码库有很大帮助。在未来,如果我们不得不改变某些东西与 forgot_password 功能。我们就知道在哪能找到它...

Calling functions from a module
从模块调用函数

Let’s say, I want to enroll a new user into my service, and need to use the create_account function. How do I call it?
比如说,我想在我的服务中注册一个新用户,需要使用 create_account 函数。我该怎么称呼它?

//File : src/lib.rs

mod user{
  pub mod authentication{
    pub fn create_account(){}
    fn login(){}
    fn forgot_password(){}
  }

  mod edit_profile{
    fn change_username(){}
    fn chang_pfp(){}
    fn change_email(){}
  }
}

pub fn call_module_function(){
  //Absolute path
  crate::user::authentication::create_account();

  //Relative path
  user::authentication::create_account();
}

We added a pub keyword for out authentication module and create account function, because by default it is private and cannot be called, because of module privacy rules
我们为out authentication模块和create account函数添加了一个 pub 关键字,因为默认情况下它是 private ,由于模块隐私规则,它不能被调用

Relative path refers to accessing modules or items within the same module hierarchy without specifying the root, while absolute path refers to accessing them by specifying the root module or crate.
相对路径指的是在不指定根的情况下访问同一模块层次结构中的模块或项目,而绝对路径指的是通过指定根模块或crate来访问它们。

For reference, here is what the module hierarchy looks like…
作为参考,下面是模块层次结构的样子。

The super keyword can also be used for relatively calling a function, super allows us to reference the parent module…
关键字 super 也可以用于相对调用函数, super 允许我们引用父模块。

Example 例如

mod parent_module {
    pub fn parent_function() {
        println!("This is a function in the parent module.");
    }
}

mod child_module {
    // Importing the `parent_function` from the parent module using `super`
    use super::parent_module;

    pub fn child_function() {
        println!("This is a function in the child module.");
        // Calling the parent function using `super`
        parent_module::parent_function();
    }
}

fn main() {
    // Calling the child function which in turn calls the parent function
    child_module::child_function();
}

Module privacy rules 模块隐私规则

Modules have privacy rules that control which items (such as structs, functions, and variables) are visible or accessible from outside the module.
模块具有隐私规则,这些规则控制哪些项(如结构、函数和变量)可从模块外部看到或访问。

These rules help enforce encapsulation and prevent unintended access to internal details of a module.
这些规则有助于强制封装并防止意外访问模块的内部细节。

mod my_module {
    // Public struct
    pub struct PublicStruct {
        pub public_field: u32,
    }

    // Private struct
    struct PrivateStruct {
        private_field: u32,
    }

    // Public function to create instances of `PrivateStruct`
    pub fn create_private_struct() -> PrivateStruct {
        PrivateStruct { private_field: 42 }
    }
}

fn main() {
    // Creating an instance of PublicStruct is allowed from outside the module
    let public_instance = my_module::PublicStruct { public_field: 10 };
    println!("Public field of PublicStruct: {}", public_instance.public_field);

    // Creating an instance of PrivateStruct is not allowed from outside the module
    // let private_instance = my_module::PrivateStruct { private_field: 20 }; // This would give a compile-time error

    // Accessing the private field of PublicStruct is not allowed
    // println!("Private field of PublicStruct: {}", public_instance.private_field); // This would give a compile-time error

    // However, we can create and access instances of PrivateStruct using the provided public function
    let private_instance = my_module::create_private_struct();
    // println!("Private field of PrivateStruct: {}", private_instance.private_field); // This would give a compile-time error
}
  • Rust’s module system allows for organizing code into logical units.
    Rust的模块系统允许将代码组织成逻辑单元。
  • Visibility and access control in Rust modules are enforced through privacy rules.
    Rust模块中的可见性和访问控制通过隐私规则来实施。
  • In Rust, items (such as structs, functions, and variables) can be marked as either public or private within a module.
    在Rust中,项目(如结构、函数和变量)可以在模块中标记为public或private。
  • Public items are accessible from outside the module, while private items are not.
    公共项可以从模块外部访问,而私有项则不能。
  • Public items are typically designated with the pub keyword, while private items are not explicitly marked.
    公共项通常使用 pub 关键字指定,而私有项不显式标记。
  • Private items are only accessible within the module where they are defined, promoting encapsulation and hiding implementation details.
    私有项只能在定义它们的模块中访问,从而促进了封装并隐藏了实现细节。
  • The pub keyword is used to make items visible outside the module, allowing them to be used by other parts of the codebase.
    pub 关键字用于使项目在模块外部可见,允许代码库的其他部分使用它们。
  • The super keyword in Rust allows access to items in the parent module, facilitating hierarchical organization and access control within a crate.
    Rust中的 super 关键字允许访问父模块中的项目,促进了crate中的分层组织和访问控制。

Use Keyword 使用关键字

use keyword allows you to bring a path into scope, so that you dont have to specify a path over and over again, let’s take a look at our previous example.
use 关键字允许您将路径带入作用域,这样您就不必一遍又一遍地指定路径,让我们看看前面的示例。

//File : src/lib.rs

mod user{
  pub mod authentication{
    pub fn create_account(){}
    fn login(){}
    fn forgot_password(){}
  }

  mod edit_profile{
    fn change_username(){}
    fn chang_pfp(){}
    fn change_email(){}
  }
}

//adding the module to our scope
use crate::user::authentication;

pub fn call_module_function(){
  //Instead of these, we can call it directly.
  //crate::user::authentication::create_account();
  //user::authentication::create_account();

  authentication::create_account();
}

Nested paths 嵌套路径

mod outer_module {
    pub mod inner_module {
        pub fn inner_function() {
            println!("This is an inner function.");
        }

        pub struct InnerStruct {
            pub value: i32,
        }
    }
}

use outer_module::inner_module::inner_function;
use outer_module::inner_moduel::InnerStruct;

fn main() {
    // Calling the inner function
    inner_function();

    // Creating an instance of InnerStruct
    let inner_struct_instance = InnerStruct { value: 42 };
    println!("Value of inner struct: {}", inner_struct_instance.value);
}

Notice how both the use statements start with outer_module::inner_module::
请注意,两个 use 语句都以 outer_module::inner_module:: 开头

We can nest the two use statements by this:
我们可以这样嵌套两个 use 语句:

use outer_module::inner_module::{inner_function, InnerStruct};

Modules in separate files
单独文件中的模块

To keep better track of our project and structure it better, we can store different modules in separate files. Let’s do that to the authentication module.
为了更好地跟踪我们的项目并更好地构建它,我们可以将不同的模块存储在单独的文件中。让我们对 authentication 模块这样做。

mod user{
  pub mod authentication{
    pub fn create_account(){}
    fn login(){}
    fn forgot_password(){}
  }

  mod edit_profile{
    fn change_username(){}
    fn chang_pfp(){}
    fn change_email(){}
  }
}

Step 1 : Create a file in the src/ directory with the same name as the module, in out case authentication.rs
第1步:在 src/ 目录中创建一个与模块同名的文件,例如 authentication.rs

Step 2 : Copy all the functions to that file but keep the module declaration
步骤2:将所有函数复制到该文件,但保留模块声明

//File : src/authentication.rs
pub fn create_account(){}
fn login(){}
fn forgot_password(){}
//File : src/lib.rs
mod user{
  pub mod authentication; //change the curly brackets to a semicolon

  mod edit_profile{
    fn change_username(){}
    fn chang_pfp(){}
    fn change_email(){}
  }
}

What this does it, the compiler looks for the file with the same name as the module name and puts all the functions and other data in the module.We can also do this for parent modules as well…
这样做的目的是,编译器查找与模块名称同名的文件,并将所有函数和其他数据放入模块中。
我们也可以对父模块这样做.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1609313.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql四种引擎区别

MySQL 提供了多种不同的数据库引擎,其中最常见的有 MyISAM、InnoDB、MEMORY 和 BLACKHOLE。这四个引擎分别有以下特点: 1. MyISAM MyISAM 是 MySQL 的默认引擎。它对于只有较少的修改、大量读取的应用场景具有良好的性能。它不支持事务处理,也…

如何查看微信公众号发布文章的主图,如何看微信文章的主图,怎么才能拿到主图

如何查看,微信公众号发布文章的主图,如何看微信文章的主图 起因是这样的,当我看到一篇文章的时候,他的主图很漂亮,但是,正文里没有,而我又想看到,并且使用这张图片,该怎么…

社交媒体数据恢复:BF Messager

BF Messenger 数据恢复方法 一、前言 BF Messenger(BF加密聊天软件)是一款基于布尔式循环移位加密算法的聊天应用程序。它使用对称密钥加密技术,用户可以在安全的环境下进行私密聊天。除此之外,该应用还具有防截屏、应用锁屏、密…

使用 Docker 部署 SurveyKing 调查问卷系统

1)SurveyKing 介绍 SurveyKing 是一款功能强大、操作简便的开源问卷系统。它不仅满足了用户对问卷调查的基本需求,还提供了丰富的逻辑设置和灵活的问题设置,使得问卷制作更加智能化和个性化。此外,SurveyKing 还具有快速部署和安全…

gin框架提高篇(四)

参数校验(一) uuid包:https://github.com/satori/go.uuid 因为作者更改了参数限制,导致会出问题 → 问题解决 package mainimport ("fmt""github.com/gin-gonic/gin""github.com/go-playground/validato…

STL容器搜索:当直接访问STL容器时,如何执行有效和正确的搜索?

在访问STL容器时进行搜索 一、简介二、std::vector, std::deque, std::list三、std::map, std::multimap, std::set, std::multiset四、std::string六、总结 一、简介 本文主要了解如何在直接访问c容器时高效地进行搜索。在STL容器中搜索,要牢记一个原则&#xff1…

禾赛面经分享

前言 禾赛的linux开发工程师(实习),base是上海,以下是面试遇到的一些问题。 目录 前言题目与答案C语言部分嵌入式相关手撕题 题目与答案 C语言部分 static关键字的作用 static修饰局部变量时:①改变了其存储位置&…

基础知识集合

https://blog.csdn.net/sheng_q/category_10901984.html?spm1001.2014.3001.5482 epoll 事件驱动的I/O模型,同时处理大量的文件描述符 内核与用户空间共享一个事件表:监控的文件描述符以它们的状态,当状态变化,内核将事件通知给…

【分治】Leetcode 库存管理 III

题目讲解 LCR 159. 库存管理 III 本题的含义就是让求出最小的k个数 算法讲解 class Solution { public:void my_qsort(vector<int>& nums, int l, int r){if(l > r) return ;int i l, left l-1, right r1;int key nums[rand() % (r - l 1) l];//完成分三…

大数据真题讲解系列——拼多多数据分析面试题

拼多多数据分析面试题&#xff1a;连续3次为球队得分的球员名单 问题&#xff1a; 两支篮球队进行了激烈的比赛&#xff0c;比分交替上升。比赛结束后&#xff0c;你有一个两队分数的明细表&#xff08;名称为“分数表”&#xff09;。表中记录了球队、球员号码、球员姓名、得…

hv第一坑:定时器

错误代码 重试策略&#xff1a;一次延迟1s,最长30s直至事件成功。 int try_count 0;//do something if(not success)m_loop->setTimerInLoop((try_count > 30 ? 30: try_count) *1000 , cb, INFINITE, 0x100);表现现象 cpu 爆了内存爆了 总结原因 hv内部代码bug&…

Maven通过flatten-maven-plugin插件实现多模块版本统一管理

正文 起因是公司开始推代码版本管理的相关制度&#xff0c;而开发过程中经常使用多模块构建项目&#xff0c;每次做版本管理时都需要对每个模块及子模块下的pom文件中parent.version和模块下依赖中的version进行修改&#xff0c;改的地方非常多&#xff0c;且非常容易漏。为此…

如何用Python构建一个生产级别的电影推荐系统 - 机器学习手册

构建项目是彻底学习概念并发展必要技能的最有效方式之一。 项目使您沉浸在现实世界的问题解决中&#xff0c;巩固您的知识&#xff0c;并培养批判性思维、适应能力和项目管理专业知识。 本指南将带您逐步构建一个根据用户喜好量身定制的电影推荐系统。我们将利用一个庞大的包…

20240419,继承,多态

土豆的老家陕西安康&#xff01;怪舒服的咯&#xff0c;广西一眼望去全是房子啦&#xff0c;小时候一眼开敞水田再也回不来啦 目录 五&#xff0c;继承 5.1 基本语法 5.2 继承方式 5.3 继承中的对象模型 5.4 构造和析构顺序 5.5 同名成员处理 5.6 同名静态成员处理 5.…

c#+unity基础

序列化&#xff1a; [SerializeField]&#xff0c;点不出来&#xff0c;只能在面板上显示绑定游戏物体 //公有隐藏 特有函数 特有函数&#xff1a;不需要调用&#xff0c;自动执行 Awake最先执行->OnEable 面向对象思想 面向对象思想&#xff1a;分为具体对象和抽象对…

从预训练损失的角度,理解语言模型的涌现能力

原文&#xff1a;Understanding Emergent Abilities of Language Models from the Loss Perspective 摘要 本文从预训练损失的角度重新审视语言模型的涌现能力&#xff0c;挑战了以往以模型大小或训练计算量为标准的观念。通过实验&#xff0c;作者发现预训练损失是预测下游任…

【算法】合并两个有序链表

本题来源---《合并两个有序链表》 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] /*** Definition for singl…

JavaSE——常用API进阶二(6/8)-ZoneId、ZoneDateTime、Instant(常见方法、用法示例)

目录 ZoneId 常见方法 用法示例 ZoneDateTime 常见方法 用法示例 Instant 常见方法 用法示例 如果在开发中我们有这样的需求&#xff1a;我们的系统需要获取美国现在的时间&#xff0c;或者其他地区的时间给用户观看&#xff0c;或者进行一些处理&#xff0c;那应该怎…

循环开关定时器(Smart PLC梯形图代码)

很多设备不需要复杂的逻辑时序控制,只需要实现简单的循环定时开关功能,对于这样的控制我们可以利用定时器组合去实现,但是如果系统里需要循环定时控制的设备比较多,那我们建议大家编写一个这样的循环定时开关功能块,SMART PLC循环开关定时器还可以参考下面文章链接 1、周…

短视频批量采集提取软件|视频关键词下载工具

短视频批量采集软件&#xff1a;快速抓取、高效下载 一、开发背景 随着短视频平台的兴起&#xff0c;获取并分析相关视频内容已成为许多业务的必要步骤。然而&#xff0c;传统的手动方式无法满足快速、批量获取的需求&#xff0c;因此我们开发了一款专业的短视频批量采集软件。…