你好,Cargo!
Cargo 是 Rust 的构建系统和包管理器。大多数 Rustaceans 使用这个工具来管理他们的 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 = "2024"
[dependencies]
cargo new 生成的 Cargo.toml 文件内容这个文件采用 TOML(Tom’s Obvious, Minimal Language,汤姆的显而易见的最小化语言)格式,它是 Cargo 的配置格式。
第一行,[package],是一个节标题,表示接下来的语句正在配置一个包。当我们向此文件中添加更多信息时,我们将添加其他节。
接下来的三行设置了 Cargo 编译程序所需的配置信息:名称、版本以及要使用的 Rust 版本。我们将在附录 E 中讨论 edition 键。.
最后一行,[dependencies],是用于列出项目所有依赖的节的开始。在 Rust 中,代码包被称为 crates。这个项目不需要其他 crates,但我们会在第 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.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 章。