likes
comments
collection
share

Rust(23):模块系统:Package、Crate、Module

作者站长头像
站长
· 阅读数 25

今天学习的内容是 Rust 中的模块化系统有关的内容。

对于模块化编程大家都不会陌生,就是将一个完整的系统拆分成一个个独立的功能模块,实现高内聚,低耦合的开发思想,方便维护和提高复用性。

Rust 项目的代码组织包含以下三个基本概念,它们构成了 Rust 的模块系统(module system)

  • Package:,一个用于构建、测试并分享单元包的 Cargo 功能。
  • Crate:箱/单元包,一个用于生成库或可执行文件的树形模块结构。
  • Module:模块,配合 use 关键字和 path 路径,用于控制文件结构、作用域及路径的私有性。

Package:包

使用 Rust 的包管理工具 cargo 创建一个项目,此项目就是一个 Package。

如下:

cargo new my-project

Rust(23):模块系统:Package、Crate、Module

Rust(23):模块系统:Package、Crate、Module

执行该命令,Cargo 会创建一个包和相应的 cargo.toml 文件。

一个 Package 必须包含一个 cargo.toml 项目配置文件。

一个 Package 中必须包含一个或多个 Crate。因为 Crate 是编译的最小单元,如果没有可用于编译的文件,那么一个 Package 就没有存在的必要了。

默认,src/main.rs 是和 Package 同名的二进制 Crate 的入口文件。因此在创建了 my-project 之后,就有了一个名为 my-projectPackage 和一个名为 my-project 的二进制 Crate

使用 new 命令创建 Package 时带上 --lib 选项,会生成一个 src/lib.rs 文件,此文件也是一个 Crate,称为库单元包

如果 src 目录中同时包含 main.rslib.rs,那么这个 Package 会同时得到一个二进制 Crate 和 一个库 Crate,这在开发一些基础库时非常有用。例如使用 Rust 实现了一个 MD5 函数,我们既希望这个 MD5 函数能作为库被别人引用,又希望能获得一个可以进行 MD5 运算的命令行工具,就可以同时为 Package 添加一个 main.rs 和 一个 lib.rs

Crate:箱

Crate 是“箱子”的意思。在 《Rust 权威指南》中被翻译为“单元包”。因为CrateRust 的最小编译单元。

Crate 在一个范围内将相关的功能组合在一起,并最终通过编译生成一个二进制文件或库

Crate 并不等同于一个 .rs 文件。Crate 可以就是一个 .rs 文件, .rs 文件还可以通过 mod 关键字引入其他 .rs 文件中的模块,所以 Crate 更严格的定义是一个用于生成库或可执行文件的树形模块结构。

Module:模块

先来看下 JS 中的模块,然后和 Rust 做个对比。

对于 JSer 来说,经常使用前端框架比如 Vue 编写前端应用,通常采用 ES Module 模块化规范,一个文件就是一个模块。或者使用 Node 编写后端应用,采用 CommonJS 规范,一个文件就是一个模块

而 Rust 中,模块和单独的文件不存在必然关联。

在编写 Rust 程序时,可以不使用模块。但是当一个 crate 中的代码越来越多时就会变得不好维护,所以就可以将其拆分成一个个独立的模块,以便于增强于可读性和代码复用。

定义模块使用 mod 关键字。也就是说,一个文件中可以没有模块,也可以有多个模块。文件和模块不是一对一的关系。

Rust 中的模块是一种

同时,Module 还能控制代码的可见性,也就是将代码分为公开代码和私有代码,公开代码可以在项目外被使用,私有代码只能在项目内被访问。

小结

本文介绍了 Rust 中的模块化编程中一些基本概念,包括 Package,Crate 和 Module。