Rust Package Crate Moudle
模块系统
- Package 包:构建,测试,共享crate。
- Crate 单元包:一个模块树,可以产生一个library或可执行文件。
- Module 模块,use:代码组织,作用域,私有路径。
- path:为struct, function, module 等项目命名的方式。
- Module 模块,use:代码组织,作用域,私有路径。
- Crate 单元包:一个模块树,可以产生一个library或可执行文件。
Package
包含:
- 1个Cargo.toml
- 0 - 1个library crate
- 任意数量的 binary crate
- 至少包含一个crate (library/binary)
Crate
crate的类型:binary/library
crate root
源代码文件,rust编译器从这里开始,组成crate的根module。
- src/main.rs 是 binary crate 的 crate root。crate的名和package名相同。
- src/lib.rs 是 library crate 的 crate root。crate的名和package名相同。
文件放在src/bin里面,代表每个文件都是单独的 binary crate。
crate 将相关的功能组合到一个作用域内,防止冲突。
eg: rand crate,访问时需要通过它的名字: rand
Moudle
在1个crate内,将代码进行分组。并能控制私有性。
建立module:
- mod 关键字
- 可嵌套
mod CAR {
mod honda {
fn MPV(){}
}
mod toyota {
}
}
Path
类似python包管理。
绝对路径:从create开始,使用crate名或字面值crate。
相对路径:从当前模块开始,使用self, super或当前模块的标识符。
路径至少由一个标识符组成,标识符之间使用::
mod CAR {
mod honda {
fn MPV(){}
}
mod toyota {
}
}
fn driver(){
// 从根目录crate root开始查起
crate::CAR::honda::MPV()
// 同一级模块
CAR::honda::MPV()
}
如果调用代码和模块代码总是一起的使用,就使用相对路径。反之则用绝对路径。
私有边界
模块默认是私有的,如果把函数或者结构体放进去,那么它就是私有的。rust中所有的条目(函数,方法,struct,enum,模块,常量)默认是私有的。
改成公共方法,关键字 pub
pub fn driver(){}
父级模块无法访问子模块中的私有条目。子模块可以使用所有祖先模块中的所有条目。
如果两个模块都是同级,那么就可以互相调用,不用公共。
mod CAR {
pub mod honda {
pub fn MPV(){}
}
mod toyota {
}
}
pub fn driver(){
// 这里可以直接调用CAR,因为是同级
crate::CAR::honda::MPV();
CAR::honda::MPV();
}
super
访问父级模块路径中的内容,类似文件系统中的..
super也是相对路径,访问上级目录。
super::someFunc()
pub struct
pub放在struct之前可以将结构体声明公有,但是里面的字段默认是私有的,也是加pub声明公有。
pub enum
pub放在enum之前可以将枚举声明公有,里面的变体默认是公有的。(enum就是为了让别人用的)
use
类似python的import,或者创建符号链接。
绝对路径:use crate::CAR::honda::MPV;
相对路径:use CAR::honda::MPV
use引用也需要遵守私有性规则。
- 针对函数,一般只引入到父模块。
- 针对struct, enum, 其他一般指定到完整路径,本身,如果引入两个,名字是一样的就父级。
use std::collections::HashMap;
as
别名,和python一样
use std::io::Result as ioResult;
pub use
重导出,类似js的暴露。
使用use将路径(名称)导入到作用域内后,该名称在此作用域内是私有的。
pub use crate::CAR::honda::MPV;
引入了MPV,然后又导出了。
package 外部包
- cargo.toml添加依赖包。
- use 引入作用域。
标准库(std)也会被当作外部包。
嵌套路径
同一个包或模块引入多个条目。
路径相同的部分::{差异部分}
use std::{io, cmp::Ordering}
如果差异只是被包含的一个关系,就可以用self。一个引用是另外一个引用的子路径。
use std::io;
use std::io::Write;
// self是导入自己
use std::io::{self, Write};
* 通配符
use std::io::*
做测试的时候,所以被测试的模块引入到tests模块中。有时被用于预导入(prelude)模块。
拆分文件
模块定义时,如果模块名后面是;,而不是代码块,rust会从模块同名的文件中加载内容。
mod CAR;
rust就会在src目录下找CAR.rs。
多级目录下父级模块要变成文件夹。