Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help


x-i18n: generated_at: “2026-03-01T13:51:36Z” model: gemini-3-flash-preview provider: google-gemini-cli source_hash: 7141297fcc8bd0d0cb4e850b9f853574ddbb15b48a8b56c615539979c8a9e27e source_path: ch07-01-packages-and-crates.md workflow: 16

包 (Packages) 与 Crate (Crates)

Packages and Crates

我们将介绍的模块系统的第一部分是包(packages)和 crate。

The first parts of the module system we’ll cover are packages and crates.

“Crate” 是 Rust 编译器一次考虑的最小代码量。即使你运行 rustc 而不是 cargo 并且传递了一个源代码文件(正如我们在第 1 章“Rust 程序基础”中所做的那样),编译器也会将该文件视为一个 crate。Crate 可以包含模块,并且这些模块可能在与 crate 一起编译的其他文件中定义,我们将在接下来的章节中看到。

A crate is the smallest amount of code that the Rust compiler considers at a time. Even if you run rustc rather than cargo and pass a single source code file (as we did all the way back in “Rust Program Basics” in Chapter 1), the compiler considers that file to be a crate. Crates can contain modules, and the modules may be defined in other files that get compiled with the crate, as we’ll see in the coming sections.

Crate 可以有两种形式:二进制 crate 或库 crate。“二进制 crate (Binary crates)” 是可以编译为可执行文件的程序,你可以运行它,例如命令行程序或服务器。每个二进制 crate 必须具有一个名为 main 的函数,该函数定义了可执行文件运行时发生的情况。到目前为止,我们创建的所有 crate 都是二进制 crate。

A crate can come in one of two forms: a binary crate or a library crate. Binary crates are programs you can compile to an executable that you can run, such as a command line program or a server. Each must have a function called main that defines what happens when the executable runs. All the crates we’ve created so far have been binary crates.

“库 crate (Library crates)” 没有 main 函数,它们不会编译为可执行文件。相反,它们定义了旨在与多个项目共享的功能。例如,我们在第 2 章中使用的 rand crate 提供了生成随机数的功能。大多数时候,Rustaceans 说 “crate” 时是指库 crate,并且他们将 “crate” 与通用编程概念中的“库 (library)”互换使用。

Library crates don’t have a main function, and they don’t compile to an executable. Instead, they define functionality intended to be shared with multiple projects. For example, the rand crate we used in Chapter 2 provides functionality that generates random numbers. Most of the time when Rustaceans say “crate,” they mean library crate, and they use “crate” interchangeably with the general programming concept of a “library.”

“Crate 根 (crate root)” 是 Rust 编译器开始并构成 crate 根模块的源文件(我们将在“使用模块控制作用域和私有性”中深入解释模块)。

The crate root is a source file that the Rust compiler starts from and makes up the root module of your crate (we’ll explain modules in depth in “Control Scope and Privacy with Modules”).

“包 (Package)” 是提供一组功能的一个或多个 crate 的捆绑。包包含一个 Cargo.toml 文件,该文件描述了如何构建这些 crate。Cargo 实际上是一个包,其中包含你一直用来构建代码的命令行工具的二进制 crate。Cargo 包还包含一个二进制 crate 所依赖的库 crate。其他项目可以依赖于 Cargo 库 crate,以使用与 Cargo 命令行工具相同的逻辑。

A package is a bundle of one or more crates that provides a set of functionality. A package contains a Cargo.toml file that describes how to build those crates. Cargo is actually a package that contains the binary crate for the command line tool you’ve been using to build your code. The Cargo package also contains a library crate that the binary crate depends on. Other projects can depend on the Cargo library crate to use the same logic the Cargo command line tool uses.

一个包可以包含任意数量的二进制 crate,但最多只能有一个库 crate。一个包必须包含至少一个 crate,无论是库 crate 还是二进制 crate。

A package can contain as many binary crates as you like, but at most only one library crate. A package must contain at least one crate, whether that’s a library or binary crate.

让我们来看看创建一个包时会发生什么。首先,我们输入命令 cargo new my-project

Let’s walk through what happens when we create a package. First, we enter the command cargo new my-project:

$ cargo new my-project
     Created binary (application) `my-project` package
$ ls my-project
Cargo.toml
src
$ ls my-project/src
main.rs

运行 cargo new my-project 后,我们使用 ls 查看 Cargo 创建的内容。在 my-project 目录中,有一个 Cargo.toml 文件,给了我们一个包。还有一个包含 main.rssrc 目录。在文本编辑器中打开 Cargo.toml,注意没有提到 src/main.rs。Cargo 遵循一个惯例,即 src/main.rs 是与包同名的二进制 crate 的 crate 根。同样,Cargo 知道如果包目录包含 src/lib.rs,则该包包含一个与包同名的库 crate,并且 src/lib.rs 是其 crate 根。Cargo 将 crate 根文件传递给 rustc 来构建库或二进制文件。

After we run cargo new my-project, we use ls to see what Cargo creates. In the my-project directory, there’s a Cargo.toml file, giving us a package. There’s also a src directory that contains main.rs. Open Cargo.toml in your text editor and note that there’s no mention of src/main.rs. Cargo follows a convention that src/main.rs is the crate root of a binary crate with the same name as the package. Likewise, Cargo knows that if the package directory contains src/lib.rs, the package contains a library crate with the same name as the package, and src/lib.rs is its crate root. Cargo passes the crate root files to rustc to build the library or binary.

在这里,我们有一个仅包含 src/main.rs 的包,意味着它仅包含一个名为 my-project 的二进制 crate。如果包同时包含 src/main.rssrc/lib.rs,它就有两个 crate:一个二进制 crate 和一个库 crate,且两者都与包同名。通过在 src/bin 目录中放置文件,一个包可以拥有多个二进制 crate:每个文件都将是一个单独的二进制 crate。

Here, we have a package that only contains src/main.rs, meaning it only contains a binary crate named my-project. If a package contains src/main.rs and src/lib.rs, it has two crates: a binary and a library, both with the same name as the package. A package can have multiple binary crates by placing files in the src/bin directory: Each file will be a separate binary crate.