青少年编程与数学 02-019 Rust 编程基础 16课题、包、单元包及模块
青少年编程与数学 02-019 Rust 编程基础 16课题、包、单元包及模块
- 一、包
- 1. **什么是 Crate?**
- 2. **Crate 的类型**
- 3. **Crate 的结构**
- 4. **使用 Crate**
- 5. **创建和管理 Crate**
- 6. **发布 Crate**
- 7. **Crate 的优势**
- 8. **示例**
- 创建一个 library crate
- 二、单元包
- 1. **单元包的定义**
- 2. **单元包的类型**
- 3. **单元包的结构**
- 文件说明:
- 4. **单元包的作用**
- 5. **创建单元包**
- 6. **单元包的元数据**
- 7. **单元包的构建和测试**
- 8. **发布单元包**
- 9. **单元包与 Crate 的关系**
- 10. **示例**
- 创建一个包含库和二进制 crate 的单元包
- 三、模块
- 1. **模块的作用**
- 2. **模块的定义**
- 使用 `mod` 关键字
- 使用单独的文件
- 使用 `mod.rs` 文件
- 3. **模块的可见性**
- 公开模块和项
- 重新导出(Re-export)
- 4. **模块的路径**
- 绝对路径
- 相对路径
- 5. **模块的嵌套**
- 6. **模块的最佳实践**
- 7. **示例**
- 文件结构
- `main.rs`
- `my_module.rs`
- `my_module/mod.rs`
- `my_module/nested.rs`
- 8. **模块与 crate 的关系**
- 总结
- 包(Package)
- 单元包(Unit Package)
- 模块(Module)
- 关系
课题摘要:
在 Rust 编程中,实现模块化编程和项目管理是提高代码可维护性、可扩展性和可复用性的关键。这里介绍一些实现模块化编程和项目管理的最佳实践。
关键词:包、单元包、模块
一、包
在 Rust 编程中,包(crate) 是代码的基本组织单位,也是 Rust 编译器处理的最小单位。它既可以是一个可执行程序(binary crate),也可以是一个可复用的库(library crate)。以下是对 Rust 中 crate 的详细解释:
1. 什么是 Crate?
Crate 是 Rust 中的代码包,可以被编译成可执行文件或库。它是 Rust 模块化编程的基础,允许开发者将代码划分为逻辑单元,并通过 crates.io 这样的生态系统进行共享。
2. Crate 的类型
Rust 中有两种主要的 crate 类型:
-
Binary Crates(二进制 crate)
- 生成可执行程序。
- 必须包含一个
main
函数作为程序的入口点。 - 示例:命令行工具、服务器等。
- 创建方式:
文件结构:cargo new my_binary
my_binary/ ├── Cargo.toml └── src/└── main.rs
-
Library Crates(库 crate)
- 提供可复用的功能,不生成可执行文件。
- 不包含
main
函数。 - 示例:
serde
(用于序列化和反序列化)。 - 创建方式:
文件结构:cargo new my_library --lib
my_library/ ├── Cargo.toml └── src/└── lib.rs
3. Crate 的结构
每个 crate 都有一个隐式的根模块(crate root),它是 crate 的入口点:
- 对于 binary crate,
main.rs
是 crate root。 - 对于 library crate,
lib.rs
是 crate root。
4. 使用 Crate
- 添加依赖:在
Cargo.toml
文件中声明依赖,然后使用cargo build
或cargo run
来下载和编译依赖。[dependencies] serde = "1.0"
- 使用外部 crate:
use serde::Serialize;
5. 创建和管理 Crate
- 创建新 crate:
cargo new crate_name --bin # 创建 binary crate cargo new crate_name --lib # 创建 library crate
- 管理依赖:
cargo add
:添加依赖。cargo remove
:移除依赖。cargo update
:更新依赖。
6. 发布 Crate
- 准备:确保
Cargo.toml
文件包含必要的元数据(如name
、version
、authors
等)。 - 发布:
cargo publish
- 登录:使用 crates.io 的 API token 进行身份验证。
7. Crate 的优势
- 模块化代码:将大型项目拆分为更小的组件,便于管理和维护。
- 复用性:在不同项目中复用 crate。
- 版本管理:通过 Cargo 管理依赖的版本。
- 社区贡献:访问 crates.io 上丰富的第三方 crate。
8. 示例
创建一个 library crate
cargo new my_library --lib
在 src/lib.rs
中定义功能:
pub fn greet(name: &str) -> String {format!("Hello, {}!", name)
}
在另一个 crate 中使用它:
# 在 Cargo.toml 中添加依赖
[dependencies]
my_library = { path = "../my_library" }
use my_library::greet;fn main() {let message = greet("Rust");println!("{}", message);
}
输出:
Hello, Rust!
通过合理使用 crate,可以显著提升 Rust 项目的组织性和可维护性。
二、单元包
在 Rust 编程中,单元包(Unit Package) 是一个由 Cargo 管理的代码单元,它包含一个或多个 crate。单元包是 Rust 项目的基本组织形式,用于构建、测试和发布代码。理解单元包的概念对于有效管理和组织 Rust 项目至关重要。
1. 单元包的定义
单元包(Package)是一个包含 Cargo.toml
文件的目录,它定义了如何构建和测试代码。一个单元包可以包含一个或多个 crate,但每个 crate 都是独立编译的。
2. 单元包的类型
单元包可以包含以下类型的 crate:
- Library Crate:提供可复用的功能,生成
.rlib
或.so
文件。 - Binary Crate:生成可执行文件。
- Example Crates:用于演示如何使用库功能的示例代码。
- Test Crates:用于测试的代码。
- Benchmark Crates:用于性能测试的代码。
3. 单元包的结构
一个典型的单元包的目录结构如下:
my_package/
├── Cargo.toml
├── src/
│ ├── lib.rs # Library crate root
│ └── main.rs # Binary crate root(可选)
├── examples/
│ └── example1.rs # Example crate
├── tests/
│ └── integration_test.rs # Test crate
└── benches/└── benchmark.rs # Benchmark crate
文件说明:
Cargo.toml
:定义包的元数据和依赖关系。src/
:包含 crate 的源代码。lib.rs
:库 crate 的根文件。main.rs
:二进制 crate 的根文件(可选)。
examples/
:包含示例代码,用于演示如何使用库。tests/
:包含集成测试代码。benches/
:包含基准测试代码。
4. 单元包的作用
- 代码组织:将相关的代码组织在一起,便于管理和维护。
- 依赖管理:通过
Cargo.toml
管理依赖,确保项目的一致性。 - 构建和测试:使用 Cargo 提供的命令(如
cargo build
、cargo test
)来构建和测试代码。 - 发布:将包发布到 crates.io,供其他开发者使用。
5. 创建单元包
使用 Cargo 创建一个新的单元包:
cargo new my_package
这将创建一个包含 Cargo.toml
和 src/
目录的基本单元包结构。
6. 单元包的元数据
在 Cargo.toml
文件中,可以定义单元包的元数据,例如:
[package]
name = "my_package"
version = "0.1.0"
edition = "2021"[dependencies]
serde = "1.0"
7. 单元包的构建和测试
- 构建:
cargo build
- 运行:
cargo run
- 测试:
cargo test
- 基准测试:
cargo bench
8. 发布单元包
将单元包发布到 crates.io:
cargo publish
在发布之前,需要确保 Cargo.toml
中的元数据完整,并且已经登录到 crates.io。
9. 单元包与 Crate 的关系
- 单元包 是一个包含
Cargo.toml
文件的目录,用于组织和管理代码。 - Crate 是单元包中的一个代码单元,可以是库或可执行文件。
- 一个单元包可以包含多个 crate,但每个 crate 都是独立编译的。
10. 示例
创建一个包含库和二进制 crate 的单元包
cargo new my_package --lib
cd my_package
cargo new -b my_binary
目录结构:
my_package/
├── Cargo.toml
├── src/
│ └── lib.rs # Library crate
└── my_binary/├── Cargo.toml└── src/└── main.rs # Binary crate
在 my_package/Cargo.toml
中添加对 my_binary
的依赖:
[dependencies]
my_binary = { path = "my_binary" }
在 my_binary/src/main.rs
中使用库 crate:
use my_package::my_function;fn main() {my_function();
}
通过合理使用单元包和 crate,可以有效地组织和管理 Rust 项目,提高代码的可维护性和复用性。
三、模块
在 Rust 编程中,模块(Module) 是用于组织代码的工具,它可以帮助开发者将代码划分为逻辑单元,提高代码的可维护性和可读性。模块还可以控制代码的可见性(即封装性),隐藏内部实现细节,只暴露必要的接口。以下是对 Rust 中模块的详细解释:
1. 模块的作用
模块的主要作用包括:
- 代码组织:将相关的函数、结构体、枚举等组织在一起,便于管理。
- 封装性:控制代码的可见性,隐藏内部实现细节。
- 命名空间管理:避免命名冲突,通过模块路径区分同名的项。
2. 模块的定义
在 Rust 中,模块可以通过以下方式定义:
使用 mod
关键字
在同一个文件中定义模块:
mod my_module {pub fn my_function() {println!("Hello from my_module!");}
}
使用单独的文件
将模块定义为单独的 .rs
文件,文件名即为模块名:
src/
├── main.rs
└── my_module.rs
在 main.rs
中声明模块:
mod my_module;
在 my_module.rs
中定义模块内容:
pub fn my_function() {println!("Hello from my_module!");
}
使用 mod.rs
文件
对于更复杂的项目,可以使用包含 mod.rs
文件的目录来定义模块:
src/
├── main.rs
└── my_module/├── mod.rs└── my_function.rs
在 mod.rs
中声明子模块:
pub mod my_function;
在 my_function.rs
中定义函数:
pub fn my_function() {println!("Hello from my_function!");
}
在 main.rs
中声明模块:
mod my_module;
3. 模块的可见性
Rust 中的模块和模块内的项默认是私有的(private),只有通过 pub
关键字标记的项才能在模块外部访问。
公开模块和项
pub mod my_module {pub fn my_function() {println!("Hello from my_module!");}
}
在模块外部访问:
my_module::my_function();
重新导出(Re-export)
可以使用 pub use
将模块内的项重新导出,使其在更高层次的模块中可用:
pub mod my_module {pub fn my_function() {println!("Hello from my_module!");}
}pub use my_module::my_function;
在模块外部访问:
my_function();
4. 模块的路径
模块路径用于唯一标识模块中的项。路径可以是绝对路径(从 crate 根开始)或相对路径(从当前模块开始)。
绝对路径
crate::my_module::my_function();
相对路径
my_module::my_function();
5. 模块的嵌套
模块可以嵌套,形成更复杂的结构:
mod my_module {pub mod nested_module {pub fn nested_function() {println!("Hello from nested_module!");}}
}
访问嵌套模块中的项:
my_module::nested_module::nested_function();
6. 模块的最佳实践
- 合理划分模块:将相关的功能组织到同一个模块中,避免模块过大或过小。
- 控制可见性:只公开必要的接口,隐藏内部实现细节。
- 使用清晰的命名:模块名称应具有描述性,避免使用过于通用的名称。
- 避免命名冲突:通过模块路径区分同名的项。
- 使用
mod.rs
文件:对于大型项目,使用mod.rs
文件来组织模块结构,便于维护。
7. 示例
以下是一个完整的示例,展示如何定义和使用模块:
文件结构
src/
├── main.rs
├── my_module.rs
└── my_module/├── mod.rs└── nested.rs
main.rs
mod my_module;fn main() {my_module::my_function();my_module::nested::nested_function();
}
my_module.rs
pub fn my_function() {println!("Hello from my_module!");
}pub mod nested;
my_module/mod.rs
pub mod nested;
my_module/nested.rs
pub fn nested_function() {println!("Hello from nested_module!");
}
8. 模块与 crate 的关系
- Crate 是 Rust 中的代码包,是编译器处理的最小单位。
- 模块 是 crate 内部的代码组织单元,用于划分逻辑和控制可见性。
- 每个 crate 都有一个隐式的根模块,即
main.rs
或lib.rs
。
通过合理使用模块,可以显著提升 Rust 项目的组织性和可维护性,同时确保代码的封装性和复用性。
总结
Rust 的模块化编程通过 包(Package)、单元包(Unit Package) 和 模块(Module) 三个层次来组织代码,实现清晰的结构和高效的代码管理。
包(Package)
包是 Rust 中的代码组织单元,由 Cargo.toml
文件定义,包含一个或多个 crate。包是 Cargo 管理的最小单位,用于构建、测试和发布代码。一个包可以包含:
- 库 crate:提供可复用的功能。
- 二进制 crate:生成可执行文件。
- 示例、测试和基准测试代码:用于演示和验证功能。
单元包(Unit Package)
单元包是包含 Cargo.toml
的目录,用于组织和管理包的内容。它定义了包的元数据、依赖关系和构建配置。单元包可以包含多个 crate,但每个 crate 都是独立编译的。
模块(Module)
模块是 crate 内部的代码组织单元,用于划分逻辑和控制可见性。模块通过 mod
关键字定义,可以包含函数、结构体、枚举等。模块的主要作用包括:
- 代码组织:将相关的功能组织在一起。
- 封装性:通过
pub
关键字控制可见性,隐藏内部实现。 - 命名空间管理:避免命名冲突,通过路径访问模块中的项。
关系
- 包 是项目的顶层组织形式,由 Cargo 管理。
- 单元包 是包的具体实现,包含
Cargo.toml
和源代码。 - 模块 是 crate 内部的组织单元,用于划分逻辑和控制可见性。
通过合理使用包、单元包和模块,Rust 项目可以实现清晰的结构、高效的代码管理和良好的封装性,从而提高代码的可维护性和复用性。
相关文章:
青少年编程与数学 02-019 Rust 编程基础 16课题、包、单元包及模块
青少年编程与数学 02-019 Rust 编程基础 16课题、包、单元包及模块 一、包1. **什么是 Crate?**2. **Crate 的类型**3. **Crate 的结构**4. **使用 Crate**5. **创建和管理 Crate**6. **发布 Crate**7. **Crate 的优势**8. **示例**创建一个 library crate 二、单元…...
bat 批处理获取日期、时间
在Windows批处理脚本编程中,获取当前日期和时间是一项常见且重要的操作。 1. 获取当前日期和时间的基本脚本 echo off for /F "tokens2" %%i in (date /t) do set mydate%%i set mytime%time% echo Current time is %mydate%:%mytime%输出示例ÿ…...
手写tomcat:基本功能实现(3)
TomcatRoute类 TomcatRoute类是Servlet容器,是Tomcat中最核心的部分,其本身是一个HashMap,其功能为:将路径和对象写入Servlet容器中。 package com.qcby.config;import com.qcby.Util.SearchClassUtil; import com.qcby.servlet…...
Spring Cloud Seata 快速入门及生产实战指南
文章目录 前言一、快速入门(AT模式)二、生产环境实战要点总结 前言 上一篇博客带大家深入解析Seata的核心原理及架构,理解了“为什么需要分布式事务”以及“Seata如何解决数据一致性问题”,相信大家已经对分布式事务的理论框架有…...
电商平台自动化
为什么要进行独立站自动化 纯人工测试人力成本高,相对效率低 回归测试在通用模块重复进行人工测试,测试效率低 前期调研备选自动化框架(工具): Katalon Applitools Testim 阿里云EMAS Playwright Appium Cypress 相关…...
Java微服务架构实战:Spring Boot与Spring Cloud的完美结合
Java微服务架构实战:Spring Boot与Spring Cloud的完美结合 引言 随着云计算和分布式系统的快速发展,微服务架构已成为现代软件开发的主流模式。Java作为企业级应用开发的核心语言,结合Spring Boot和Spring Cloud,为开发者提供了…...
王树森推荐系统公开课 召回11:地理位置召回、作者召回、缓存召回
GeoHash 召回 属于地理位置召回,用户可能对附近发生的事情感兴趣。GeoHash 是一种对经纬度的编码,地图上每个单位矩形的 GeoHash 的前几位是相同的,GeoHash 编码截取前几位后,将相同编码发布的内容按时间顺序(先是时间…...

无刷直流水泵构成及工作原理详解--【其利天下技术】
无刷直流水泵是相对于有刷直流泵而言的。 一:无刷直流水泵简介 无刷直流水泵即BLDC PUMP,其中“BL”意为“无刷”,DC即直流电机。 无刷直流水泵(BLDC PUMP)以电子换向器取代了机械换向器,所以无刷直流水泵既具有直流电机良好的调…...
less中使用 @supports
在Less中使用supports supports 是CSS的条件规则,用于检测浏览器是否支持特定的CSS属性或值。在Less中,你可以像在普通CSS中一样使用supports,同时还能利用Less的特性来增强它。 基本用法 /* 检测浏览器是否支持display: flex */ supports …...

大数据:新能源汽车宇宙的未来曲率引擎
** 发布日期:2025-05-14** 关键词:大数据、新能源、机器学习、碳中和、CSDN爆款 1. 大数据科普:定义、特征与技术核心 1.1 什么是大数据? 大数据(Big Data)指规模巨大、类型多样、生成速度快且价值密度低…...

【Java ee】关于抓包软件Fiddler Classic的安装与使用
Web Debugging Proxy Tool | Fiddler Classic 安装网站↑ 下载好安装包之后,双击一路next就可以了 一、抓包软件 电脑上安装了抓包软件之后,抓包软件就可以监听你的网卡上通过的数据。 本来是你的客户端通过网卡,把数据发给目标服务器&a…...
第五部分:第五节 - Express 路由与中间件进阶:厨房的分工与异常处理
随着你的 Express 应用变得越来越大,所有的路由和中间件都写在一个文件里会变得难以管理。这时候就需要将代码进行拆分和组织。此外,一个健壮的后端应用必须能够优雅地处理错误和一些常见的 Web 开发问题,比如跨域。 路由模块化 (express.Ro…...
在 CentOS 7.9 上部署 node_exporter 并接入 Prometheus + Grafana 实现主机监控
文章目录 在 CentOS 7.9 上部署 node_exporter 并接入 Prometheus Grafana 实现主机监控环境说明node_exporter 安装与配置下载并解压 node_exporter创建 Systemd 启动服务验证服务状态验证端口监听 Prometheus 配置 node_exporter 监控项修改 prometheus.yml重新加载 Prometh…...

C++--内存管理
内存管理 1. C/C内存分布 在C语言阶段,常说局部变量存储在栈区,动态内存中的数据存储在堆区,静态变量存储在静态区(数据段),常量存储在常量区(代码段),其实这里所说的栈…...
Java实现PDF加水印功能:技术解析与实践指南
Java实现PDF加水印功能:技术解析与实践指南 在当今数字化办公环境中,PDF文件因其跨平台兼容性和格式稳定性而被广泛应用。然而,为了保护文档的版权、标记文档状态(如“草稿”“机密”等)或增加文档的可追溯性…...
Django + Celery 打造企业级大模型异步任务管理平台 —— 从需求到完整实践(含全模板源码)
如需完整工程文件(含所有模板),可回复获取详细模板代码。 面向人群:自动化测试工程师、企业中后台开发人员、希望提升效率的 AI 业务从业者 核心收获:掌握 Django 三表关系设计、Celery 异步任务实践、基础 Web 交互与前后端分离思路,源码可直接落地,方便二次扩展 一、系…...

TC3xx学习笔记-UCB BMHD使用详解(二)
文章目录 前言Confirmation的定义Dual UCB: Confirmation StatesDual UCB: Errored State or ECC Error in the UCB Confirmation CodesECC Error in the UCB ContentDual Password UCB ORIG and COPY Re-programming UCB_BMHDx_ORIG and UCB_BMHDx_COPY (x 0-3)BMHD Protecti…...

用Python实现数据库数据自动化导出PDF报告:从MySQL到个性化文档的全流程实践
本文将介绍如何使用Python构建一个自动化工具,实现从MySQL数据库提取员工数据,并为每位员工生成包含定制化表格的PDF报告。通过该方案,可显著提升数据导出效率,避免手动操作误差,同时支持灵活的格式定制。 需求&#…...

实战设计模式之状态模式
概述 作为一种行为设计模式,状态模式允许对象在其内部状态改变时,改变其行为。这种模式通过将状态逻辑从对象中分离出来,并封装到独立的状态类中来实现。每个状态类代表一种特定的状态,拥有自己的一套行为方法。当对象的状态发生变…...
人工智能、机器学习与深度学习:概念解析与内在联系
人工智能、机器学习与深度学习:概念解析与内在联系 一、人工智能(Artificial Intelligence, AI) (一)人工智能的定义 人工智能的定义随着技术发展不断演变。从广义上讲,人工智能是指通过计算机技术实现的…...

什么是着色器 Shader
本人就是图形学结课了,对 OpenGL着色器还有很多疑问嘿嘿 文章目录 为什么要有着色器vshaderfshader 本文围绕 vshader 和 fshader 代码示例讲解。 (着色器代码取自本人简单OpenGL项目 https://github.com/DBWGLX/-OpenGL-3D-Lighting-and-Shadow-Modeli…...

Redis的主从架构
主从模式 全量同步 首先主从同步过程第一步 会先比较replication id 判断是否是第一次同步假设为第一次同步 那么就会 启动bgsave异步生成RDB 同时fork子进程记录生成期间的新数据发送RDB给从节点 清空本地数据写入RDB 增量同步 对比ReplicationID不同因此选择增量同步在Rep…...

博客系统功能测试
博客系统网址:http://8.137.19.140:9090/blog_list.html 主要测试内容 功能测试、界面测试、性能测试、易用性测试、安全测试、兼容性测试、弱网测试、安装卸载测试、压力测试… 测试方法及目的 利用selenium和python编写测试脚本,对博客系统进行的相关…...

【深度学习新浪潮】什么是多模态大模型?
多模态大模型是人工智能领域的前沿技术方向,它融合了多种数据模态(如文本、图像、语音、视频、传感器数据等),并通过大规模参数模型实现跨模态的联合理解与生成。简单来说,这类模型就像人类一样,能同时“看”“听”“读”“说”,并将不同信息关联起来,完成复杂任务。 …...

机器学习前言2
1.机器学习 2.机器学习模型 3.模型评价方法 4.如何选择合适的模型 介绍 机器学习(Machine Learning, ML)是人工智能(AI)的核心分支,致力于通过数据和算法让计算机系统自动“学习”并改进性能,而无需显式编…...

【成品设计】基于Arduino的自动化农业灌溉系统
《基于STM32的单相瞬时值反馈逆变器》 硬件设计: ESP-C3最小系统板:主控芯片,内部集成wifi。土壤湿度传感器:采集土壤湿度。温度传感器:采集土壤温度。水泵模块:水泵继电器软管。按键3个:参数…...

前端页面 JavaScript数据交互
前言:学习JavaScript为前端设置动态效果,实现交互。JavaScript是一种广泛应用于网页开发的脚本语言,它能够使网页变得更加动态和交互性。作为一种客户端脚本语言,JavaScript可以被嵌入到HTML中,并且可以被所有现代的网…...

esp32课设记录(三)mqtt通信记录 附mqtt介绍
目录 安装mqttx(云端部署) 安装mosquitto(本地部署) 编程,连接wifi 编程,连接mqtt,实现数据接收 实际效果展示: 附录:mqtt介绍 工作流程简述: 工作流…...

string类(详解)
【本节目标】 1. 为什么要学习string类 2. 标准库中的string类 3. string类的模拟实现 4. 扩展阅读 1. 为什么学习string类? 1.1 C语言中的字符串 C 语言中,字符串是以 \0 结尾的一些字符的集合,为了操作方便, C 标准库中提供…...

MATLAB | R2025a 更新了哪些有趣的东西?
千呼万唤始出来,MATLAB R2025A 来见面,这次更新比往常晚了两个月,让我们看看更了哪些好玩的新东西叭:首先下载更新启动一气呵成,映入眼帘的是: 1 基本界面 基本界面变得和 MATLAB 网页版一模一样了&#…...