Rust系列:初步⚙所有权⚙结构体和枚举类⚙函数进阶⚙泛型和特征⚙并发和线程通信
cargo是Rust的包管理工具,兼具一些调试功能,在认识cargo之前,我们都是直接新建一个.rs
文件,并用rustc命令来编译,有了cargo,则会自动创建项目文件夹,示例如下
cargo new --bin hello
new用于创建一个新项目,bin表示这个项目将被编译为二进制文件,hello是项目名称。相应地,当前路径下出现了一个hello文件夹,内部结构如下
hello
├─src
│ └─main.rs
├─Cargo.toml
└─.gitignore
其中Cargo.toml是配置文件,内容如下。
[package]
name = "hello"
version = "0.1.0"
edition = "2021"
[dependencies]
前面几行意义不大,主要是申明项目名、版本号等标识,但[dependencies]很重要,尽管目前还未引入任何依赖。
src中的main.rs则为源代码,默认的内容非常简单
fn main() {
println!("Hello, world!");
}
接下来进入hello文件夹,然后运行cargo run,即可运行项目
>cd hello
>cargo run
Hello, world!
如果在src文件夹中新建一个文件add.rs
,内容如下
pub fn add(a:i32, b:i32) -> i32{
a+b
}
其中,pub即public,表示这个函数可被其他文件调用。
然后修改main.rs文件,内容如下
mod add;
pub use crate::add::add;
fn main() {
println!("{}+{}={}", 3, 4, add(3,4));
}
第一行表示使用名为add的模块;第二行表示使用add模块中的add函数,运行结果为
>cargo run
3+4=7
如果项目规模进一步扩大,那么众多模块也需要组织,即需要被存放在文件夹里。而这里又有一个问题,即main.rs只能调用其他文件夹中名为mod.rs的文件。例如,将上述src文件夹重新规划为如下样式,则会报错。
src
├─add
│ └─add.rs // 需要把这个文件改名为mod.rs
└─main.rs
而只要把add.rs改写为mod.rs,那就再度正常运行了。
当工程规模变得越来越大,模块化编程是唯一的出路,这几乎是所有编程语言的共识,Rust亦然。
在Rust中,项目组织分为三个层级
而这些层级关系,可通过cargo工具来进行管理,下面就创建一个模块
cargo new --lib add
此即创建了一个add模块,当前路径下也多了一个add文件夹,内有一个src子文件夹,包含一个lib.rs文件,默认内容如下
pub fn add(left: usize, right: usize) -> usize {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}
上面的代码中,关键字pub所修饰的对象可以被模块外部所调用。这个add函数,是属于这个库的唯一内容。
#[cfg(test)]
下面的代码是用于测试的,其mod与main.rs中使用的mod作用相似。
super标识当前文件的上一级目录,也可以理解为父模块,use super::*
表示导入父模块的所有函数。
通过cargo test
可以对上述代码进行测试。
接下来,准备在hello项目中引用add库中的内容,为了实现这个目的,首先需要修改配置文件Cargo.toml,在其依赖项下方加入库的路径
[dependencies]
add = { path = "../add" }
然后修改main.rs文件如下,就又可以得到3+4=7了。
extern crate add;
fn main() {
println!("{}+{}={}", 3, 4, add::add(3,4));
}