包,creat与模块-Rust

简单认识三个概念

在 Windows 中,可以将 package 视为包含相关代码和配置的文件夹,crate 通常对应着主要的 rs 文件(对于库 crate 可能是 lib.rs ,对于可执行 crate 可能是 main.rs ),而模块就是通过 mod 关键字在 rs 文件中定义的有特定功能和作用域的代码块。

package

包含一个 Cargo.toml 文件,阐述如何去构建这些 crate。

可以包含多个二进制create和一个库create

image-20241214162455482

image-20241214162312520

crate(截图crate写错了)

分为两种类型

二进制项目

sec/main.rs

image-20241214163003975

库 并没有 main 函数,它们也不会编译为可执行程序,它们提供一些诸如函数之类的东西,使其他项目也能使用这些东西。

src/lib.rs

image-20241214163621727

mod

image-20241214163447964

路径

通过路径来找到自己想使用的模块或者函数

与文件系统类似,存在绝对路径与相对路径,推荐使用绝对路径编写代码,这样不担心模块移动以后触发bug

绝对路径:从crate开始编写,使用crate名字或直接写

相对路径:使用self或者super或者当前包名

标识符之间使用::分割

1
2
3
4
5
6
7
8
9
10
11
12
13
mod front_of_house{

mod hosting{
fn add_to_waitlist(){}
}

}

pub fn eat_at_restaurant(){
crate::front_of_house::hosting::add_to_waitlist();//绝对路径

front_of_house::hosting::add_to_waitlist();//相对路径
}

私有边界

image-20241214165123556

原因是因为Rust默认函数方法模块等是私有的,不允许其他语句使用,需要显示的使用pub定义

比如pub fn eat_at_restaurant()

1
2
3
4
5
6
7
8
9
10
11
12
13
mod front_of_house{

pub mod hosting{
pub fn add_to_waitlist(){}
}

}

pub fn eat_at_restaurant(){//由于和front_of_house处于同级,相互调用不需要关注私有公有都可以使用
crate::front_of_house::hosting::add_to_waitlist();//绝对路径

front_of_house::hosting::add_to_waitlist();//相对路径
}

以上代码就不会报错,运行cargo run的时候注意main.rs代码不要有错误

super

image-20241214170055292

结构体私有问题

结构体pub不代表自己的成员都是公开的,每个成员也都需要手动添加pub,不过枚举主体添加pub以后成员不需要再加pub了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
mod back_of_homee{

pub struct Breakfast{
pub toast:String,
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_rest(){

let mut meal = crate::back_of_homee::Breakfast::summer("111");
meal.toast=String::from("wheat");
println!("i like {}",meal.toast);
meal.s//无法访问

}

image-20241214171151416

use关键字

使用函数

可以将路径引入到相关作用域

image-20241214171817289

1
2
3
4
5
6
7
8
9
10
11
12
use front_of_house::hosting;//使用use关键字引入hosting即可,无法直接访问兄弟模块的子模块

mod front_of_house{
pub mod hosting{
pub fn add_to_waitlist(){}
}

}

pub fn test(){
hosting::add_to_waitlist();//如果函数私有也是不可以使用的
}

上面的例子我们针对函数引用到了hosting模块,这是为了防止hosting模块有多个我们需要使用的函数,也可以直接引用到函数本身,但是不推荐

使用结构体

针对结构体的引用就需要我们直接引用到结构体自身

image-20241214172446932

1
2
3
4
5
6
7
8
use std::collections::HashMap;//我们使用的时候直接引用到了结构体本身 

fn main() {

let mut map =HashMap::new();//使用hashmap的时候就不需要加模块名了
map.insert(1, 2);

}

同名引用

1
2
3
4
5
6
7
8
9
10
use std::fmt;
use std::io;

fn f1 -> fmt::Result{}//使用的时候加上不同名的父级目录即可
fn f2 -> io::Result{}


fn main() {

}

as关键字

1
2
3
4
5
6
7
8
9
10
11
use std::fmt::Result;
use std::io::Result as IoResult;//别名

fn f1 -> Result{}
fn f2 -> ioResult{}


fn main() {

}

使用外部package

需要在cargo.tom添加依赖包

image-20241214174908184

修改下载源

进入用户目录下的.cargo目录

创建config文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 放到 `$HOME/.cargo/config` 文件中
[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"
# 指定镜像
replace-with = 'sjtu' # 如:tuna、sjtu、ustc,或者 rustcc

# 注:以下源配置一个即可,无需全部
# 目前 sjtu 相对稳定些

# 中国科学技术大学
[source.ustc]
registry = "https://mirrors.ustc.edu.cn/crates.io-index"

# 上海交通大学
[source.sjtu]
registry = "https://mirrors.sjtug.sjtu.edu.cn/git/crates.io-index/"

# 清华大学
[source.tuna]
registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"

# rustcc社区
[source.rustcc]
registry = "https://code.aliyun.com/rustcc/crates.io-index.git"

嵌套路径

1
2
3
4
5
6
7
8
9
10
11
use std::alloc;
use std::any;
use std::assert;

//use std::{alloc,any,assert};


fn main() {
test();

}

模块与文件

image-20241214180548830

src\front_of_hous.rs

1
2
3
4
pub mod hosting{
pub fn add_to_waitlist(){}
}

如果想要把hosting模块也独立出去需要创建front_of_hous的同名目录把hosting.rs放到这个目录下