你好,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 中的代码。

Filename: Cargo.toml
[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
Listing 1-2: Contents of Cargo.toml generated by cargo new

这个文件采用 TOML (Tom 的显而易见、最小化语言) 格式,这是 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 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 checkcargo 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 的价值将逐渐显现。一旦程序增长到多个文件或需要依赖项时,让 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 章。