Managing Growing Projects with Packages, Crates, and Modules
Managing Growing Projects with Packages, Crates, and Modules
Packages and Crates
Package
Package(包) : Cargo 的特性,让你构建、测试、共享 crate
Crate(单元包) : 模块树,它可产生一个 library 或可执行文件
Module(模块), use : 让你控制代码的组织、作用域、私有路径
Path(路径) : 为 struct、function 或 module 等项命名的方式
Cargo 的惯例
1 | src/main.rs: |
1 | 一个 package 可以同时包含 src/main.rs 和 src/lib.rs |
Defining Modules to Control Scope and Privacy
module
1 | Module: |
1 | 建立 module: |
例如
1 | mod front_of_house { |
pub
关键字
1 | pub struct: |
例如
1 | mod front_of_house { |
Paths for Referring to an Item in the Module Tree
Path
绝对路径:从 crate root 开始,使用 crate 名 或 字面值 crate
相对路径:从 当前模块开始,使用 self,super 或当前模块的标识符
1 | mod front_of_house { |
Cargo run 会发现错误
1 | /* |
这就是因为默认私有,使用 pub
关键字将条目标记为公共的
1 | mod front_of_house { |
父级模块无法访问子模块中的私有条目
子模块可以访问所有祖先模块中的条目
super
关键字,表示上一级
1 | mod front_of_house { |
Bringing Paths into Scope with the use
Keyword
遵守私有性原则
一般将函数的的父级引入模块
struct,enum,其他:指定完整路径(指定到本身)
1 | mod front_of_house { |
同名条目:指定到父级
1 | use std::fmt; |
as
关键字
1 | use std::fmt::Result as FmtResult; |
这时候就可以直接用 as 后的东西代替前面的东西
use
引入默认私有,外部代码看不到
1 | fn eat_at_restaurant() { |
1 | fn eat_at_restaurant() { |
使用外部包 package
Cargo.toml 下添加 package
package 下载 https://crates.io/
1 | // Cargo.toml 下 |
需要 cargo build, 下载慢可以换国内镜像源
使用 use 将特定条目引入作用域
1 | use rand::Rng; |
std 默认内置(即不需要在 dependencies 放 package),但需要用 use 来引入作用域
例如引入 HashMap
1 | use std::collections::HashMap; |
使用嵌套路径清理大量 use 语句
1 | use std::collections::HashMap; |
我们发现前面都是一样的
使用语法 相同部分::{不同部分,...}
1 | use std::collections::{HashMap, HashSet, BTreeMap}; |
当我们需要本身和它下面的条目时,使用 self
例如:引入 std::collections 和 std::collections::HashMap
1 | use std::collections::{self, HashMap};// self |
当我们需要一个模块下所有条目时,我们可以使用通配符 *
来引入
1 | use std::collections::*; |
一般测试时才会用
Separating Modules into Different Files
将模块内容移动到其他文件
模块定义时,如果模块名后面是;
,而不是代码块{code}
,rust 会从与模块同名的文件中加载内容,模块树结构不会变化
1 | // lib.rs 内 |
如果是嵌套模块,需要放到对应文件夹下