你好,Cargo!
Cargo 是 Rust 的构建系统和包管理器。大多数 Rustacean 使用此工具来管理他们的 Rust 项目,因为 Cargo 会为你处理很多任务,例如构建代码、下载代码依赖的库以及构建这些库。(我们称代码需要的库为_依赖项_。)
最简单的 Rust 程序(例如我们目前编写的程序)没有任何依赖项。如果我们使用 Cargo 构建“你好,世界!”项目,它只会使用 Cargo 中处理代码构建的部分。当你编写更复杂的 Rust 程序时,你将添加依赖项,如果你使用 Cargo 启动项目,添加依赖项将更容易。
因为绝大多数 Rust 项目都使用 Cargo,所以本书的其余部分假设你也在使用 Cargo。如果你使用“安装”部分中讨论的官方安装程序,Cargo 会随 Rust 一起安装。如果你通过其他方式安装了 Rust,请在终端中输入以下内容来检查是否安装了 Cargo
$ cargo --version
如果你看到版本号,则说明你已经安装了!如果你看到错误,例如 command not found
,请查看安装方法的文档,以确定如何单独安装 Cargo。
使用 Cargo 创建项目
让我们使用 Cargo 创建一个新项目,并查看它与我们最初的“你好,世界!”项目的不同之处。导航回到你的_项目_目录(或者你决定存储代码的任何位置)。然后,在任何操作系统上,运行以下命令
$ 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 中的代码。
文件名:Cargo.toml
[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]
此文件采用 TOML(Tom’s Obvious, Minimal Language,即 Tom 的显而易见、极简语言)格式,这是 Cargo 的配置文件格式。
第一行 [package]
是一个节标题,表示以下语句用于配置包。随着我们向该文件添加更多信息,我们将添加其他节。
接下来的三行设置 Cargo 编译程序所需的配置信息:名称、版本和要使用的 Rust 版本。我们将在 附录 E 中讨论 edition
键。.
最后一行 [dependencies]
是一个节的开头,用于列出项目的所有依赖项。在 Rust 中,代码包称为*crate*。此项目不需要任何其他 crate,但在第 2 章的第一个项目中需要,因此我们将在那时使用此依赖项节。
现在打开 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 项目
现在让我们看看使用 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
将加快让您知道您的项目是否仍在编译的过程!因此,许多 Rustacean 在编写程序时会定期运行 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 章。