rust组织结构

一 、crate

crate称为箱。
crate有两种形式:二进制箱(binary crate)和库箱(library crate)。
二进制箱必须有一个 main 函数,可以编译为可执行程序。
库箱并没有 main 函数,它们也不会编译为可执行程序,它们只是提供一些函数供其他项目使用。

crate root叫箱的根,是一个源文件,Rust编译器以它为起始点,构建你的crate。

二、package

package称为包。包就是一个工程项目,包必须有一个Cargo.toml文件。
一个包至少包含一个箱,这些箱最多包含一个库箱,但可以包含任意数量的二进制箱。
使用cargo new命令创建包。包名就是目录名。
如果使用cargo new proj创建包,src目录下会默认生成一个main.rs源文件。
如果使用cargo new --lib proj命令创建包,src目录下会默认生成一个lib.rs源文件。
Cargo约定:
src/main.rs是一个二进制箱的根。此箱名与包名相同。
src/lib.rs是一个库箱的根。此箱名与包名相同。
如果包只有src/main.rs文件,意味着包只含有一个二进制箱。此箱名与包名相同。
如果一个包同时含有 src/main.rs和src/lib.rs,则它包含两个箱:一个二进制箱和一个库箱,且名字都与包相同。
通过将文件放在src/bin目录下,一个包可以拥有多个二进制箱:src/bin下的每个文件都会编译成一个独立的二进制箱。此目录下的箱名与包名不同,而是与文件名相同。

三、模块

rust模块就是命名空间。

(一)声明模块
使用mod关键字来声明模块。

mod hello {pub fn say_hello() {println!("hello world");}
}

模块内的项默认是private,外部不可见,如果要外部可见需要加pub

模块可以嵌套,形成模块树(module tree)

mod nation {mod government {fn govern() {}}mod congress {fn legislate() {}}mod court {fn judicial() {}}
}

每个箱都是一个模块树。src/main.rs 和 src/lib.rs 叫做箱根,是因为这两个文件为模块树创建了一个名为 crate 的根模块。

crate
└──nation├──government│     └──govern├──congress│     └──legislate└──court└──judicial

(二)使用模块
1.模块的路径
如何在模块树中找到一个项的位置,我们使用路径,就像在文件系统使用路径一样。为了调用一个函数,我们需要知道它的路径。
路径有两种形式:
绝对路径(absolute path)是以箱根开头的全路径:引用外部箱代码,是以箱名开头的绝对路径;引用当前箱代码,则以crate开头。
相对路径(relative path)从当前所在模块开始,以 self、super 或当前模块的标识符开头。
(1)路径以双冒号(::)为分割符
例如:

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

(2)使用以 super 开头的相对路径

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

(3)使用外部箱
必须先添加依赖。在Cargo.toml中添加外部箱所在的包
比如,

[dependencies]
rand = "0.8.5"

Cargo要从 crates.io 下载 rand 和其依赖。
这样就可以使用绝对路径使用外部箱了

use rand::Rng;
fn main() {let secret_number = rand::thread_rng().gen_range(1..101);
}

(4)std标准库
std也是外部箱。因为标准库随Rust语言一同分发,无需修改 Cargo.toml 来引入 std
比如,

let mut guess = String::new();
std::io::stdin().read_line(&mut guess).expect("failed readline");

2.use语句
无论是使用绝对路径还是相对路径都不便,我们可以使用 use 关键字创建一个短路径。

(1)use关键字将模块标识符引入当前作用域:
实例

mod nation {pub mod government {pub fn govern() {}}
}
use crate::nation::government::govern;
fn main() {govern();
}

use关键字把govern标识符导入到了当前的模块下,可以直接使用。

(2)可以使用use as为标识符添加别名:
实例

mod nation {pub mod government {pub fn govern() {}}pub fn govern() {}
}
use crate::nation::government::govern;
use crate::nation::govern as nation_govern;
fn main() {nation_govern();govern();
}

这里有两个govern函数,一个是nation下的,一个是government下的,我们用as将nation下的取别名nation_govern。两个名称可以同时使用。

(3)use关键字可以与pub关键字配合使用:
实例

mod nation {pub mod government {pub fn govern() {}}pub use government::govern;
}
fn main() {nation::govern();
}

(4)使用大括号引入相同模块的多个子模块,可以显著减少 use 语句的数量
比如,

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

(5)使用通配符*引入所有子模块
例子

use std::collections::*;

将 std::collections 中所有公有项引入当前作用域

(三)将模块分割进不同文件
到目前为止,都是在一个文件中定义多个模块。当模块变得更大时,你可能想要将它们移动到单独的文件中。
例如,

文件名: src/lib.rs
mod front_of_house;	//声明front_of_house模块,其内容将位于src/front_of_house.rs
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {hosting::add_to_waitlist();
}
文件名: src/front_of_house.rs
pub mod hosting {pub fn add_to_waitlist() {}
}

在src/front_of_house.rs中定义front_of_house模块
在mod front_of_house后使用分号,而不是代码块,表示在其他文件中定义模块。Rust会在与模块同名的文件中查找模块的代码。
继续重构我们例子,将hosting模块也提取到其自己的文件中

文件名: src/front_of_house.rs
pub mod hosting;

创建一个src/front_of_house目录,在src/front_of_house/hosting.rs文件中定义hosting模块:

文件名: src/front_of_house/hosting.rs
pub fn add_to_waitlist() {}

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

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

相关文章

Arm64体系架构-MPIDR_EL1寄存器

背景 在Arm64多核处理器中, 各核间的关系可能不同. 比如1个16 core的cpu, 每4个core划分为1个cluster,共享L2 cache. 当我们需要从core 0将任务调度出来时,如果优先选择core 1~3, 那么性能明显时优于其他core的. 那么操作系统怎么知道core之间这样的拓扑信息呢? Arm提供了MPID…

Selenium+Phantomjs动态获取CSDN下载资源信息和评论

源代码 # codingutf-8 from selenium import webdriver from selenium.webdriver.common.keys import Keys import selenium.webdriver.support.ui as ui from selenium.webdriver.common.action_chains import ActionChains import time import re…

分享好用的Cloudflare测速文件

引言 有时候我们想测试一下自己的带宽,或者梯子的速度。又或者我们想看看我们服务器的速度到底有多快?那么就需要一个大文件来支撑我们进行这样的测试。 而这样的测速文件需要有两个特性: 不受速率限制,也就是说能把你的带宽拉…

登录系统的时候账号和密码加密传输

1、登录系统的时候账号和密码加密传输,前端解密,后端解密 2、前端点击登录按钮的执行方法 function loginSubmit() {//先把账号的属性设置为password,这样点击登录按钮,看到的就是加密后的账号$("input[nameusername]"…

FPGA设计时序约束三、设置时钟组set_clock_groups

目录 一、背景 二、时钟间关系 2.1 时钟关系分类 2.2 时钟关系查看 三、异步时钟组 3.1 优先级 3.2 使用格式 3.3 asynchronous和exclusive 3.4 结果示例 四、参考资料 一、背景 Vivado中时序分析工具默认会分析设计中所有时钟相关的时序路径,除非时序约束…

Java包装类、装箱和拆箱

在 java 的设计中提倡一种思想,即一切皆对象。但是从数据类型的划分中,我们知道 Java 中的数据类型分为基本数据类型和引用数据类型,但是基本数据类型怎么能够称为对象呢?于是 Java 为每种基本数据类型分别设计了对应的类&#xf…

引导滤波融合matlab

引导滤波(Guided Filter)是一种用于图像增强和融合的技术,它可以用于将一幅图像的细节信息(引导图像)融合到另一幅图像(目标图像)中。在MATLAB中,你可以使用以下步骤来执行引导滤波融…

Games104现代游戏引擎笔记 基础ai

游戏AI navigation(导航系统) 地图的表达形式, 寻路,路径优化 Map representation: 1.可行走区域(物理碰撞,跳跃距离,攀爬高度) 2.表达形式:waypoint networks(路点网络图)&#…

交互式ICP

以下程序演示如何编写交互式ICP查看器。该程序将加载点云并对其进行刚性变换。之后&#xff0c;使用ICP算法将变换后的点云与原来的点云对齐。每次用户按下“空格”&#xff0c;进行ICP迭代&#xff0c;刷新可视化界面。 代码实现 资源准备 monkey.ply #include <string&…

I/O多路复用【Linux/网络】(C++实现select、poll和epoll服务器)

阅读前导&#xff1a; “I/O 多路复用”处于知识树中网络和操作系统的最后&#xff0c;因此本文默认读者有计算机网络和操作系统的基础。 1. 引入&#xff1a;C10K 问题 c10k 问题是指如何让一个服务器同时处理超过 10000 个客户端的连接&#xff0c;这是一个网络编程中的经…

STM32+USB3300复位枚举异常的问题

关键字&#xff1a;STM32F4&#xff0c;STM32H7&#xff0c;USB3300&#xff0c;USBHS&#xff0c;Reset复位 F4和H7用的都是DWC2的USBIP&#xff0c;我的板子上3300单片机工作的很好&#xff0c;插入枚举一切正常&#xff0c;但是设备收到上位机的复位命令后&#xff0c;单片…

ubuntu安装ssh

安装 OpenSSH 服务器&#xff08;如果尚未安装&#xff09;&#xff1a; apt-get update && apt-get upgrade -y sudo apt-get install -y openssh-server 检查 SSH 服务是否正在运行&#xff1a; sudo service ssh status 如果 SSH 服务未运行&#xff0c;请通过以…

Redis之主从复制,哨兵模式,集群

Redis之主从复制&#xff0c;哨兵模式&#xff0c;集群 1、主从复制1.1主从复制概述1.2Redis主从复制作用1.3Redis主从复制流程1.4部署Redis 主从复制 2、哨兵模式2.1哨兵模式原理2.2哨兵模式的作用2.3哨兵模式的结构2.4故障转移机制2.5搭建Redis 哨兵模式 3、Redis集群模式3.1…

Deep learning of free boundary and Stefan problems论文阅读复现

Deep learning of free boundary and Stefan problems论文阅读复现 摘要1. 一维一相Stefan问题1.1 Direct Stefan problem1.2 Inverse Type I1.3 Inverse Type II 2. 一维二相Stefan问题2.1 Direct Stefan problem2.2 Inverse Type I2.3 Inverse Type II 3. 二维一相Stefan问题…

数据结构 | (四) Queue

队列 &#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(First In First Out) 入队列&#xff1a;进行插入操作的一端称为 队尾&#xff08; Tail/Rear &#xff09; 出队列&#xff1a;进行删除操…

如何在mac a1系统下将mysql加入环境变量

mac系统若使用二进制软件包直接安装&#xff0c;默认路径为/usr/local/mysql 故而需要将/usr/local/mysql/bin加入到环境变量中即可&#xff0c;具体操作过程如下&#xff1a; 打开终端open -e .zprofile回车在TextEdit中追加如下内容&#xff0c;并保存 PATH"/usr/loc…

代码随想录 单调栈part2

503. 下一个更大元素 II 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nums 中每个元素的 下一个更大元素 。 数字 x 的 下一个更大的元素 是按数组遍历顺序&#xff0c;这个数字之后的第一个比它更大的数…

iOS App上架全流程及相关处理

iOS app上架总体流程&#xff1a; 一、IOS上架整个流程 1、申请开发者账号 2、创建APP ID及申请证书 3、itunes connect 创建APP 4、打包 上传APP 5、提交APP&#xff0c;上线成功 1、申请开发者账号 苹果开发者账号主要分为三种&#xff1a;个人账号、公司账号、企业账…

Linux安装单机PostgreSQL15.4

1. 联网rpm安装 1.1.关闭服务 ## 关闭防火墙 systemctl stop firewalld.service systemctl disable firewalld.service ## 关闭 selinux cat /etc/selinux/config SELINUXdisabled1.2.安装yum源 yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-…

深度学习基础知识 register_buffer 与 register_parameter用法分析

深度学习基础知识 register_buffer 与 register_parameter用法分析 1、问题引入2、register_parameter()2.1 作用2.2 用法 3、register_buffer()3.1 作用3.2 用法 1、问题引入 思考问题&#xff1a;定义的weight与bias是否会被保存到网络的参数中&#xff0c;可否在优化器的作用…