Rust系统编程之项目管理
1.Crate
一个由多个模块组成的树形结构,可以作为三方库进行分发,也可以生成可执行文件进行运行。将多个功能打包到一起形成一个代码集合箱,一个crate
是一个编译单元。
1.1 binary crate
一个二进制crate,它的充分必要条件是会有./src/main.rs
这个文件,是整个用于执行crate的入口文件。
cargo新建binary crate命令:
1 |
|
1.2 library crate
一个library crate,它的充分必要条件是有./src/lib.rs
这个文件。
2.Package
Package就是一个工程,包含了1个或者n个crate
以及测试、文档等,一个Package包含一个Cargo.toml
配置文件。
规则:
- 一个package最多包含一个library crate
- 一个package可以包含任意多的binary crate
- 一个package至少要包含一个crate(无论是binary或是library)
典型的package解构:
1 |
|
3.Module
Module让我们可以将一个 crate 中的代码进行分组,以提高可读性与重用性。
Module相当于在一个crate
中的更小的功能单元,一个crate
可能使用了n个module
,使用mod xxx
的方式来引用一个module
。
3.1 代码搜索规则
在rust编译crate
时会从以下路径中寻找module
的代码:
- 内联,在大括号中,当
mod garden
后方不是一个分号而是一个大括号 - 在文件
src/garden.rs
- 在文件
src/garden/mod.rs
并且可以在module
中引用其他的module
,搜索方式如上。
一旦一个模块是crate
的一部分,你可以在隐私规则允许的前提下,从同一个crate
内的任意地方,通过代码路径引用该模块的代码。
举例而言,一个garden vegetables模块下的Asparagus
类型可以在crate::garden::vegetables::Asparagus
被找到。
3.2 隐私规则
一个模块里的代码默认对其父模块私有,但是子模块可以访问到父模块。为了使一个模块公用,应当在声明时使用pub mod
替代mod
。为了使一个公用模块内部的成员公用,应当在成员声明前使用pub
。
3.3 模块树
示例代码如下:
1 |
|
此时从crate
为根节点会生成如下的模块树结构:
1 |
|
add_to_waitlist
与seat_at_table
互为兄弟模块,front_of_house
和hosting
构成父子模块。
3.4 引用路径搜索规则
在模块树中找到一个module
的位置,我们使用指定路径的方式,就像在文件系统种使用路径一样。为了调用一个函数,我们需要知道它的代码路径。
路径分两种:
- 绝对路径(absolute path)是以 crate 根(root)开头的全路径;对于外部 crate 的代码,是以 crate 名开头的绝对路径,对于对于当前 crate 的代码,则以字面值
crate
开头。 - 相对路径(relative path)从当前模块开始,以
self
、super
或当前模块的标识符开头,super
关键字用于访问父模块中的项。
绝对路径和相对路径都后跟一个或多个由双冒号(::
)分割路径中的module
。
3.5 use关键字
use
关键字简化了路径搜索,可以在一个module
种使用use来声明一个作用时间更久的软链接的方式将其他module
的代码引入当前作用域。
1 |
|
嵌套引用:
1 |
|
引用所有公有项:
1 |
|
3.6 as关键字
为类型起别名
1 |
|
3.7 pub use重导出
在一个作用域内使用use
将其他module
的项导入进来后,这个项在这个作用域外面还是私有的。如果想外面的代码访问这个项跟访问引入那个项的作用域的权限一致的话,可以使用pub use
关键字将那个项进行重导出。
1 |
|
在这个修改之前,外部代码需要使用路径 restaurant::front_of_house::hosting::add_to_waitlist()
来调用 add_to_waitlist
函数。现在这个 pub use
从根模块重导出了 hosting
模块,外部代码现在可以使用路径 restaurant::hosting::add_to_waitlist
来调用。