当前位置: 首页 > news >正文

Rust之包、单元包及模块

  • 包:一个用于构建、测试并分享单元包的Cargo功能;
  • 单元包:一个用于生成库或可执行文件的树形模块结构;
  • 模块及use关键字:被用于控制文件结构、作用域及路径的私有性;
  • 路径:一种用于命名条目的方法,这些条目包括结构体、函数和模块等。

1、包与单元包:

单元包可以被用于生成二进制程序或库。将Rust编译时所使用的入口文件称作这个单元包的根节点,它同时也是单元包的根模块。
包由一个或多个提供相关功能的单元包集合而成,它所附带的配置文件Cargo.toml描述了如何构建这些单元包的信息。
包包含的规则:

  • 一个包中只能拥有最多一个库单元包;
  • 包可以拥有任意多个二进制单元包;
  • 包内必须存在至少一个单元包(库单元包或二进制单元包)。

Cargo会默认将src/main.rs视作一个二进制单元包的根节点而无需指定,这个二进制单元包与包拥有相同的名称。当包中同时存在src/main.rssrc/lib.rs时,就会分别存在一个二进制单元包与一个库单元包,它们拥有与包相同的名称,可以在路径src/bin下添加源文件来创建出更多的二进制单元包,这个路径下的每个源文件都会被视作单独的二进制单元包。
单元包可以将相关的功能分组,并放到同一作用域下,这样便可以使这些功能轻松地在多个项目中共享。
将单元包的功能保留在它们自己的作用域中有助于指明某个特定功能来源于哪个单元包,并避免可能的命名冲突。

2、通过定义模块来控制作用域及私有性:

模块允许将单元包内的代码按照可读性与易用性来进行分组,同时还允许控制条目的私有性。即模块决定了一个条目是否可以被外部代码使用(公用),或者仅仅只是一个内部的实现细节而不对外暴露(私有)。
模块内可以继续定义其他模块,也同样可以包含其他条目的定义,例如:结构体、枚举、常量、trait等。
在Rust中src/main.rssrc/lib.rs被称为单元包的根节点,这两个文件的内容各自组成了一个名为crate的模块,并位于单元包模块结构的根部。这个模块结构也被称为模块树
模块树的结构:
在这里插入图片描述
当模块A被包含在模块B内时,将模块A称为模块B的子节点,模块B称为模块A的父节点。

3、用于在模块树中指明条目的路径:

为了在Rust的模块树中找到某个条目,同样需要使用路径。例如,在调用某个函数的时候,必须知道它的路径。
路径有两种形式:

  • 使用单元包名或字面量crate从根节点开始的绝对路径;
  • 使用self、super或内部标识符从当前模块开始的相对路径。

绝对路径与相对路径都由至少一个标识符组成,标识符之间使用双冒号::分隔。
Rust中的所有条目(函数、方法、结构体、枚举、模块及常量)默认都是私有的。处于父级模块中的条目无法使用子模块中的私有条目,但子模块中的条目可以使用它所有祖先模块中的条目。虽然子模块包装并隐藏了自身的实现细节,但它却依然能够感知当前定义环境中的上下文。

(1)、使用pub关键字来暴露路径:

为了能够让父模块中可以正常访问子模块中的函数,可以使用关键字pub来标记函数。示例:

mod front_of_house{pub mod hosting{pub add_to_waitlist(){}}
}
pub fn eat_at_restaurant() {// 绝对路径crate::front_of_house::hosting::add_to_waitlist();// 相对路径front_of_house::hosting::add_to_waitlist();
}

注意:仅将父模块设为pub,在访问时,子模块仍是私有的,对外不可见,需要将要调用的最终模块也设置为pub。一个模块的同级节点之间的访问不需要使用关键字pub

(2)、使用super关键字开始构造相对路径:

可以从父模块开始构造相对路径,这一方式需要在路径起始处使用super关键字。
示例:

fn serve_order(){}
mod back_of_house {fn fix_incorrect_order(){cook_order();super::serve_order();}
}

由于fix_incorrect_order函数处于back_of_house模块内,所以可以使用super关键字来跳转至back_of_house的父模块,也就是根模块处。从它开始,可以成功地找到 serve_order。

(3)、将结构体或枚举声明为公共的:

结构体和枚举都可以使用pub来声明为公共的,但是二者存在一定的差异。当在结构体前面使用pub时,结构体本身就成为了公共结构体,但是它的字段依旧保持了私有状态。可以逐一决定是否将某个字段公开。
示例:

mod back_of_house {pub struct Breakfast {pub toast: String,seasonal_fruit: String,}impl Breakfast {pub fn summer(toast: &str) -> Breakfast {Breakfast {toast: String::from(toast),seasonal_fruit: String::from("peaches"),}}}
}

这里的toast是公共的,所以可以在别的函数中使用点号读写,但是seasonal_fruit字段是私有的,不可以直接使用点号进行读写。因为back_of_house::Breakfast拥有了一个私有字段,所以这个结构体需要提供一个公共的关联函数来构造Breakfast的实例(也就是本例中的summer)。如果缺少了这样的函数,将无法在别的函数中中创建任何的Breakfast实例。
与结构体不同的是,将一个枚举声明为公共的时,它所有的变体都自动变为了公共的,仅需要在enum关键字前放置pub。
示例:

mod back_of_house{pub enum Appetizer{Soup,Salad,}
}

这里的Soup和Salad都具有公共属性。

4、用use关键字将路径导入作用域:

借助关键字use可以将路径引入作用域,并像使用本地条目一样来调用路径中的目录。

mod front_of_house {pub mod hosting {pub fn add_to_waitlist() {}}
}
use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {hosting::add_to_waitlist();hosting::add_to_waitlist();hosting::add_to_waitlist();
}

使用use来指定相对路径稍有一些不同。必须在传递给use的路径的开始处使用关键字self,而不是从当前作用域中可用的名称开始。

mod front_of_house {pub mod hosting {pub fn add_to_waitlist() {}}
}
use self::front_of_house::hosting;
pub fn eat_at_restaurant() {hosting::add_to_waitlist();hosting::add_to_waitlist();hosting::add_to_waitlist();
}

(1)、创建use路径时的惯用模式:

在使用关键字use指定函数路径时,只指定到函数的父模块,这意味着在调用函数时必须指定这个父模块,从而更清晰地表明当前函数有没有被定义在当前作用域,同样也能避免重复路径。

(2)、使用as关键字来提供新的名称:

使用use将同名类型引入作用域时所产生的问题还有另外一种解决办法:可以在路径后使用as关键字为类型指定一个新的本地名称,也就是别名。
示例:

use std::fmt::Result;
use std::io::Result as IoResult;
fn function1() -> Result {// --略
--
}
fn function2() -> IoResult<()> {// --略
--
}

(3)、使用pub usb重导出名称:

当我们使用use关键字将名称引入作用域时,这个名称会以私有的方式在新的作用域中生效。为了让外部代码能够访问到这些名称,可以通过组合使用pubuse实现。这项技术也被称作重导出。因为不仅将条目引入了作用域,而且使该条目可以被外部代码从新的作用域引入自己的作用域。

mod front_of_house {pub mod hosting {pub fn add_to_waitlist() {}}
}
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {hosting::add_to_waitlist();hosting::add_to_waitlist();hosting::add_to_waitlist();
}

(4)、使用嵌套的路径来清理众多use语句:

当想要使用同一个包或同一个模块内的多个条目时,将它们逐行列出会占据较多的纵向空间。可以在同一行内使用嵌套路径来将上述条目引入作用域。这一方法需要首先指定路径的相同部分,再在后面跟上两个冒号,接着用一对花括号包裹路径差异部分的列表。
示例:

use std::cmp::Ordering;
use std::io;
// ---略

可以写成:

use std::{cmp::Ordering, io};
// ---略

同理:

use std::io;
use std::io::Write;

可以写成:

use std::io::{self, Write};

(5)、通配符:

假如想要将所有定义在某个路径中的公共条目都导入作用域,那么可以在指定路径时在后面使用*通配符。
示例:

use std::collections::*;

上面这行use语句会将定义在std::collections内的所有公共条目都导入当前作用域。

相关文章:

Rust之包、单元包及模块

包&#xff1a;一个用于构建、测试并分享单元包的Cargo功能&#xff1b;单元包&#xff1a;一个用于生成库或可执行文件的树形模块结构&#xff1b;模块及use关键字&#xff1a;被用于控制文件结构、作用域及路径的私有性&#xff1b;路径&#xff1a;一种用于命名条目的方法&a…...

内存函数讲解

&#x1f495;"痛苦难以避免&#xff0c;而磨难可以选择。"-->村上春树&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;数据在内存中的存储 内存函数就是管理内存数据的函数&#xff0c;包含于头文件<string.h>中 1.memcpy函数-->内存…...

C语言假期作业 DAY 01

题目 1.选择题 1、执行下面程序&#xff0c;正确的输出是&#xff08; &#xff09; int x5,y7; void swap() { int z; zx; xy; yz; } int main() { int x3,y8; swap(); printf("%d,%d\n"&#xff0c;x, y)…...

2023牛客暑期多校-J-Qu‘est-ce Que C‘est?(DP)

题意&#xff1a; 给定长度为n的数列,要求每个数都在的范围&#xff0c;且任意长度大于等于2的区间和都大于等于0&#xff0c;问方案数。。 思路&#xff1a; 首先要看出是dp题&#xff0c;用来表示遍历到第i位且后缀和最小为x的可行方案数&#xff08;此时的后缀可以只有最…...

【141. 环形链表】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#x…...

ORB特征笔记

简介 ORB Oriented FAST Rotated BRIEF 前面的Oriented FAST说明的是它的关键点的选取是一种改良过的FAST&#xff0c;在FAST的基础上加了方向信息&#xff1b;后面的Rotated BRIEF是指特征描述符使用BRIEF描述子&#xff08;Binary Robust Independent Elementary Featur…...

12.Netty源码之整体架构脉络

Netty 整体架构脉络 Netty 的逻辑处理架构为典型网络分层架构设计&#xff0c;共分为网络通信层、事件调度层、服务编排层&#xff0c;每一层各司其职。 网络通信层 网络通信层的职责是执行网络 I/O 的操作。它支持多种网络协议和 I/O 模型的连接操作。当网络数据读取到内核缓冲…...

【ArcGIS Pro二次开发】(54):三调名称转用地用海名称

三调地类和用地用海地类之间有点相似但并不一致。 在做规划时&#xff0c;拿到的三调&#xff0c;都需要将三调地类转换为用地用海地类&#xff0c;然后才能做后续的工作。 一般情况下&#xff0c;三调转用地用海存在【一对一&#xff0c;多对一和一对多】3种情况。 前2种情况…...

3D Tiles官方示例资源下载链接

本文列出Cesium官方提供的 3D Tiles 1.0和1.1规范的9个示例切块集&#xff08;tileset&#xff09;。 有关如何使用本地服务器托管这些示例的详细信息&#xff0c;请参阅 INSTRUCTIONS.md。 推荐&#xff1a;用 NSDT设计器 快速搭建可编程3D场景。 1、Metadata Granularities …...

【Java】分支结构习题

【Java】分支结构 文章目录 【Java】分支结构题1 &#xff1a;数字9 出现的次数题2 &#xff1a;计算1/1-1/21/3-1/41/5 …… 1/99 - 1/100 的值。题3 &#xff1a;猜数字题4 &#xff1a;牛客BC110 X图案题5 &#xff1a;输出一个整数的每一位题6 &#xff1a; 模拟三次密码输…...

删除主表 子表外键没有索引的性能优化

整个表147M&#xff0c;执行时一个CPU耗尽&#xff0c; buffer gets 超过1个G&#xff0c; 启用并行也没有用 今天开发的同事问有个表上的数据为什么删不掉&#xff1f;我看了一下&#xff0c;也就不到100000条数据&#xff0c;表上有外键&#xff0c;等了5分钟hang在那里&…...

面向切面编程AOP

面向切面编程简介 IoC使软件组件松耦合。AOP让你能够捕捉系统中经常使用的功能&#xff0c;把它转化成组件。 AOP&#xff08;Aspect Oriented Programming&#xff09;&#xff1a;面向切面编程&#xff0c;面向方面编程。&#xff08;AOP是一种编程技术&#xff09; AOP是对…...

大学生活题解

样例输入&#xff1a; 3 .xA ... Bx.样例输出&#xff1a; 6思路分析&#xff1a; 这道题只需要在正常的广搜模板上多维护一个— —方向&#xff0c;如果当前改变方向&#xff0c;就坐标不变&#xff0c;方向变&#xff0c;步数加一&#xff1b;否则坐标变&#xff0c;方向不…...

flask的配置项

flask的配置项 为了使 Flask 应用程序正常运行&#xff0c;有多种配置选项需要考虑。下面是一些基本的 Flask 配置选项&#xff1a; DEBUG: 这个配置项决定 Flask 是否应该在调试模式下运行。如果这个值被设为 True&#xff0c;Flask 将会提供更详细的错误信息&#xff0c;并…...

暑假刷题第16天--7/28

143. 最大异或对 - AcWing题库&#xff08;字典树&#xff09; #include<iostream> using namespace std; const int N100005; int a[N]; int nex[10000007][2],cnt; void insert(int x){int p0;for(int i30;i>0;i--){int ux>>i&1;if(!nex[p][u])nex[p][u]…...

vue vite ts electron ipc arm64

初始化 npm init vue # 全选 yes npm i # 进入项目目录后使用 npm install electron electron-builder -D npm install commander -D # 额外组件增加文件 新建 plugins 文件夹 src/background.ts 属于主进程 ipcMain.on、ipcMain.handle 都用于主进程监听 ipc&#xff0c;…...

数据分析-关于指标和指标体系

一、电商指标体系 二、指标体系的作用 三、统计学中基本的分析手段...

Vue+ElementUI操作确认框及提示框的使用

在进行数据增删改查操作中为保证用户的使用体验&#xff0c;通常需要显示相关操作的确认信息以及操作结果的通知信息。文章以数据的下载和删除提示为例进行了简要实现&#xff0c;点击下载以及删除按钮&#xff0c;会出现对相关信息的提示&#xff0c;操作结果如下所示。 点击…...

宋浩线性代数笔记(二)矩阵及其性质

更新线性代数第二章——矩阵&#xff0c;本章为线代学科最核心的一章&#xff0c;知识点多而杂碎&#xff0c;务必仔细学习。 重难点在于&#xff1a; 1.矩阵的乘法运算 2.逆矩阵、伴随矩阵的求解 3.矩阵的初等变换 4.矩阵的秩 &#xff08;去年写的字&#xff0c;属实有点ugl…...

Linux之Shell 编程详解(二)

第 9 章 正则表达式入门 正则表达式使用单个字符串来描述、匹配一系列符合某个语法规则的字符串。在很多文 本编辑器里&#xff0c;正则表达式通常被用来检索、替换那些符合某个模式的文本。在 Linux 中&#xff0c;grep&#xff0c; sed&#xff0c;awk 等文本处理工具都支持…...

TCP网络通信编程之字节流

目录 【TCP字节流编程】 // 网络编程中&#xff0c;一定是server端先运行 【案例1】 【思路分析】 【客户端代码】 【服务端代码】 【结果展示】 【案例2】 【题目描述】 【注意事项】 【服务端代码】 【客户端代码】 【代码结果】 【TCP字节流编程】 // 网络编程中&a…...

【暑期每日一练】 day8

目录 选择题 &#xff08;1&#xff09; 解析&#xff1a; &#xff08;2&#xff09; 解析&#xff1a; &#xff08;3&#xff09; 解析&#xff1a; &#xff08;4&#xff09; 解析&#xff1a; &#xff08;5&#xff09; 解析&#xff1a; 编程题 题一 描述…...

maven的基本学习

maven https://www.bilibili.com/video/BV14j411S76G?p1&vd_source5c648979fd92a0f7ba8de0cde4f02a6e 1.简介 1.1介绍 Maven翻译为"专家"、“内行”&#xff0c;是Apache下的一个纯Java开发的开源项目。基于项目对象模型(缩写:POM)概念&#xff0c;Maven利用一…...

疲劳驾驶检测和识别2:Pytorch实现疲劳驾驶检测和识别(含疲劳驾驶数据集和训练代码)

疲劳驾驶检测和识别2&#xff1a;Pytorch实现疲劳驾驶检测和识别(含疲劳驾驶数据集和训练代码) 目录 疲劳驾驶检测和识别2&#xff1a;Pytorch实现疲劳驾驶检测和识别(含疲劳驾驶数据集和训练代码) 1.疲劳驾驶检测和识别方法 2.疲劳驾驶数据集 &#xff08;1&#xff09;疲…...

安防监控视频汇聚EasyCVR修改录像计划等待时间较长,是什么原因?

安防监控视频EasyCVR视频融合汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、云存储、回放与检…...

EXCEL数据自动web网页查询----高效工作,做个监工

目的 自动将excel将数据填充到web网页&#xff0c;将反馈的数据粘贴到excel表 准备 24KB的鼠标连点器软件&#xff08;文末附链接&#xff09;、Excel 宏模块 优势 不需要编程、web验证、爬虫等风险提示。轻量、稳定、安全。 缺点 效率没那么快 演示 宏环境 ht…...

visual studio 2022换背景遇到的问题

如果要自定义背景图&#xff0c;则可以下载ClaudialIDE 1.在拓展->点击拓展管理->右上角搜索background->点击下载ClaudialIDE->加载完之后需要关闭vs界面进行下载&#xff0c;下载失败&#xff0c;弹出“由于出现以下错误 无法安装一个或多个扩展”。 解决&#x…...

MODBUS-TCP转Ethernet IP 网关连接空压机 配置案例

本案例是工业现场应用捷米特JM-EIP-TCP的Ethernet/IP转Modbus-TCP网关连接欧姆龙PLC与空压机的配置案例。使用设备&#xff1a;欧姆龙PLC&#xff0c;捷米特JM-EIP-TCP网关&#xff0c; ETHERNET/IP 的电气连接 ETHERNET/IP 采用标准的 T568B 接法&#xff0c;支持直连和交叉接…...

Go重写Redis中间件 - GO实现TCP服务器

GO实现TCP服务器 首先新建一个项目go-redis,将config和lib包放到项目中,config.go用来解析配置,比如端口、功能、DB数;lib包有两个文件夹,分别是logger和sync,其中logger.go是一个日志框架,sync包中的bool.go包装了atomic操作,因为atomic原生没有bool类型,所以将uint…...

使用Kmeans算法完成聚类任务

聚类任务 聚类任务是一种无监督学习任务&#xff0c;其目的是将一组数据点划分成若干个类别或簇&#xff0c;使得同一个簇内的数据点之间的相似度尽可能高&#xff0c;而不同簇之间的相似度尽可能低。聚类算法可以帮助我们发现数据中的内在结构和模式&#xff0c;发现异常点和离…...