使用cargo new创建项目时,有项目类型的选项:
- —bin:编译为可执行文件
- —lib:编译为库文件
默认的,是—lib。事实上,Rust能创建的库的种类有下面几种:
- rlib:Rust库,这是cargo new默认的种类,只能被Rust调用;
- dylib:Rust规范的动态链接库,windows上编译成.dll,linux上编译成.so,也只能被Rust调用;
- cdylib:满足C语言规范的动态链接库,windows上编译成.dll,linux上编译成.so,可以被其他语言调用
- staticlib:静态库,windows上编译成.lib,linux上编译成.a,可以被其他语言调用
只是被Rust调用的话,默认的rlib是最好的选择,如果想用其他的种类,无法直接使用cargo指定,只能手动修改Cargo.toml。
[lib]
crate-type = ["rlib", "dylib", "cdylib", "staticlib"]
cargo允许同时设置多种类型,同一套代码,同时编译为多种类型。
创建numrust库
可以使用cargo创建项目:
cargo new numrust
也可以使用Clion为我们创建,两者创建的文件是相同的:
在库中创建mod
Rust使用mod关键字创建命名空间,自动生成的代码中,已经包含了一个mod tests:
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
mod默认为私有,也就是说,这个tests并不会被库导出,它是为我们测试而准备的。我们可以创建自己的mod:
pub mod numrust { // 创建公有的mod
pub fn hello() { // 创建公有的函数
println!("hello numrust")
}
}
要想在tests中调用,需要了解mod的路径规则。Rust使用“::”来分隔命名空间,使用crate、self、super三个关键字来表示路径的起点:
- crate:类似于根目录
- self:指当前mod,类似于“.”
- super:指当前mod的父mod,类似于“..”
numrust与tests是同级的,所以在tests中调用numrust有两种方式:
crate::numrust::hello();
super::numrust::hello();
除此之外,还可以使用use引用mod。在Python中,人们都习惯这样引入numpy:
import numpy as np
这在Rust中同样可以:
#[cfg(test)]
mod tests {
use super::numrust as nr;
#[test]
fn it_works() {
nr::hello();
assert_eq!(2 + 2, 4);
}
}
要调试我们的库,可以直接使用命令:
> cargo test
Finished test [unoptimized + debuginfo] target(s) in 0.01s
Running unittests (target\debug\deps\numrust-0bda5bdf4b187237.exe)
running 1 test
test tests::it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
也可以在Clion中运行:
在exe中调用库
下面再创建一个可执行的项目,来调用刚刚的库。
cargo new --bin numrustexe
可使用Clion创建:
然后修改Cargo.toml,指定库项目Cargo.toml所在的目录:
[dependencies]
numrust = { path = "../numrust" }
然后修改main.rs:
extern crate numrust; // 导入外部crate
use numrust::numrust as nr; // 引用numrust,第一个为库名,第二个为库中mod的名称
fn main() {
nr::hello();
}
到此,就可以运行了:
> cargo run
Compiling numrustexe v0.1.0 (C:\Users\zhangmh\Desktop\MarkDown\numrust\code\numrustexe)
Finished dev [unoptimized + debuginfo] target(s) in 0.78s
Running `target\debug\numrustexe.exe`
hello numrust
当numrust库被修改时,cargo会先编译numrust,然后再编译numrustexe,保证每次运行都是最新的结果。