@@ -43,11 +43,11 @@ organization, including which details are exposed, which details are private,
43
43
and what names are in each scope in your programs. These features, sometimes
44
44
collectively referred to as the * module system* , include:
45
45
46
- * ** Packages: ** A Cargo feature that lets you build, test, and share crates
47
- * ** Crates: ** A tree of modules that produces a library or executable
48
- * ** Modules** and ** use: ** Let you control the organization, scope, and
49
- privacy of paths
50
- * ** Paths: ** A way of naming an item, such as a struct, function, or module
46
+ * ** Packages** : A Cargo feature that lets you build, test, and share crates
47
+ * ** Crates** : A tree of modules that produces a library or executable
48
+ * ** Modules and use** : Let you control the organization, scope, and privacy of
49
+ paths
50
+ * ** Paths** : A way of naming an item, such as a struct, function, or module
51
51
52
52
In this chapter, we’ll cover all these features, discuss how they interact, and
53
53
explain how to use them to manage scope. By the end, you should have a solid
@@ -72,10 +72,10 @@ created so far have been binary crates.
72
72
73
73
* Library crates* don’t have a ` main ` function, and they don’t compile to an
74
74
executable. Instead, they define functionality intended to be shared with
75
- multiple projects. For example, the ` rand ` crate we used in Chapter
76
- 2 provides functionality that generates random numbers.
77
- Most of the time when Rustaceans say “crate”, they mean library crate, and they
78
- use “crate” interchangeably with the general programming concept of a “library”.
75
+ multiple projects. For example, the ` rand ` crate we used in Chapter 2 provides
76
+ functionality that generates random numbers. Most of the time when Rustaceans
77
+ say “crate,” they mean library crate, and they use “crate” interchangeably with
78
+ the general programming concept of a “library.”
79
79
80
80
The * crate root* is a source file that the Rust compiler starts from and makes
81
81
up the root module of your crate (we’ll explain modules in depth in “Defining
@@ -87,9 +87,11 @@ build those crates. Cargo is actually a package that contains the binary crate
87
87
for the command line tool you’ve been using to build your code. The Cargo
88
88
package also contains a library crate that the binary crate depends on. Other
89
89
projects can depend on the Cargo library crate to use the same logic the Cargo
90
- command line tool uses. A package can contain as many binary crates as you
91
- like, but at most only one library crate. A package must contain at least one
92
- crate, whether that’s a library or binary crate.
90
+ command line tool uses.
91
+
92
+ A package can contain as many binary crates as you like, but at most only one
93
+ library crate. A package must contain at least one crate, whether that’s a
94
+ library or binary crate.
93
95
94
96
Let’s walk through what happens when we create a package. First we enter the
95
97
command ` cargo new my-project ` :
@@ -116,16 +118,9 @@ files to `rustc` to build the library or binary.
116
118
117
119
Here, we have a package that only contains * src/main.rs* , meaning it only
118
120
contains a binary crate named ` my-project ` . If a package contains * src/main.rs*
119
- and * src/lib.rs* , it has two crates: a binary and a library, both with the same
120
- name as the package. A package can have multiple binary crates by placing files
121
- in the * src/bin* directory: each file will be a separate binary crate.
122
-
123
- ## Defining Modules to Control Scope and Privacy
124
-
125
- In this section, we’ll talk about modules and other parts of the module system,
126
- namely * paths* , which allow you to name items; the ` use ` keyword that brings a
127
- path into scope; and the ` pub ` keyword to make items public. We’ll also discuss
128
- the ` as ` keyword, external packages, and the glob operator.
121
+ and * src/lib.rs* , it has two crates: a binary and a library, both with the
122
+ same name as the package. A package can have multiple binary crates by placing
123
+ files in the * src/bin* directory: each file will be a separate binary crate.
129
124
130
125
### Modules Cheat Sheet
131
126
@@ -141,7 +136,8 @@ great place to refer to as a reminder of how modules work.
141
136
* ** Declaring modules** : In the crate root file, you can declare new modules;
142
137
say you declare a “garden” module with ` mod garden; ` . The compiler will look
143
138
for the module’s code in these places:
144
- * Inline, within curly brackets that replace the semicolon following ` mod garden `
139
+ * Inline, within curly brackets that replace the semicolon following `mod
140
+ garden`
145
141
* In the file * src/garden.rs*
146
142
* In the file * src/garden/mod.rs*
147
143
* ** Declaring submodules** : In any file other than the crate root, you can
@@ -163,8 +159,9 @@ great place to refer to as a reminder of how modules work.
163
159
` pub ` before their declarations.
164
160
* ** The ` use ` keyword** : Within a scope, the ` use ` keyword creates shortcuts to
165
161
items to reduce repetition of long paths. In any scope that can refer to
166
- ` crate::garden::vegetables::Asparagus ` , you can create a shortcut with ` use crate::garden::vegetables::Asparagus; ` and from then on you only need to
167
- write ` Asparagus ` to make use of that type in the scope.
162
+ ` crate::garden::vegetables::Asparagus ` , you can create a shortcut with `use
163
+ crate::garden::vegetables::Asparagus;` and from then on you only need to write
164
+ ` Asparagus ` to make use of that type in the scope.
168
165
169
166
Here, we create a binary crate named ` backyard ` that illustrates these rules.
170
167
The crate’s directory, also named ` backyard ` , contains these files and
@@ -176,15 +173,13 @@ backyard
176
173
├── Cargo.toml
177
174
└── src
178
175
├── garden
179
- │ └── vegetables.rs
176
+ │ └── vegetables.rs
180
177
├── garden.rs
181
178
└── main.rs
182
179
```
183
180
184
181
The crate root file in this case is * src/main.rs* , and it contains:
185
182
186
- src/main.rs
187
-
188
183
```
189
184
use crate::garden::vegetables::Asparagus;
190
185
@@ -219,7 +214,12 @@ pub struct Asparagus {}
219
214
220
215
Now let’s get into the details of these rules and demonstrate them in action!
221
216
222
- ### Grouping Related Code in Modules
217
+ ## Defining Modules to Control Scope and Privacy
218
+
219
+ In this section, we’ll talk about modules and other parts of the module system,
220
+ namely * paths* , which allow you to name items; the ` use ` keyword that brings a
221
+ path into scope; and the ` pub ` keyword to make items public. We’ll also discuss
222
+ the ` as ` keyword, external packages, and the glob operator.
223
223
224
224
* Modules* let us organize code within a crate for readability and easy reuse.
225
225
Modules also allow us to control the * privacy* of items because code within a
@@ -241,7 +241,8 @@ chefs and cooks work in the kitchen, dishwashers clean up, and managers do
241
241
administrative work.
242
242
243
243
To structure our crate in this way, we can organize its functions into nested
244
- modules. Create a new library named ` restaurant ` by running ` cargo new restaurant --lib ` . Then enter the code in Listing 7-1 into * src/lib.rs* to
244
+ modules. Create a new library named ` restaurant ` by running `cargo new
245
+ restaurant --lib`. Then enter the code in Listing 7-1 into * src/lib.rs* to
245
246
define some modules and function signatures; this code is the front of house
246
247
section.
247
248
@@ -271,8 +272,8 @@ We define a module with the `mod` keyword followed by the name of the module
271
272
(in this case, ` front_of_house ` ). The body of the module then goes inside curly
272
273
brackets. Inside modules, we can place other modules, as in this case with the
273
274
modules ` hosting ` and ` serving ` . Modules can also hold definitions for other
274
- items, such as structs, enums, constants, traits, and— as in Listing
275
- 7-1— functions.
275
+ items, such as structs, enums, constants, traits, and as in Listing 7-1,
276
+ functions.
276
277
277
278
By using modules, we can group related definitions together and name why
278
279
they’re related. Programmers using this code can navigate the code based on the
@@ -580,8 +581,8 @@ interested in this topic, see The Rust API Guidelines at *https://rust-lang.gith
580
581
> root as well as a * src/lib.rs* library crate root, and both crates will have
581
582
> the package name by default. Typically, packages with this pattern of
582
583
> containing both a library and a binary crate will have just enough code in the
583
- > binary crate to start an executable that calls code within the library crate.
584
- > This lets other projects benefit from most of the functionality that the
584
+ > binary crate to start an executable that calls code defined in the library
585
+ > crate. This lets other projects benefit from the most functionality that the
585
586
> package provides because the library crate’s code can be shared.
586
587
>
587
588
> The module tree should be defined in * src/lib.rs* . Then, any public items can
@@ -590,20 +591,19 @@ interested in this topic, see The Rust API Guidelines at *https://rust-lang.gith
590
591
> external crate would use the library crate: it can only use the public API.
591
592
> This helps you design a good API; not only are you the author, you’re also a
592
593
> client!
593
- >
594
- > In Chapter 12, we’ll demonstrate this organizational
595
- > practice with a command line program that will contain both a binary crate
596
- > and a library crate.
594
+ >
595
+ > In Chapter 12, we’ll demonstrate this organizational practice with a command
596
+ > line program that will contain both a binary crate and a library crate.
597
597
598
598
### Starting Relative Paths with super
599
599
600
600
We can construct relative paths that begin in the parent module, rather than
601
601
the current module or the crate root, by using ` super ` at the start of the
602
- path. This is like starting a filesystem path with the ` .. ` syntax. Using
603
- ` super ` allows us to reference an item that we know is in the parent module,
604
- which can make rearranging the module tree easier when the module is closely
605
- related to the parent but the parent might be moved elsewhere in the module
606
- tree someday.
602
+ path. This is like starting a filesystem path with the ` .. ` syntax that means
603
+ to go to the parent directory. Using ` super ` allows us to reference an item
604
+ that we know is in the parent module, which can make rearranging the module
605
+ tree easier when the module is closely related to the parent but the parent
606
+ might be moved elsewhere in the module tree someday.
607
607
608
608
Consider the code in Listing 7-8 that models the situation in which a chef
609
609
fixes an incorrect order and personally brings it out to the customer. The
@@ -940,12 +940,12 @@ considered idiomatic, so the choice is up to you!
940
940
941
941
### Re-exporting Names with pub use
942
942
943
- When we bring a name into scope with the ` use ` keyword, the name available in
944
- the new scope is private . To enable the code that calls our code to refer to
945
- that name as if it had been defined in that code’s scope, we can combine ` pub `
946
- and ` use ` . This technique is called * re-exporting* because we’re bringing an
947
- item into scope but also making that item available for others to bring into
948
- their scope.
943
+ When we bring a name into scope with the ` use ` keyword, the name is private to
944
+ the scope into which we imported it . To enable code outside that scope to refer
945
+ to that name as if it had been defined in that scope, we can combine ` pub ` and
946
+ ` use ` . This technique is called * re-exporting* because we’re bringing an item
947
+ into scope but also making that item available for others to bring into their
948
+ scope.
949
949
950
950
Listing 7-17 shows the code in Listing 7-11 with ` use ` in the root module
951
951
changed to ` pub use ` .
@@ -1117,7 +1117,10 @@ use std::collections::*;
1117
1117
This ` use ` statement brings all public items defined in ` std::collections ` into
1118
1118
the current scope. Be careful when using the glob operator! Glob can make it
1119
1119
harder to tell what names are in scope and where a name used in your program
1120
- was defined.
1120
+ was defined. Additionally, if the dependency changes its definitions, what
1121
+ you’ve imported changes as well, which may lead to compiler errors when you
1122
+ upgrade the dependency if the dependency adds a definition with the same name
1123
+ as a definition of yours in the same scope, for example.
1121
1124
1122
1125
The glob operator is often used when testing to bring everything under test into
1123
1126
the ` tests ` module; we’ll talk about that in “How to Write
0 commit comments