你好,Cargo!
Cargo 是 Rust 的构建系统和包管理器。大多数 Rust 爱好者使用这个工具来管理他们的 Rust 项目,因为 Cargo 为你处理了很多任务,比如构建你的代码,下载你的代码所依赖的库,以及构建这些库。(我们将你的代码需要的库称为依赖项。)
最简单的 Rust 程序,比如我们目前为止编写的程序,没有任何依赖项。如果我们使用 Cargo 构建 “Hello, world!” 项目,它只会使用 Cargo 中处理代码构建的部分。随着你编写更复杂的 Rust 程序,你会添加依赖项,而且如果你使用 Cargo 启动一个项目,添加依赖项会容易得多。
因为绝大多数 Rust 项目都使用 Cargo,本书的其余部分都假定你也正在使用 Cargo。如果你使用在 “安装”部分讨论的官方安装程序,Cargo 会随 Rust 一起安装。如果你通过其他方式安装了 Rust,请在你的终端中输入以下命令来检查 Cargo 是否已安装
$ cargo --version
如果你看到一个版本号,那么你已经安装了它!如果你看到一个错误,比如 command not found
,请查看你的安装方法的文档,以确定如何单独安装 Cargo。
使用 Cargo 创建一个项目
让我们使用 Cargo 创建一个新项目,并看看它与我们最初的 “Hello, world!” 项目有何不同。导航回到你的 projects 目录(或者你决定存储代码的任何地方)。然后,在任何操作系统上,运行以下命令
$ cargo new hello_cargo
$ cd hello_cargo
第一个命令创建一个名为 hello_cargo 的新目录和项目。我们把项目命名为 hello_cargo,Cargo 会在同名目录中创建它的文件。
进入 hello_cargo 目录并列出文件。你会看到 Cargo 为我们生成了两个文件和一个目录:一个 Cargo.toml 文件和一个包含 main.rs 文件的 src 目录。
它还初始化了一个新的 Git 存储库以及一个 .gitignore 文件。如果你在现有的 Git 存储库中运行 cargo new
,则不会生成 Git 文件;你可以通过使用 cargo new --vcs=git
来覆盖此行为。
注意:Git 是一个通用的版本控制系统。你可以使用 --vcs
标志来更改 cargo new
使用不同的版本控制系统或不使用版本控制系统。运行 cargo new --help
来查看可用的选项。
在您选择的文本编辑器中打开 Cargo.toml。它应该类似于清单 1-2 中的代码。
[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.net.cn/cargo/reference/manifest.html
[dependencies]
cargo new
生成的 Cargo.toml 的内容此文件采用 TOML(Tom 的显而易见、极简语言) 格式,这是 Cargo 的配置格式。
第一行 [package]
是一个节标题,表示以下语句正在配置一个包。当我们向此文件添加更多信息时,我们将添加其他部分。
接下来的三行设置 Cargo 编译你的程序所需的配置信息:名称、版本和要使用的 Rust 版本。我们将在 附录 E 中讨论 edition
键。.
最后一行 [dependencies]
是一个节的开头,你可以在其中列出项目的任何依赖项。在 Rust 中,代码包被称为crate。我们不需要这个项目的任何其他 crate,但是我们将在第 2 章的第一个项目中使用,所以我们将在那时使用这个 dependencies 部分。
现在打开 src/main.rs 并看一下
文件名:src/main.rs
fn main() { println!("Hello, world!"); }
Cargo 为你生成了一个 “Hello, world!” 程序,就像我们在清单 1-1 中编写的程序一样!到目前为止,我们的项目和 Cargo 生成的项目之间的区别在于 Cargo 将代码放在 src 目录中,并且我们在顶层目录中有一个 Cargo.toml 配置文件。
Cargo 希望你的源文件位于 src 目录中。顶层项目目录仅用于 README 文件、许可证信息、配置文件以及其他与你的代码无关的内容。使用 Cargo 可以帮助你组织你的项目。一切都有其位置,一切都井井有条。
如果你启动了一个不使用 Cargo 的项目,就像我们用 “Hello, world!” 项目所做的那样,你可以将其转换为使用 Cargo 的项目。将项目代码移动到 src 目录并创建一个适当的 Cargo.toml 文件。获取 Cargo.toml 文件的一个简单方法是运行 cargo init
,它会自动为你创建该文件。
构建和运行 Cargo 项目
现在让我们看看使用 Cargo 构建和运行 “Hello, world!” 程序时有什么不同!从你的 hello_cargo 目录中,通过输入以下命令来构建你的项目
$ cargo build
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs
此命令在 target/debug/hello_cargo (或者 Windows 上的 target\debug\hello_cargo.exe) 中创建一个可执行文件,而不是在你的当前目录中。由于默认构建是调试构建,Cargo 会将二进制文件放在名为 debug 的目录中。你可以使用以下命令运行可执行文件
$ ./target/debug/hello_cargo # or .\target\debug\hello_cargo.exe on Windows
Hello, world!
如果一切顺利,Hello, world!
应该打印到终端。第一次运行 cargo build
还会导致 Cargo 在顶层创建一个新文件:Cargo.lock。此文件跟踪你的项目中依赖项的确切版本。此项目没有依赖项,因此该文件有点稀疏。你永远不需要手动更改此文件;Cargo 会为你管理其内容。
我们刚刚使用 cargo build
构建了一个项目,并使用 ./target/debug/hello_cargo
运行了它,但是我们也可以使用 cargo run
来编译代码,然后在一个命令中运行生成的可执行文件
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/hello_cargo`
Hello, world!
使用 cargo run
比记住运行 cargo build
然后使用二进制文件的完整路径更方便,因此大多数开发人员都使用 cargo run
。
请注意,这次我们没有看到表明 Cargo 正在编译 hello_cargo
的输出。Cargo 发现文件没有更改,因此它没有重新构建,而只是运行了二进制文件。如果你修改了你的源代码,Cargo 将在运行之前重新构建项目,并且你会看到以下输出
$ cargo run
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
Running `target/debug/hello_cargo`
Hello, world!
Cargo 还提供了一个名为 cargo check
的命令。此命令快速检查你的代码以确保其可以编译,但不会生成可执行文件
$ cargo check
Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
为什么你不想生成可执行文件?通常,cargo check
比 cargo build
快得多,因为它跳过了生成可执行文件的步骤。如果你在编写代码时不断检查你的工作,使用 cargo check
将加快让你知道你的项目是否仍在编译的过程!因此,许多 Rustaceans 会在编写程序时定期运行 cargo check
以确保其可以编译。然后,当他们准备好使用可执行文件时,他们会运行 cargo build
。
让我们回顾一下我们目前所了解的关于 Cargo 的内容
- 我们可以使用
cargo new
创建一个项目。 - 我们可以使用
cargo build
构建一个项目。 - 我们可以使用
cargo run
一步构建和运行一个项目。 - 我们可以构建一个项目而不生成二进制文件,以使用
cargo check
检查错误。 - Cargo 将构建结果存储在 target/debug 目录中,而不是将构建结果保存在与我们的代码相同的目录中。
使用 Cargo 的另一个优点是,无论你使用的是哪个操作系统,命令都是相同的。因此,此时,我们将不再提供针对 Linux 和 macOS 与 Windows 的特定说明。
构建以发布
当你的项目最终准备好发布时,你可以使用 cargo build --release
来使用优化编译它。此命令将在 target/release 而不是 target/debug 中创建一个可执行文件。优化使你的 Rust 代码运行得更快,但是启用优化会延长程序编译所需的时间。这就是为什么有两个不同的配置文件:一个用于开发,当你希望快速且频繁地重新构建时,另一个用于构建你将提供给用户的最终程序,该程序不会被重复构建,并且将尽可能快地运行。如果你要对代码的运行时间进行基准测试,请确保运行 cargo build --release
并使用 target/release 中的可执行文件进行基准测试。
作为约定的 Cargo
对于简单的项目,Cargo 并没有比仅仅使用 rustc
提供更多价值,但随着你的程序变得更加复杂,它将证明其价值。一旦程序增长到多个文件或需要依赖项,让 Cargo 协调构建会容易得多。
即使 hello_cargo
项目很简单,它现在也使用了你在其余 Rust 职业生涯中将使用的大部分真实工具。实际上,要处理任何现有项目,你可以使用以下命令使用 Git 检出代码,更改到该项目的目录并进行构建
$ git clone example.org/someproject
$ cd someproject
$ cargo build
有关 Cargo 的更多信息,请查看 其文档。
总结
你在 Rust 之旅中已经有了一个良好的开端!在本章中,你学习了如何
- 使用
rustup
安装最新的稳定版 Rust - 更新到较新的 Rust 版本
- 打开本地安装的文档
- 直接使用
rustc
编写并运行一个 “Hello, world!” 程序 - 使用 Cargo 的约定创建和运行一个新项目
现在是构建一个更实质性的程序以习惯阅读和编写 Rust 代码的好时机。因此,在第 2 章中,我们将构建一个猜数字游戏程序。如果你想先学习常见的编程概念如何在 Rust 中工作,请参阅第 3 章,然后返回第 2 章。