包和模块
包和模块
为什么需要包,封装多个文件/模块
当工程规模变大时,把代码写到一个甚至几个文件中,都是不太聪明的做法,可能存在以下问题:
- 单个文件过大,导致打开、翻页速度大幅变慢
 - 查询和定位效率大幅降低,类比下,你会把所有知识内容放在一个几十万字的文档中吗?
 - 只有一个代码层次:函数,难以维护和协作,想象一下你的操作系统只有一个根目录,剩下的都是单层子目录会如何:
disaster - 容易滋生 Bug
 
同时,将大的代码文件拆分成包和模块,还允许我们实现代码抽象和复用:将你的代码封装好后提供给用户,那么用户只需要调用公共接口即可,无需知道内部该如何实现。
概念和项目单位
因此,跟其它语言一样,Rust 也提供了相应概念用于代码的组织管理:(概念尽量从大到小排序,组织上更类似于node.js的方式)
- 工作空间(WorkSpace) 
- 组成: 对于大型项目,可以进一步将多个包联合在一起,组织成工作空间
 - 特点:可以有多个 package 和 crate
 - 类比:类似于 js 中一个复杂的 monorepo 的样子,有多个 package.json
 
 - 项目(Packages) 
- 组成: 可以包含一个库(library)类型的包和包含多个二进制可执行类型的包
 - 特点: 一个包 (
Cargo) 提供的feature。可以用来构建、测试和分享包 - 类比 
- 类似于 js 的 package.json 对应一个项目,可以有 build/test/publish 等编译入口。
 
 
 - 包/货箱(Crate) 
- 组成: 一个由多个模块组成的树形结构。一个Crate对应一个 Cargo.toml 文件
 - 特点: 独立的可编译单元,它编译后会生成一个可执行文件用来运行,或者生成一个库 (可能用于第三方库的分发等)。
 - 类比: 
- 类似于 js 的 package.json 中能编译项目的 script 项 (编译入口),又可以分可执行还是库类型
 
 
 - 文件(File) 
- 略,就是文件
 
 - 模块(Module) 
- 组成: 一个文件一个/多个模块 (一个文件至少包含一个名为 
<fileName>的模块) - 特点: 模块可以被认为是真实项目中的代码组织单元
 - 类比 
- 声明,类似cpp的using,命名空间
 - 导出,不一定要额外声明 (文件本身相当于一个mod),类似于 js 的 
export xxx - 导入,
mod modeName,类似于 js 的import xxx - 入口文件 
- 有文件夹:
<folderName>/mod.rs或<folderName>.rs,且在里面pub mod xx暴露出模块 - 无文件夹:
<fileName>.rs - 类似于python的 
__init__.py 
 - 有文件夹:
 
 
 - 组成: 一个文件一个/多个模块 (一个文件至少包含一个名为 
 
Note
与其他语言不同:
注意,项目叫package应该是受js之类的影响。不然一般应该是叫project,然后包有可能叫package
为什么名字怪怪的:(无论英文还是中文)
鉴于 Rust 团队标新立异的起名传统,以及包的名称被 crate 占用,库的名称被 library 占用,经过斟酌, 我们决定将 Package 翻译成项目,你也可以理解为工程、软件包。
结合项目目录demo
Cargo.toml  | |
Cargo.lock  | |
src  | |
main.rs  | 默认二进制包,生成的可执行文件与   | 
lib.rs  | 唯一库包  | 
bin  | |
main1.rs  | 其余二进制包,生成的可执行文件与文件名同名  | 
main2.rs  | 其余二进制包,生成的可执行文件与文件名同名  | 
tests  | 集成测试文件  | 
some_integration_tests.rs  | |
benches  | 基准性能测试  | 
simple_bench.rs  | |
examples  | 项目示例  | 
simple_example.rs  | 
其他
目前看到这里应该会是挺懵逼的,需要后面详细举例和分别描述,才能有所体会。
下面,让我们一一来学习这些概念以及如何在实践中运用。
链接到当前文件 0
没有文件链接到当前文件