rust-book-cn/src/ch07-01-packages-and-crates.md

65 lines
3.1 KiB
Markdown
Raw Normal View History

2021-05-09 14:49:31 +08:00
## Packages and Crates
The first parts of the module system well cover are packages and crates. A
crate is a binary or library. The *crate root* is a source file that the Rust
compiler starts from and makes up the root module of your crate (well explain
modules in depth in the [“Defining Modules to Control Scope and
Privacy”][modules]<!-- ignore --> section). A *package* is one or more crates
that provide a set of functionality. A package contains a *Cargo.toml* file
that describes how to build those crates.
Several rules determine what a package can contain. A package *must* contain
zero or one library crates, and no more. It can contain as many binary crates
as youd like, but it must contain at least one crate (either library or
binary).
Lets walk through what happens when we create a package. First, we enter the
command `cargo new`:
```console
$ cargo new my-project
Created binary (application) `my-project` package
$ ls my-project
Cargo.toml
src
$ ls my-project/src
main.rs
```
When we entered the command, Cargo created a *Cargo.toml* file, giving us a
package. Looking at the contents of *Cargo.toml*, theres no mention of
*src/main.rs* because 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.
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 library and a binary, 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.
A crate will group related functionality together in a scope so the
functionality is easy to share between multiple projects. For example, the
`rand` crate we used in [Chapter 2][rand]<!-- ignore --> provides functionality
that generates random numbers. We can use that functionality in our own
projects by bringing the `rand` crate into our projects scope. All the
functionality provided by the `rand` crate is accessible through the crates
name, `rand`.
Keeping a crates functionality in its own scope clarifies whether particular
functionality is defined in our crate or the `rand` crate and prevents
potential conflicts. For example, the `rand` crate provides a trait named
`Rng`. We can also define a `struct` named `Rng` in our own crate. Because a
crates functionality is namespaced in its own scope, when we add `rand` as a
dependency, the compiler isnt confused about what the name `Rng` refers to. In
our crate, it refers to the `struct Rng` that we defined. We would access the
`Rng` trait from the `rand` crate as `rand::Rng`.
Lets move on and talk about the module system!
[modules]: ch07-02-defining-modules-to-control-scope-and-privacy.html
[rand]: ch02-00-guessing-game-tutorial.html#generating-a-random-number