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

rust 包模块组织结构

一个包(package)可以拥有多个二进制单元包及一个可选的库单元包。随着包内代码规模的增长,你还可以将代码拆分到独立的单元包(crate)中,并将它作为外部依赖进行引用。

RUST提供了一系列的功能来帮助我们管理代码,包括决定哪些细节是暴露的、哪些细节是私有的,以及不同的作用域的命名管理。这些功能有时被统称为模块系统(module system),它们包括:

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

有几条规则决定了包可以包含哪些东西:首先,一个包中最多只能拥有一个库单元包。其次,包可以拥有多个二进制单元包。最后,包内必须存在至少一个单元包(库单元包或二进制单元包)。

cargo new my-project

当我们执行这条命令时,Cargo会生成一个包并创建相应的Cargo.toml文件。Cargo会默认将src/main.rs视作一个二进制单元包的根节点,这个二进制单元包与包拥有相同的名字。同样地,假设包的目录中包含文件src/lib.rsCargo也会自动将其视作与包同名的库单元包的根节点。

最初生产的包只包含源文件src/main.rs,这也意味着只包含一个名为my-project的二进制单元包。而假设包中同时存在src/main.rssrc/lib.rs,那么其中就会分别存在一个二进制单元包和一个库单元包,它们用于与包相同的名字。我们可以在路径src/bin下添加源文件来创建出更多的二进制单元包,这个路径下的每个源文件都会被视作单独的二进制单元包。

我们依赖的外部包,比如提供生成随机数功能的rand包就属于单元包。将单元包的功能保留在它们自己的作用域中有助于指明某个特定功能来源于哪个单元包,并避免可能得命名冲突。

定义模块来控制作用域及私有性

通过下面的方式创建一个库单元包,RUST也默认生成了单元测试的代码

cargo new --lib restaurant
// src/lib.rs
mod front_of_house {mod host {fn add_to_waitlist() {}fn seat_at_table() {}}mod serving {fn take_order() {}fn serve_order() {}fn take_payment() {}}
}

通过mod关键字开头来定义一个模块,接着指明这个模块的名称,并在其后使用一对花括号来包裹模块体。模块内可以定义其他模块,同样也可以包含其它条目的定义,比如结构体、枚举、常量等。

我们前面提到过,src/main.rssrc/lib.rs被称为单元包的根节点,因为这两个文件的内容各自组成了一个名为crate的模块,并位于单元包模块结构的根部。这个模块结构也被称为模块树(module tree),整个模块树都被放置在一个名为crate的隐式根模块下:

crate└── front_of_house     ├── hosting     │   ├── add_to_waitlist     │   └── seat_at_table     └── serving     ├── take_order     ├── serve_order     └── take_payment

为了在RUST模块树中找到某个条目,我们需要指定条目的路径,有两种形式:

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

绝对路径与相对路径都至少由一个标识符组成,标识符之间使用双冒号(::)分隔。

// src/lib.rs
pub fn eat_at_restaurant() {// 绝对路径crate::front_of_house::host::add_to_waitlist();// 相对路径front_of_house::host::add_to_waitlist();
}

我们使用绝对路径和相对路径来调用add_to_waitlist函数,大部分开发者更倾向使用绝对路径,因为我们往往会彼此独立地移动代码的定义与代码调用。

这段代码编译器报错,因为模块host是私有的。模块不仅仅被用于组织代码,同时还定义了RUST的私有边界(privacy boundary):外部代码无法访问那些由私有边界封装的细节。

RUST中的所有条目(函数、方法、结构体、枚举、模块及常量)默认都是私有的。处于父模块中的条目无法使用子模块中的私有条目,但子模块中的条目可以使用祖先模块中的条目。虽然子模块包装并隐藏了自身的实现细节,但它却依然能够感知当前定义环境的上下文。

我们需要给hosting模块添加pub关键字,之后我们便拥有了访问hosting子模块的权利。然后,我们再给add_to_waitlist添加pub关键字,私有性问题就解决了。整个过程中,编译正常通过而front_of_house模块并没有声明为pub,是因为front_of_houseeat_at_restaurant被定义在相同的模块下。

fn server_oreder() {}mod back_of_house {fn fix_incorrent_order() {cook_order();super::server_oreder();}fn cook_order() {}
}

代码从父模块开始构建相对路径,这一方式需要在路径起始处使用super关键字。这有些类似于在文件系统中使用..语法开始一段路径。例子中,我们通过super关键字来跳转至back_of_house的父模块,也就是根模块。

结构体及枚举声明为公开

当我们在结构体定义前使用pub时,结构体本身就成为了公共结构体,但它的字段依旧保持了私有状态。我们可以逐一决定是否将某个字段公开。

枚举与结构体不同,由于枚举只有在所有变体都公开时才能实现最大的功效,而为所有枚举变体添加pub则显得繁琐,因此所有的枚举变体默认都是公开的。但前提是我们将枚举声明为公开。

use将路径导入作用域

基于路径调用函数的写法使用起来有些重复和冗长,我们可以借助use关键字将路径引入作用域,并像使用本地条目一样来调用路径中的条目。

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

通过在单元包的根节点下添加use crate::front_of_house::hosthost成为该作用域下的一个有效名字,就如同host模块被定义在根节点下一样。当然,使用use将路径引入作用域时也需要遵守私有性规则。

实例中使用了绝对路径,使用相对路径也是可以的:use front_of_house::host

使用as提供新的名称

使用use将同名类型引入作用域时,可以在路径后使用as关键字为类型指定一个新的本地名字,也就是别名。

use std::fmt::Result;
use std::io::Result as IoResult;

使用嵌套的路径来清理众多use语句

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

这两条拥有共同的前缀std::io,该前缀还是第一条路径本身。可以在嵌套路径中使用self将两条路径合并至一行use语句中。

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

相关文章:

rust 包模块组织结构

一个包(package)可以拥有多个二进制单元包及一个可选的库单元包。随着包内代码规模的增长,你还可以将代码拆分到独立的单元包(crate)中,并将它作为外部依赖进行引用。 RUST提供了一系列的功能来帮助我们管…...

深入浅出:HTTPS单向与双向认证及证书解析20231208

介绍: 网络安全的核心之一是了解和实施HTTPS认证。本文将探讨HTTPS单向认证和双向认证的区别,以及SSL证书和CA证书在这些过程中的作用,并通过Nginx配置实例具体说明。 第一部分:HTTPS单向认证 定义及工作原理:HTTPS单向认证是一…...

水利安全监测方案——基于RTU200的解决方案

引言: 水资源是人类赖以生存的重要基础,对于保障水利系统安全运行以及应对自然灾害起着关键作用。为了实现水利安全监测的目标,我们提出了基于RTU200的解决方案。本方案将结合RTU200的可靠性、灵活性和高效性,为您打造一个全面的…...

安卓开发学习---kotlin版---笔记(一)

Hello word 前言:上次学习安卓,学了Java开发,简单的搭了几个安卓界面。这次要学习Kotlin语言,然后开发安卓,趁着还年轻,学点新东西,坚持~ 未来的你会感谢现在努力的你~ 主要学习资料&#xff1a…...

挑选在线客服系统的七大注意事项

越来越多的企业开始注重客户服务,所以在线客服系统也逐渐成为了电商企业不可或缺的一部分。然而在挑选在线客服系统的过程中,蛮多企业会遇到各种各样的问题,这就导致了最终选择的系统并不适合自己企业的需求。接下来我将提醒大家挑选在线客服…...

剧本杀小程序搭建:打造线上剧本杀新体验

剧本杀是一款以角色扮演为主的游戏,一度成为了年轻人的最喜爱的社交游戏。在剧本杀市场需求下,剧本杀规模也迅速上升。今年第一季度,剧本杀市场规模环比增长47%,市场整体消费水平逐渐呈上升趋势。 随着剧本杀的不断发展&#xff…...

机器学习实战:预测波士顿房价

前言: Hello大家好,我是Dream。 今天来学习一下机器学习中一个非常经典的案例:预测波士顿房价,在此过程中也会补充很多重要的知识点,欢迎大家一起前来探讨学习~ 一、导入数据 在这个项目中,我们利用马萨诸…...

基于个微机器人的开发

简要描述: 下载消息中的动图 请求URL: http://域名/getMsgEmoji 请求方式: POST 请求头Headers: Content-Type:application/jsonAuthorization:login接口返回 参数: 参数名必选类型说明…...

程序员学习方法

https://www.zhihu.com/question/24187324 https://www.zhihu.com/question/505750740 windows系统: 如何业余开展 Windows 系统的学习? - 知乎 wifi工作原理: WiFi的工作原理是什么? - 知乎 发...

VUE+THREE.JS 点击模型相机缓入查看模型相关信息

点击模型相机缓入查看模型相关信息 1.引入2.初始化CSS3DRenderer3.animate 加入一直执行渲染4.点击事件4.1 初始化renderer时加入监听事件4.2 触发点击事件 5. 关键代码分析5.1 移除模型5.2 创建模型上方的弹框5.3 相机缓入动画5.4 动画执行 1.引入 引入模型所要呈现的3DSprite…...

cpu 300% 爆满 内存占用不高 排查

top查询 cpu最高的PID ps -ef | grep PID 查看具体哪一个jar服务 jstack -l PID > ./jstack.log 下载/打印进程的线程栈信息 可以加信息简单分析 或进一步 查看堆内存使用情况 jmap -heap Java进程id jstack.log 信息示例 Full thread dump Java HotSpot(TM) 64-Bit Se…...

Halcon 简单的ORC 字体识别

文章目录 仿射变化识别 仿射变化 将图片进行矫正处理 dev_close_window() read_image(Image,C:/Users/Augustine/Desktop/halcon/image.png) *获取图片的大小 get_image_size(Image, Width, Height) *仿射运算获取图片的角度对图片进行矫正 *选中图片的区域 gen_rectangle1 (Re…...

12月7日作业

使用QT模仿一个登陆界面(模仿育碧Ubisoft登录界面) #include "myqq.h"MyQQ::MyQQ(QWidget *parent): QMainWindow(parent) {this->resize(880,550); //设置窗口大小this->setFixedSize(880,550); //固定窗口大小this->setStyleShee…...

【腾讯云HAI域探密】- AIGC应用助力企业降本增效之路

一、前言: 近年来,随着深度学习、大数据、人工智能、AI等技术领域的不断发展,机器学习是目前最火热的人工智能分支之一,是使用大量数据训练计算机程序,以实现智能决策、语音识别、图像处理等任务。 作者也是经过了以上…...

云原生之深入解析如何限制Kubernetes集群中文件描述符与线程数量

一、背景 linux 中为了防止进程恶意使用资源,系统使用 ulimit 来限制进程的资源使用情况(包括文件描述符,线程数,内存大小等)。同样地在容器化场景中,需要限制其系统资源的使用量。ulimit: docker 默认支持…...

Django的Auth模块

Auth模块 我们在创建好一个Django项目后执行数据库迁移命令会自动生成很多表 其中有auth_user等表 Django在启动之后就可以直接访问admin路由,需要输入用户名和密码,数据参考的就是auth_user表,并且必须是管理员才能进入 依赖于a…...

敏捷开发方法

理解: 极限编程(XP):敏捷开发的典型方法之一,是一种轻量级(敏捷)、高效,低风险、柔性、可预测的、科学的软件开发方法,它由价值观、原则、实践和行为4个部分组成。其中4大…...

vue 前端实现login页登陆 验证码

实现效果 // template <el-form :model"loginForm" :rules"fieldRules" ref"loginForm" label-position"left" label-width"0px" class"login-container"><span class"tool-bar"></sp…...

python 涉及opencv mediapipe知识,眨眼计数 供初学者参考

基本思路 我们知道正面侦测到人脸时&#xff0c;任意一只眼睛水平方向上的两个特征点构成水平距离&#xff0c;上下两个特征点构成垂直距离 当头像靠近或者远离摄像头时&#xff0c;垂直距离与水平距离的比值基本恒定 根据这一思路 当闭眼时 垂直距离变小 比值固定小于某一个…...

HTTP 和 HTTPS的区别

一、HTTP 1.明文传输&#xff0c;不安全 2.默认端口号&#xff1a;80 3.TCP三次握手即可 二、HTTPS 1.加密传输&#xff0c;更安全(在HTTP层与TCP层之间加上了SSL/TTL安全协议) SSL和TTL是在不同时期的两种叫法&#xff0c;含义相同。 2.默认端口号&#xff1a;443 3.TCP三…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...