包管理几乎是现代语言的标配,Rust 自带包管理工具;简单说,包管理工具就是组织、整理代码的一种工具;Rust 中有关包管理有 4 个概念:
- Package:包,它是 Cargo 的一个特效,是 Cargo 用来构建、测试或者共享代码时的集合。
- Crates: 是一系列 Module 的集合,用来生成库文件,或者可执行文件;类似 Java 中的 Jar 包。
- Modules / use: 模块和路径,这两个和文件系统很类型,可以类比。
Module
模块就是切分代码模块,相等于整理一个文件夹。use
用来通过路径访问响应的模块代码,和文件系统的路径很像,也有绝对路径和相对路径的概念。
- Paths: 模块项命名方式
Packages 和 Crates
先说
crate
,这是编译器识别代码的最小单元,当执行 cargo build
或者 rustc
的相关命令时,编译器会把当前所有可访问到的文件代码,打包为一个 crate。crate 分为
library crate
和 binary crate
。binary crate
就是可执行文件格式,有 main
函数。library crate
就是库文件,用来生产静态库或者动态库,所有没有 main
。通常包含一个 lib.rs
文件。还有一个
crate root
概念,这表示编译器开始查找代码文件的根路径。Package 包,会将一个或多个 crate 打包在一起,通常就是一个项目工程对应一个 Package,Package 包含一个标志性文件 Cargo.toml,这个
toml
文件描述了依赖哪些 crate,以及如何编排它们。Module
模块的概念,很多语言都有,主要用来
- 封装某些代码
- 隔离作用域
- 设置隐私性,可访问性
Module 经常和另外两个关键字一起使用:
use
和 pub
。Module 的工作方式:- 从 Crate Root 开始: 当编译一个 crate 的时候,首先从 crate root 开始;通过
src/lib.rs
所在路径作为 library crate 的 root 路径;src/main.rs
所在路径作为 binary crate 的 root 路径。
- 声明一个 Module: 默认,什么也不写的时候,一个 .rs 文件,就是一个 Module。也可以显式的声明一个 Module:
mod garden {}
表示一个 garden 模块。这时候编译器会在以下地方查找 garden 模块相关的代码: - 行内 (Inline): 即在模块的
{}
内 - 在 src/garden.rs 文件内,因为默认一个文件就是一个 Module,文件名就是模块名。
- 在 src/garden/mod.rs,也可以在子路径 src/garden 下查找,另外还可以再子路径下定义 garden 的子模块。
- 模块路径:
crate::garden::*
,通过类型这样的路径方式寻找和引入模块代码,::
类似系统的./
或者/
路径。
- Private 和 Public: 模块内的代码默认都是私有的,即使模块本身是公开的。
pub mod
将某个模块公开,公开模块仅仅表示,可以通过::
路径符号访问到这个模块,模块内定义的其他 enum 或者 struct 依然默认是私有的。可以继续使用pub
关键字公开模块内的表达式。
- use:
use
关键字可以用来给某个路径指定快捷指令,相当于文件系统的软链接。
例如当前工程的路径结构:
backyard ├── Cargo.lock ├── Cargo.toml └── src ├── garden │ └── vegetables.rs ├── garden.rs └── main.rs
scr/main.rs
所在路径就是 crate root 路径,从这个根路径出发,可以访问其他模块:use crate::garden::vegetables::Asparagus; // 软链接到了 Asparagus,当前文件可以使用 Asparagus 表示 crate::garden::vegetables::Asparagus; // 这好比用一个相对路径表示一个绝对路径 fn main() { let plant = Asparagus {}; println!("I'm growing {:?}!", plant); }
另外,还有 super 关键字,表示
../
父路径,路径和模块这部分,在实际项目中能更快的掌握和理解,这里只是一些概念的梳理。(全文完)