XiaoboTalk

模块与包

包管理几乎是现代语言的标配,Rust 自带包管理工具;简单说,包管理工具就是组织、整理代码的一种工具;Rust 中有关包管理有 4 个概念:
  • Package:包,它是 Cargo 的一个特效,是 Cargo 用来构建、测试或者共享代码时的集合。
  • Crates: 是一系列 Module 的集合,用来生成库文件,或者可执行文件;类似 Java 中的 Jar 包。
  • Modules / use: 模块和路径,这两个和文件系统很类型,可以类比。Module 模块就是切分代码模块,相等于整理一个文件夹。use 用来通过路径访问响应的模块代码,和文件系统的路径很像,也有绝对路径相对路径的概念。
  • Paths: 模块项命名方式
 

Packages 和 Crates

先说 crate ,这是编译器识别代码的最小单元,当执行 cargo build 或者 rustc 的相关命令时,编译器会把当前所有可访问到的文件代码,打包为一个 crate。
crate 分为 library cratebinary cratebinary crate 就是可执行文件格式,有 main 函数。library crate 就是库文件,用来生产静态库或者动态库,所有没有 main 。通常包含一个 lib.rs 文件。
还有一个 crate root 概念,这表示编译器开始查找代码文件的根路径。
 
Package 包,会将一个或多个 crate 打包在一起,通常就是一个项目工程对应一个 Package,Package 包含一个标志性文件 Cargo.toml,这个 toml 文件描述了依赖哪些 crate,以及如何编排它们。
 

Module

模块的概念,很多语言都有,主要用来
  • 封装某些代码
  • 隔离作用域
  • 设置隐私性,可访问性
Module 经常和另外两个关键字一起使用:usepub 。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 关键字,表示../ 父路径,路径和模块这部分,在实际项目中能更快的掌握和理解,这里只是一些概念的梳理。
(全文完)