Package 和 Crate
Packages and Crates
我们要讨论的模块系统的第一部分是 package(包)和 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 提供了生成随机数的功能。大多数时候 Rustacean 说 “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 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 的捆绑。Package 包含一个 Cargo.toml 文件,该文件描述了如何构建这些 crate。Cargo 实际上是一个 package,它包含你一直用来构建代码的命令行工具的二进制 crate。Cargo package 还包含二进制 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.
一个 package 可以包含任意数量的二进制 crate,但最多只能包含一个库 crate。一个 package 必须包含至少一个 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.
让我们看看创建一个 package 时会发生什么。首先,我们输入命令 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 文件,为我们提供了一个 package。还有一个包含 main.rs 的 src 目录。在文本编辑器中打开 Cargo.toml,注意没有提到 src/main.rs。Cargo 遵循一项约定,即 src/main.rs 是与 package 同名的二进制 crate 的 crate root。同样,Cargo 知道如果 package 目录包含 src/lib.rs,则 package 包含一个与 package 同名的库 crate,并且 src/lib.rs 是其 crate root。Cargo 将 crate root 文件传递给 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 的 package,这意味着它仅包含一个名为 my-project 的二进制 crate。如果一个 package 包含 src/main.rs 和 src/lib.rs,它就有两个 crate:一个二进制 crate 和一个库 crate,且两者都与 package 同名。通过将文件放置在 src/bin 目录中,一个 package 可以拥有多个二进制 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.