一、使用发布配置来定制构建
Rust中的发布配置是一系列预定义好的配置方案,它们的配置选项各有不同,都允许程序员对细节进行定制修改。
Cargo最常用的配置有两种: 执行cargo build
时使用的dev配置,以及执行cargo build --release
时使用的release配置。dev配置中的默认选项适合在开发过程中使用,而release配置中的默认选项则适合在正式发布时使用。
当项目的Cargo.toml文件中没有任何[profile.*]
区域时,Cargo针对每个配置都会有一套可以应用的默认选项。通过为任意的配置添加[profile.*]
区域,我们可以覆盖默认设置的任意子集。
[profile.dev]
opt-level = 0
[profile.release]
opt-level = 3
选项opt-level
决定了Rust在编译时会对代码执行何种程度的优化,从0到3都是合法的配置值。越高级的优化需要消耗越多的编译时间。
二、将包发布到crates.io
由于crates.io
的包注册表会以源代码的形式来分发你的包,所以由它托管的包大部分都是开源的。Rust和Cargo提供了一些功能来帮助人们更轻松地找到并使用你所发布的包。
1、编写有用的文档注释
Rust还提供了一种一种特殊的文档注释。以这种方式编写的注释内容可以被生成为HTML文档。这些HTML文档回想感兴趣的用户展示公共API的文档注释内容,它的作用在于描述当前包的使用方法而不是包内部的实现细节。
我们使用三斜线///
而不是双斜线//
来编写文档注释,并且可以在文档注释中使用Markdown语法来格式化内容。文档注释被放置在它所说明的条目之前。
/// Adds one to the number given.
///
/// # Examples
///
/// ```
/// let arg = 5;
/// let answer = my_crate::add_one(arg);
///
/// assert_eq!(6, answer);
/// ```
pub fn add_one(x: i32) -> i32 {
x + 1
}
在上面代码中,我们首先描述了add_one
函数的用途,接着开始了一段名为Examples的区域并提供了一段演示add_one
函数使用方式的代码。我们通过运行cargo doc
命令来基于这段代码注释生成HTML文档。这条命令会调用Rust内置的rustdoc工具在target/doc
路径下生成HTML文档。
为了方便,我们也可以调用cargo doc --open
来生成并自动在浏览器中打开当前包的文档以及所有依赖包的文档。
在示例中使用Markdown标题语法# Examples
在HTML文档中创建了标题为Examples
的区域。除此之外,作者还经常使用下面的区域:
- Panics:指出函数可能引发panic的场景。不想触发panic的调用者应当确保自己的代码不会在这些场景下调用该函数;
- Errors:当函数返回Result作为结果时,这个区域会指出可能出现的错误,以及造成这些错误的具体原因,它可以帮助调用者在编写代码时为不同的错误采取不通的措施;
- Safety:当函数使用了unsafe关键字时,这个区域会指出当前函数不安全的原因,以及调用者应当确保的使用前提;
1.将文档注释用作测试
在文档注释中增加示例可以帮助用户理解代码库的使用方式。除此之外,cargo test
会在执行时将文档注释中的代码示例作为测试区运行。
2.在条目内部编写注释
还有一种文档注释形式:||!
它可以为包裹当前注释的内层条目(而不是紧随注释之后的条目)添加文档。这种文档注释通常被用在包的根文件或模块的根文件上,分别为整个包或这个模块提供文档。
//! # My Crate
//!
//! `my_crate` is a collection of utilities to make performing certain
//! calculations more convenient.
/// Adds one to the number given.
// --snip--
///
/// # Examples
///
/// ```
/// let arg = 5;
/// let answer = my_crate::add_one(arg);
///
/// assert_eq!(6, answer);
/// ```
pub fn add_one(x: i32) -> i32 {
x + 1
}
注意,最后一个||!
注释行的后面没有任何可供注释的代码。因为我们在注释时使用了||!
而不是|||
,所以该注释是为了包含这段注释的条目而编写的,而不是为了紧随注释之后的条目编写的。在示例中,包含这段注释的条目就是src/lib.rs
文件,也就是包的根文件,也就是说这段注释描述整个包。
我们再次运行cargo doc --open
,这段注释就会出现在my_crate
首页。
3、使用pub use来导出合适的公共API
在决定发布一个包时,我们必须要考虑好如何组织公共API。一旦包的层次结构过去复杂,用户就可能会难以找到他们真正需要的部分。我们可以使用pub use
来重新导出部分条目,从而建立一套和你的内部结构不同的对外结构。
三、Cargo工作空间
Cargo提供一个叫做工作空间的功能,它可以帮助开发者管理多个相互关联且需要协同开发的包。
1、创建工作空间
工作空间是由共用同一个Cargo.lock
和输出目录的一系列包所组成的。这个工作空间最终包含一个二进制包和两个代码包,二进制包依赖于另外两个代码包来实现自己的主要功能。
首先,我们先创建工作空间的目录:
C:\Users\Lucky\projects>mkdir add
C:\Users\Lucky\projects>cd add
随后,在add
目录中添加一个用于配置工作空间的Cargo.toml
文件,它与我们曾经见过的其他的Cargo.toml
文件有所不通,它既不包含[package]
区域,也不包含之前使用过的其他元数据。这个文件会以[workspace]
区域开始,该区域允许我们指定二进包的路径来为工作空间添加成员。
[workspace]
members = [
"adder",
]
接下来,使用cargo new
命令在add
目录下创建这个adder
二进制包:
现在,我们使用cargo build
构建这个工作空间。
add
目录下的文件结构如下:
工作空间在根目录下有一个target
目录用来存放所有成员的编译产出物,相对应的,adder
包也没有了自己独立的target
目录。即使我们进入adder
目录中运行cargo build
,编译产出物依然会输出到add/target
中。Cargo之所以会将不通的target
目录集中到一处是因为工作空间中的包往往都是互相依赖的。
四、使用cargo install从crates.io上安装可执行程序
cargo install
命令使我们可以在计算机中安装和使用二进制包。但要注意的是,它不能被用来替换操作系统的包管理工具。所有通过cargo install
命令安装的二进制文件都会被存储在Rust安装根目录下的bin文件夹中。
五、使用自定义命令扩展Cargo的功能
Cargo允许我们添加子命令来扩展它的功能而无须修改Cargo本身。只要你的$PATH
路径中存在二进制文件cargo-something
,就可以通过运行cargo something
运行该二进制文件。运行cargo --list
可以累出所有与此类似的自定义命令。