文章目录
- 一、module模块
- 1.二进制文件的cargo项目
- 2.库的cargo项目
- 模块中使用crate关键字
- 模块中使用super
- 模块中结构体的访问规则
- 模块中枚举的访问规则
- 模块中use关键字
- 不同模块定义了相同类型冲突解决办法
- 使用pub use导出本模块的函数给外面模块
- 引入外部依赖
- 模块与子模块
- 小结
- 3.文件内的module
- 二、模块化项目结构
- 1.关于module
- 2.各个模块之间互相引用
- 三、推荐项目结构
- 1.实例
- 参考
一、module模块
crate规则:
- 规则一:一个包中必须至少包含一个crate
- 规则二:一个包中可以不包含库crate或者包含1个库crate
规则三:一个包中可以包含任意数量的二进制crate
1.二进制文件的cargo项目
bin下面一个rs文件就是一个crate
2.库的cargo项目
模块中使用crate关键字
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub fn eat_at_restaurant() {
// 绝对路径
// 使用crate的原因是:
// crate 的被称为 模块树 的模块结构的根部:https://rustwiki.org/zh-CN/book/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html
crate::front_of_house::hosting::add_to_waitlist();
// 相对路径
front_of_house::hosting::add_to_waitlist();
}
模块中使用super
fn serve_order() {}
mod back_of_house {
fn fix_incorrect_order() {
cook_order();
// 访问父模块的函数
super::serve_order();
}
fn cook_order() {}
}
模块中结构体的访问规则
mod back_of_house {
pub struct Breakfast {
//结构体成员默认是私有的
pub toast: String,
pub seasonal_fruit: String,
}
impl Breakfast {
pub fn summer(toast: &str) -> Breakfast {
Breakfast {
toast: String::from(toast),
seasonal_fruit: String::from("peaches"),
}
}
}
}
pub fn eat_at_restaurant() {
// 在夏天点一份黑麦面包作为早餐
let mut meal = back_of_house::Breakfast::summer("Rye");
// 更改我们想要的面包
meal.toast = String::from("Wheat");
println!("I'd like {} toast please", meal.toast);
meal.seasonal_fruit = String::from("blueberries");
let meal2 = back_of_house::Breakfast {
toast: String::from("Wheat"),
seasonal_fruit: String::from("strawberries"),
};
}
模块中枚举的访问规则
mod back_of_house {
// 枚举前面加上pub即可
pub enum Appetizer {
Soup,
Salad,
}
}
pub fn eat_at_restaurant() {
let order1 = back_of_house::Appetizer::Soup;
let order2 = back_of_house::Appetizer::Salad;
}
模块中use关键字
use关键字将路径引入到作用域中
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
//在一个模块里面,也可以直接使用self,use self::front_of_house::hosting;
// 函数:use引用其父亲模块,对于struct和enum则建议全部引入进来
use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
}
fn main() {}
不同模块定义了相同类型冲突解决办法
// 引入父模块
use std::fmt;
use std::io;
fn function1() -> fmt::Result {
// --snip--
}
fn function2() -> io::Result<()> {
// --snip--
}
// 通过重命名解决
#![allow(unused)]
fn main() {
use std::fmt::Result;
use std::io::Result as IoResult;
fn function1() -> Result {
// --snip--
Ok(())
}
fn function2() -> IoResult<()> {
// --snip--
Ok(())
}
}
使用pub use导出本模块的函数给外面模块
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
}
fn main() {}
引入外部依赖
使用外部依赖
use rand::Rng;
fn main() {
let secret_number = rand::thread_rng().gen_range(1..101);
}
模块与子模块
将front_of_house.rs中的子模块hosting定义在另外一个文件中,先创建front_of_house子目录,然后创建hosting.rs文件
模块是可以定义在同级的另外一个文件中的,如上所示,librs的mod front_of_house;
子模块是定义在以父模块为名的目录中的,如上所示,可以在front_of_house.rs模块中使用其子模块hosting.rs。
小结
1。Rust的模块系统概念包括:包package,包装箱crate,模块module和路径path。模块系统的目标是有效组织目录。
2。crate是Rust中的一个编译单元,它可以是一个二机制crate,也可以是一个库crate
3。cargo new缺省创建的是二进制项目,可以通过–bin指定创建二进制项目,或者–Lib~指定创建库项目
4。一个包package可以由一个或者多个crate组成。它包含一个Cargo。toml文件,其中可以定义它所包含的crates
5。一个包最多只能有一个库crate,可以有任意多个二进制crate。但是一个包中必须至少有一个crate。
6。模块类似名字空间,可以逻辑拆分和组织代码。模块用关键字mod定义,模块可以是public也可以是private的。
7。缺省情况下,模块是private私有的,可以添加pub关键字,将一个模块设置为public的。模块中可以嵌套子模块。
8。路径path用于访问一个模块中定义的项。路径可以是相对的,也可以是绝对的。
3.文件内的module
关键字:mod
引入模块中的方法
- usemod名字:方法名
- usemod名字.*
- 写全路径
二、模块化项目结构
·好处
- 使源代码管理更加方便
- 更方便读
1.关于module
默认是private
组成一个module
- File
- Directory,需要mod.rs
2.各个模块之间互相引用
crate根目录引入
super相对路径引入
三、推荐项目结构
bin目录
- 把main.rs放入
somelib
- 需要修改Cargo.toml
[somelib]
name =“somelib"
path=“src/somelib/mod.rs”I //文件夹
path=“src/somelib/some.rs” //单个文件
1.实例
创建一个项目
创建一个库mlib
- 创建单文件translate模块
- 创建music目录模块
mp3
flac
在flac调用translate模块中的方法
将flac中的music方法暴露出去
main.rs
fn main() {
println!("Hello, world!");
mlib::translate::func1();
mlib::music::flac::flac();
mlib::music::flac::flac_music();
mlib::test();
mlib::flac_music();
}
src/mlib/music/flac.rs
pub fn flac() {
//方法1 调用外层translate.rs里面的方法
super::super::translate::func1();
println!("flac");
}
pub fn flac_music() {
// 方法2
crate::translate::func1();
println!("flac_music");
}
src/mlib/music/mod.rs
// 声明出去
pub mod flac;
pub mod mp3;
src/mlib/music/mp3.rs
pub fn mp3() {
println!("mp3");
}
src/mlib/mod.rs
// 暴露模块
pub mod music;
pub mod translate;
pub fn test() {
println!("test....");
}
// 暴露模块中的某个函数
pub use music::flac::flac_music;
src/mlib/translate.rs
pub fn func1() {
println!("Hello, func1!");
}
Cargo.toml
[package]
name = "demo"
version = "0.1.0"
edition = "2021"
[lib]
name="mlib"
path="src/mlib/mod.rs"
[dependencies]
参考
- Rust项目结构