]>
Commit | Line | Data |
---|---|---|
5e7ed085 FG |
1 | <!-- DO NOT EDIT THIS FILE. |
2 | ||
3 | This file is periodically generated from the content in the `/src/` | |
4 | directory, so all fixes need to be made in `/src/`. | |
5 | --> | |
6 | ||
7 | [TOC] | |
8 | ||
9 | # Managing Growing Projects with Packages, Crates, and Modules | |
10 | ||
923072b8 FG |
11 | As you write large programs, organizing your code will become increasingly |
12 | important. By grouping related functionality and separating code with distinct | |
13 | features, you’ll clarify where to find code that implements a particular | |
14 | feature and where to go to change how a feature works. | |
5e7ed085 FG |
15 | |
16 | The programs we’ve written so far have been in one module in one file. As a | |
923072b8 FG |
17 | project grows, you should organize code by splitting it into multiple modules |
18 | and then multiple files. A package can contain multiple binary crates and | |
5e7ed085 FG |
19 | optionally one library crate. As a package grows, you can extract parts into |
20 | separate crates that become external dependencies. This chapter covers all | |
923072b8 FG |
21 | these techniques. For very large projects comprising a set of interrelated |
22 | packages that evolve together, Cargo provides *workspaces*, which we’ll cover | |
23 | in the “Cargo Workspaces” section in Chapter 14. | |
24 | ||
25 | We’ll also discuss encapsulating implementation details, which lets you reuse | |
26 | code at a higher level: once you’ve implemented an operation, other code can | |
27 | call your code via its public interface without having to know how the | |
28 | implementation works. The way you write code defines which parts are public for | |
29 | other code to use and which parts are private implementation details that you | |
30 | reserve the right to change. This is another way to limit the amount of detail | |
31 | you have to keep in your head. | |
5e7ed085 FG |
32 | |
33 | A related concept is scope: the nested context in which code is written has a | |
34 | set of names that are defined as “in scope.” When reading, writing, and | |
35 | compiling code, programmers and compilers need to know whether a particular | |
36 | name at a particular spot refers to a variable, function, struct, enum, module, | |
37 | constant, or other item and what that item means. You can create scopes and | |
38 | change which names are in or out of scope. You can’t have two items with the | |
39 | same name in the same scope; tools are available to resolve name conflicts. | |
40 | ||
41 | Rust has a number of features that allow you to manage your code’s | |
42 | organization, including which details are exposed, which details are private, | |
43 | and what names are in each scope in your programs. These features, sometimes | |
44 | collectively referred to as the *module system*, include: | |
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 | |
51 | ||
52 | In this chapter, we’ll cover all these features, discuss how they interact, and | |
53 | explain how to use them to manage scope. By the end, you should have a solid | |
54 | understanding of the module system and be able to work with scopes like a pro! | |
55 | ||
56 | ## Packages and Crates | |
57 | ||
5e7ed085 FG |
58 | The first parts of the module system we’ll cover are packages and crates. |
59 | ||
923072b8 FG |
60 | <!-- Do you have a general definition of a crate we can add, or is it too |
61 | dependent on whether it's a binary or library crate? /LC --> | |
62 | <!-- I've struggled to come up with something that isn't just "smaller than a | |
63 | package but bigger than a module"... "reusable" or "what you specify as a | |
64 | dependency" only applies to library crates... this definition I've added here | |
65 | gets a little bit into how the compiler sees crates, which might be too much | |
66 | detail? What do you think about this next paragraph? /Carol --> | |
67 | <!-- JT, what do you think? /LC --> | |
68 | <!-- I think this works. | |
69 | ||
70 | Carol - I'm wondering a bit if "packages" above helps the reader build the | |
71 | mental model or if it's kind of an implementation detail for cargo (we could | |
72 | say we "package crates"). You're definitely the expert here, but I wonder if we | |
73 | can simplify down to Crates/Modules/Paths and mention that we'll introduce some | |
74 | of the techniques the tooling uses to work with these later. /JT --> | |
75 | <!-- I feel like we need to explain the `[package]` section in *Cargo.toml*, | |
76 | and explain what the container is when you have a library and one or more | |
77 | binaries in one directory, and that's a package. It is a little weird because | |
78 | people hardly ever talk in terms of packages, only in terms of crates, but I | |
79 | think it's better to have the discussion of package here. /Carol --> | |
80 | ||
81 | A *crate* is the smallest amount of code that the Rust compiler considers at a | |
82 | time. Even if you run `rustc` rather than `cargo` and pass a single source code | |
83 | file (as we did all the way back in the “Writing and Running a Rust Program” | |
84 | section of Chapter 1), the compiler considers that file to be a crate. Crates | |
85 | can contain modules, and the modules may be defined in other files that get | |
86 | compiled with the crate, as we’ll see in the coming sections. | |
87 | ||
88 | A crate can come in one of two forms: a binary crate or a library crate. | |
89 | *Binary crates* are programs you can compile to an executable that you can run, | |
90 | such as a command-line program or a server. Each must have a function called | |
91 | `main` that defines what happens when the executable runs. All the crates we’ve | |
92 | created so far have been binary crates. | |
5e7ed085 FG |
93 | |
94 | *Library crates* don’t have a `main` function, and they don’t compile to an | |
923072b8 FG |
95 | executable. Instead, they define functionality intended to be shared with |
96 | multiple projects. For example, the `rand` crate we used in Chapter 2 provides | |
97 | functionality that generates random numbers. Most of the time when Rustaceans | |
98 | say “crate”, they mean library crate, and they use “crate” interchangeably with | |
99 | the general programming concept of a “library". | |
5e7ed085 FG |
100 | |
101 | The *crate root* is a source file that the Rust compiler starts from and makes | |
102 | up the root module of your crate (we’ll explain modules in depth in the | |
103 | “Defining Modules to Control Scope and Privacy” section). | |
104 | ||
923072b8 FG |
105 | A *package* is a bundle of one or more crates that provides a set of |
106 | functionality. A package contains a *Cargo.toml* file that describes how to | |
107 | build those crates. Cargo is actually a package that contains the binary crate | |
108 | for the command-line tool you’ve been using to build your code. The Cargo | |
109 | package also contains a library crate that the binary crate depends on. Other | |
110 | projects can depend on the Cargo library crate to use the same logic the Cargo | |
111 | command-line tool uses. | |
112 | ||
113 | A package can contain as many binary crates as you like, but at most only one | |
114 | library crate. A package must contain at least one crate, whether that’s a | |
115 | library or binary crate. | |
5e7ed085 FG |
116 | |
117 | Let’s walk through what happens when we create a package. First, we enter the | |
118 | command `cargo new`: | |
119 | ||
120 | ``` | |
121 | $ cargo new my-project | |
122 | Created binary (application) `my-project` package | |
123 | $ ls my-project | |
124 | Cargo.toml | |
125 | src | |
126 | $ ls my-project/src | |
127 | main.rs | |
128 | ``` | |
129 | ||
923072b8 FG |
130 | <!-- I can't remember if we warned folks we were going to use unix commands. May |
131 | want to throw in the Windows command here too, so they feel welcome. /JT --> | |
132 | <!-- I don't think JT has seen chapter 1 yet, we address that there /Carol --> | |
133 | ||
134 | After we run `cargo new`, we use `ls` to see what Cargo creates. In the project | |
135 | directory, there’s a *Cargo.toml* file, giving us a package. There’s also a | |
136 | *src* directory that contains *main.rs*. Open *Cargo.toml* in your text editor, | |
137 | and note there’s no mention of *src/main.rs*. Cargo follows a convention that | |
138 | *src/main.rs* is the crate root of a binary crate with the same name as the | |
139 | package. Likewise, Cargo knows that if the package directory contains | |
140 | *src/lib.rs*, the package contains a library crate with the same name as the | |
141 | package, and *src/lib.rs* is its crate root. Cargo passes the crate root files | |
142 | to `rustc` to build the library or binary. | |
5e7ed085 FG |
143 | |
144 | Here, we have a package that only contains *src/main.rs*, meaning it only | |
145 | contains a binary crate named `my-project`. If a package contains *src/main.rs* | |
146 | and *src/lib.rs*, it has two crates: a binary and a library, both with the same | |
147 | name as the package. A package can have multiple binary crates by placing files | |
148 | in the *src/bin* directory: each file will be a separate binary crate. | |
149 | ||
150 | ## Defining Modules to Control Scope and Privacy | |
151 | ||
152 | In this section, we’ll talk about modules and other parts of the module system, | |
153 | namely *paths* that allow you to name items; the `use` keyword that brings a | |
154 | path into scope; and the `pub` keyword to make items public. We’ll also discuss | |
155 | the `as` keyword, external packages, and the glob operator. | |
156 | ||
157 | First, we’re going to start with a list of rules for easy reference when you’re | |
158 | organizing your code in the future. Then we’ll explain each of the rules in | |
159 | detail. | |
160 | ||
923072b8 | 161 | ### Modules Cheat Sheet |
5e7ed085 | 162 | |
923072b8 | 163 | <!--WHEN TRANSFERRED TO WORD, DECIDE ON BOX OR NOT --> |
5e7ed085 | 164 | |
923072b8 FG |
165 | Here we provide a quick reference on how modules, paths, the `use` keyword, and |
166 | the `pub` keyword work in the compiler, and how most developers organize their | |
167 | code. We’ll be going through examples of each of these rules throughout this | |
168 | chapter, but this is a great place to refer to as a reminder of how modules | |
169 | work. | |
5e7ed085 FG |
170 | |
171 | - **Start from the crate root**: When compiling a crate, the compiler first | |
172 | looks in the crate root file (usually *src/lib.rs* for a library crate or | |
923072b8 FG |
173 | *src/main.rs* for a binary crate) for code to compile. |
174 | <!-- I may be asking a silly question here... but what is the compiler looking | |
175 | for in the crate root file? just things to start compiling? /LC --> | |
176 | <!-- That's exactly it-- it's the starting point of compilation, and the | |
177 | compiler will only find files if they're connected to the crate root somehow. | |
178 | Do you think that should be mentioned here? Is there something about this | |
179 | explanation that would make you feel more confident about the concept? /Carol | |
180 | --> | |
181 | <!-- I've added "for things to compile" -- I wanted to make sure the reader | |
182 | knew they weren't missing anything, that there wasn't a particular thing | |
183 | being looked for that the reader wasn't aware of /LC --> | |
184 | <!-- I changed "things" to "code" to be more precise /Carol --> | |
185 | - **Declaring modules**: In the crate root file, you can declare new modules; | |
186 | say, you declare a “garden” module with `mod garden;`. The compiler will look | |
187 | for the module’s code in these places: | |
188 | ||
189 | - Inline, within curly brackets that replace the semicolon following `mod | |
190 | garden` | |
191 | <!-- instead of or after the semicolon? Or is all of this instead of a | |
192 | semicolon? /LC --> | |
193 | <!-- Curly brackets and everything within them instead of the semicolon. | |
194 | I'm not sure a pithy way to make that distinction clearer? /Carol --> | |
195 | <!-- JT, would "Inline, within curly brackets that replace the semicolon | |
196 | following `mod garden` be clearer/accurate? /LC --> | |
197 | <!-- I wonder if we should order it where this cheatsheet happens after | |
198 | we show more examples. Most of the time, you'll use the `mod` keyword to | |
199 | pull files in as you refactor out into separate files. Sometimes you'll use | |
200 | it for those key cases, like grouping tests. Showing those examples and then | |
201 | going into the resolution may be a bit easier. | |
202 | ||
203 | To your question - I think of this as something that could be more of | |
204 | a warning. If you want to use `mod foo`, then be sure you haven't already | |
205 | declared a module called that in the current file. If you do, the compiler | |
206 | will see it first before it looks for a file with that name. /JT --> | |
207 | <!-- I feel pretty strongly that the cheat sheet needs to go first, so that | |
208 | after a reader's first time through the book, when they go back to the | |
209 | modules chapter to try and figure out why their modules aren't working, | |
210 | they get this first rather than having to read through or skip through the | |
211 | examples when they're already frustrated. | |
212 | ||
213 | I also don't feel like the "warning" way of talking about this belongs | |
214 | here. I almost added a section called "common mistakes" or "pitfalls" or | |
215 | "troubleshooting", and I think talking about what you *don't* want to do | |
216 | would belong there... | |
217 | ||
218 | Liz, I'm fine with your suggested wording and I've made that change. /Carol | |
219 | --> | |
220 | ||
5e7ed085 FG |
221 | - In the file *src/garden.rs* |
222 | - In the file *src/garden/mod.rs* | |
923072b8 FG |
223 | - **Declaring submodules**: In any file other than the crate root, you can |
224 | declare submodules. For example, you might declare `mod vegetables;` in | |
225 | *src/garden.rs*. The compiler will look for the submodule’s code within the | |
226 | directory named for the parent module in these places: | |
5e7ed085 FG |
227 | - Inline, directly following `mod vegetables`, within curly brackets instead |
228 | of the semicolon | |
229 | - In the file *src/garden/vegetables.rs* | |
230 | - In the file *src/garden/vegetables/mod.rs* | |
923072b8 FG |
231 | - **Paths to code in modules**: Once a module is part of your crate, you can |
232 | refer to code in that module from anywhere else in that same crate, as long | |
233 | as the privacy rules allow, using the path to the code. For example, an | |
234 | `Asparagus` type in the garden vegetables module would be found at | |
235 | `crate::garden::vegetables::Asparagus`. | |
5e7ed085 FG |
236 | - **Private vs public**: Code within a module is private from its parent |
237 | modules by default. To make a module public, declare it with `pub mod` | |
238 | instead of `mod`. To make items within a public module public as well, use | |
239 | `pub` before their declarations. | |
240 | - **The `use` keyword**: Within a scope, the `use` keyword creates shortcuts to | |
241 | items to reduce repetition of long paths. In any scope that can refer to | |
242 | `crate::garden::vegetables::Asparagus`, you can create a shortcut with `use | |
923072b8 FG |
243 | crate::garden::vegetables::Asparagus;` and from then on you only need to |
244 | write `Asparagus` to make use of that type in the scope. | |
5e7ed085 | 245 | |
923072b8 | 246 | Here we create a binary crate named `backyard` that illustrates these rules. The |
5e7ed085 FG |
247 | crate’s directory, also named `backyard`, contains these files and directories: |
248 | ||
249 | ``` | |
250 | backyard | |
251 | ├── Cargo.lock | |
252 | ├── Cargo.toml | |
253 | └── src | |
254 | ├── garden | |
255 | │ └── vegetables.rs | |
256 | ├── garden.rs | |
257 | └── main.rs | |
258 | ``` | |
259 | ||
923072b8 | 260 | The crate root file in this case is *src/main.rs*, and it contains: |
5e7ed085 FG |
261 | |
262 | Filename: src/main.rs | |
263 | ||
264 | ``` | |
265 | use crate::garden::vegetables::Asparagus; | |
266 | ||
267 | pub mod garden; | |
268 | ||
269 | fn main() { | |
270 | let plant = Asparagus {}; | |
271 | println!("I'm growing {:?}!", plant); | |
272 | } | |
273 | ``` | |
274 | ||
923072b8 | 275 | The `pub mod garden;` line tells the compiler to include the code it finds in |
5e7ed085 FG |
276 | *src/garden.rs*, which is: |
277 | ||
278 | Filename: src/garden.rs | |
279 | ||
280 | ``` | |
281 | pub mod vegetables; | |
282 | ``` | |
283 | ||
923072b8 FG |
284 | Here, `pub mod vegetables;` means the code in *src/garden/vegetables.rs* is |
285 | included too. That code is: | |
5e7ed085 FG |
286 | |
287 | ``` | |
288 | #[derive(Debug)] | |
289 | pub struct Asparagus {} | |
290 | ``` | |
291 | ||
292 | Now let’s get into the details of these rules and demonstrate them in action! | |
293 | ||
294 | ### Grouping Related Code in Modules | |
295 | ||
923072b8 FG |
296 | *Modules* let us organize code within a crate for readability and easy reuse. |
297 | Modules also allow us to control the *privacy* of items, because code within a | |
298 | module is private by default. Private items are internal implementation details | |
299 | not available for outside use. We can choose to make modules and the items | |
300 | within them public, which exposes them to allow external code to use and depend | |
301 | on them. | |
5e7ed085 FG |
302 | |
303 | As an example, let’s write a library crate that provides the functionality of a | |
304 | restaurant. We’ll define the signatures of functions but leave their bodies | |
923072b8 FG |
305 | empty to concentrate on the organization of the code, rather than the |
306 | implementation of a restaurant. | |
5e7ed085 FG |
307 | |
308 | In the restaurant industry, some parts of a restaurant are referred to as | |
309 | *front of house* and others as *back of house*. Front of house is where | |
923072b8 FG |
310 | customers are; this encompasses where the hosts seat customers, servers take |
311 | orders and payment, and bartenders make drinks. Back of house is where the | |
312 | chefs and cooks work in the kitchen, dishwashers clean up, and managers do | |
313 | administrative work. | |
5e7ed085 | 314 | |
923072b8 FG |
315 | To structure our crate in this way, we can organize its functions into nested |
316 | modules. Create a new library named `restaurant` by running `cargo new --lib | |
317 | restaurant`; then enter the code in Listing 7-1 into *src/lib.rs* to define | |
318 | some modules and function signatures. Here’s the front of house section: | |
5e7ed085 FG |
319 | |
320 | Filename: src/lib.rs | |
321 | ||
322 | ``` | |
323 | mod front_of_house { | |
324 | mod hosting { | |
325 | fn add_to_waitlist() {} | |
326 | ||
327 | fn seat_at_table() {} | |
328 | } | |
329 | ||
330 | mod serving { | |
331 | fn take_order() {} | |
332 | ||
333 | fn serve_order() {} | |
334 | ||
335 | fn take_payment() {} | |
336 | } | |
337 | } | |
338 | ``` | |
339 | ||
340 | Listing 7-1: A `front_of_house` module containing other modules that then | |
341 | contain functions | |
342 | ||
923072b8 FG |
343 | We define a module with the `mod` keyword followed by the name of the module |
344 | (in this case, `front_of_house`). The body of the module then goes inside curly | |
345 | brackets. Inside modules, we can place other modules, as in this case with the | |
346 | modules `hosting` and `serving`. Modules can also hold definitions for other | |
347 | items, such as structs, enums, constants, traits, and—as in Listing | |
348 | 7-1—functions. | |
5e7ed085 FG |
349 | |
350 | By using modules, we can group related definitions together and name why | |
923072b8 FG |
351 | they’re related. Programmers using this code can navigate the code based on the |
352 | groups rather than having to read through all the definitions, making it easier | |
353 | to find the definitions relevant to them. Programmers adding new functionality | |
354 | to this code would know where to place the code to keep the program organized. | |
5e7ed085 FG |
355 | |
356 | Earlier, we mentioned that *src/main.rs* and *src/lib.rs* are called crate | |
357 | roots. The reason for their name is that the contents of either of these two | |
358 | files form a module named `crate` at the root of the crate’s module structure, | |
359 | known as the *module tree*. | |
360 | ||
361 | Listing 7-2 shows the module tree for the structure in Listing 7-1. | |
362 | ||
363 | ``` | |
364 | crate | |
365 | └── front_of_house | |
366 | ├── hosting | |
367 | │ ├── add_to_waitlist | |
368 | │ └── seat_at_table | |
369 | └── serving | |
370 | ├── take_order | |
371 | ├── serve_order | |
372 | └── take_payment | |
373 | ``` | |
374 | ||
375 | Listing 7-2: The module tree for the code in Listing 7-1 | |
376 | ||
923072b8 FG |
377 | This tree shows how some of the modules nest inside one another; for example, |
378 | `hosting` nests inside `front_of_house`. The tree also shows that some modules | |
379 | are *siblings* to each other, meaning they’re defined in the same module; | |
380 | `hosting` and `serving` are siblings defined within `front_of_house`. If module | |
381 | A is contained inside module B, we say that module A is the *child* of module B | |
382 | and that module B is the *parent* of module A. Notice that the entire module | |
383 | tree is rooted under the implicit module named `crate`. | |
5e7ed085 FG |
384 | |
385 | The module tree might remind you of the filesystem’s directory tree on your | |
386 | computer; this is a very apt comparison! Just like directories in a filesystem, | |
387 | you use modules to organize your code. And just like files in a directory, we | |
388 | need a way to find our modules. | |
389 | ||
390 | ## Paths for Referring to an Item in the Module Tree | |
391 | ||
392 | To show Rust where to find an item in a module tree, we use a path in the same | |
923072b8 FG |
393 | way we use a path when navigating a filesystem. To call a function, we need to |
394 | know its path. | |
5e7ed085 FG |
395 | |
396 | A path can take two forms: | |
397 | ||
923072b8 FG |
398 | * An *absolute path* is the full path starting from a crate root; for code |
399 | from an external crate, the absolute path begins with the crate name, and for | |
400 | code from the current crate, it starts with the literal `crate`. | |
5e7ed085 FG |
401 | * A *relative path* starts from the current module and uses `self`, `super`, or |
402 | an identifier in the current module. | |
403 | ||
404 | Both absolute and relative paths are followed by one or more identifiers | |
405 | separated by double colons (`::`). | |
406 | ||
923072b8 FG |
407 | Returning to Listing 7-1, say we want to call the `add_to_waitlist` function. |
408 | This is the same as asking: what’s the path of the `add_to_waitlist` function? | |
409 | Listing 7-3 contains Listing 7-1 with some of the modules and functions | |
410 | removed. | |
411 | ||
412 | We’ll show two ways to call the `add_to_waitlist` function from a new function | |
413 | `eat_at_restaurant` defined in the crate root. These paths are correct, but | |
414 | there’s another problem remaining that will prevent this example from compiling | |
415 | as-is. We’ll explain why in a bit. | |
416 | ||
417 | The `eat_at_restaurant` function is part of our library crate’s public API, so | |
418 | we mark it with the `pub` keyword. In the “Exposing Paths with the `pub` | |
419 | Keyword” section, we’ll go into more detail about `pub`. | |
5e7ed085 FG |
420 | |
421 | Filename: src/lib.rs | |
422 | ||
423 | ``` | |
424 | mod front_of_house { | |
425 | mod hosting { | |
426 | fn add_to_waitlist() {} | |
427 | } | |
428 | } | |
429 | ||
430 | pub fn eat_at_restaurant() { | |
431 | // Absolute path | |
432 | crate::front_of_house::hosting::add_to_waitlist(); | |
433 | ||
434 | // Relative path | |
435 | front_of_house::hosting::add_to_waitlist(); | |
436 | } | |
437 | ``` | |
438 | ||
923072b8 FG |
439 | <!-- We should probably let the reader know the above is expected to fail a |
440 | little earlier. /JT --> | |
441 | <!-- I've rearranged a bit /Carol --> | |
442 | ||
5e7ed085 FG |
443 | Listing 7-3: Calling the `add_to_waitlist` function using absolute and relative |
444 | paths | |
445 | ||
446 | The first time we call the `add_to_waitlist` function in `eat_at_restaurant`, | |
447 | we use an absolute path. The `add_to_waitlist` function is defined in the same | |
448 | crate as `eat_at_restaurant`, which means we can use the `crate` keyword to | |
923072b8 FG |
449 | start an absolute path. We then include each of the successive modules until we |
450 | make our way to `add_to_waitlist`. You can imagine a filesystem with the same | |
451 | structure: we’d specify the path `/front_of_house/hosting/add_to_waitlist` to | |
452 | run the `add_to_waitlist` program; using the `crate` name to start from the | |
453 | crate root is like using `/` to start from the filesystem root in your shell. | |
5e7ed085 FG |
454 | |
455 | The second time we call `add_to_waitlist` in `eat_at_restaurant`, we use a | |
456 | relative path. The path starts with `front_of_house`, the name of the module | |
457 | defined at the same level of the module tree as `eat_at_restaurant`. Here the | |
458 | filesystem equivalent would be using the path | |
923072b8 FG |
459 | `front_of_house/hosting/add_to_waitlist`. Starting with a module name means |
460 | that the path is relative. | |
5e7ed085 FG |
461 | |
462 | Choosing whether to use a relative or absolute path is a decision you’ll make | |
923072b8 FG |
463 | based on your project, and depends on whether you’re more likely to move item |
464 | definition code separately from or together with the code that uses the item. | |
465 | For example, if we move the `front_of_house` module and the `eat_at_restaurant` | |
466 | function into a module named `customer_experience`, we’d need to update the | |
467 | absolute path to `add_to_waitlist`, but the relative path would still be valid. | |
468 | However, if we moved the `eat_at_restaurant` function separately into a module | |
469 | named `dining`, the absolute path to the `add_to_waitlist` call would stay the | |
470 | same, but the relative path would need to be updated. | |
471 | ||
472 | Our preference in general is to specify absolute paths because it’s more likely | |
473 | we’ll want to move code definitions and item calls independently of each other. | |
5e7ed085 FG |
474 | |
475 | Let’s try to compile Listing 7-3 and find out why it won’t compile yet! The | |
476 | error we get is shown in Listing 7-4. | |
477 | ||
478 | ``` | |
479 | $ cargo build | |
480 | Compiling restaurant v0.1.0 (file:///projects/restaurant) | |
481 | error[E0603]: module `hosting` is private | |
482 | --> src/lib.rs:9:28 | |
483 | | | |
484 | 9 | crate::front_of_house::hosting::add_to_waitlist(); | |
485 | | ^^^^^^^ private module | |
486 | | | |
487 | note: the module `hosting` is defined here | |
488 | --> src/lib.rs:2:5 | |
489 | | | |
490 | 2 | mod hosting { | |
491 | | ^^^^^^^^^^^ | |
492 | ||
493 | error[E0603]: module `hosting` is private | |
494 | --> src/lib.rs:12:21 | |
495 | | | |
496 | 12 | front_of_house::hosting::add_to_waitlist(); | |
497 | | ^^^^^^^ private module | |
498 | | | |
499 | note: the module `hosting` is defined here | |
500 | --> src/lib.rs:2:5 | |
501 | | | |
502 | 2 | mod hosting { | |
503 | | ^^^^^^^^^^^ | |
504 | ``` | |
505 | ||
506 | Listing 7-4: Compiler errors from building the code in Listing 7-3 | |
507 | ||
508 | The error messages say that module `hosting` is private. In other words, we | |
509 | have the correct paths for the `hosting` module and the `add_to_waitlist` | |
510 | function, but Rust won’t let us use them because it doesn’t have access to the | |
923072b8 FG |
511 | private sections. In Rust, all items (functions, methods, structs, enums, |
512 | modules, and constants) are private to parent modules by default. If you want | |
513 | to make an item like a function or struct private, you put it in a module. | |
514 | ||
515 | Items in a parent module can’t use the private items inside child modules, but | |
516 | items in child modules can use the items in their ancestor modules. This is | |
517 | because child modules wrap and hide their implementation details, but the child | |
518 | modules can see the context in which they’re defined. To continue with our | |
519 | metaphor, think of the privacy rules as being like the back office of a | |
520 | restaurant: what goes on in there is private to restaurant customers, but | |
521 | office managers can see and do everything in the restaurant they operate. | |
5e7ed085 FG |
522 | |
523 | Rust chose to have the module system function this way so that hiding inner | |
524 | implementation details is the default. That way, you know which parts of the | |
923072b8 FG |
525 | inner code you can change without breaking outer code. However, Rust does give |
526 | you the option to expose inner parts of child modules’ code to outer ancestor | |
527 | modules by using the `pub` keyword to make an item public. | |
5e7ed085 FG |
528 | |
529 | ### Exposing Paths with the `pub` Keyword | |
530 | ||
531 | Let’s return to the error in Listing 7-4 that told us the `hosting` module is | |
532 | private. We want the `eat_at_restaurant` function in the parent module to have | |
533 | access to the `add_to_waitlist` function in the child module, so we mark the | |
534 | `hosting` module with the `pub` keyword, as shown in Listing 7-5. | |
535 | ||
536 | Filename: src/lib.rs | |
537 | ||
538 | ``` | |
539 | mod front_of_house { | |
540 | pub mod hosting { | |
541 | fn add_to_waitlist() {} | |
542 | } | |
543 | } | |
544 | ||
545 | pub fn eat_at_restaurant() { | |
546 | // Absolute path | |
547 | crate::front_of_house::hosting::add_to_waitlist(); | |
548 | ||
549 | // Relative path | |
550 | front_of_house::hosting::add_to_waitlist(); | |
551 | } | |
552 | ``` | |
553 | ||
554 | Listing 7-5: Declaring the `hosting` module as `pub` to use it from | |
555 | `eat_at_restaurant` | |
556 | ||
557 | Unfortunately, the code in Listing 7-5 still results in an error, as shown in | |
558 | Listing 7-6. | |
559 | ||
560 | ``` | |
561 | $ cargo build | |
562 | Compiling restaurant v0.1.0 (file:///projects/restaurant) | |
563 | error[E0603]: function `add_to_waitlist` is private | |
564 | --> src/lib.rs:9:37 | |
565 | | | |
566 | 9 | crate::front_of_house::hosting::add_to_waitlist(); | |
567 | | ^^^^^^^^^^^^^^^ private function | |
568 | | | |
569 | note: the function `add_to_waitlist` is defined here | |
570 | --> src/lib.rs:3:9 | |
571 | | | |
572 | 3 | fn add_to_waitlist() {} | |
573 | | ^^^^^^^^^^^^^^^^^^^^ | |
574 | ||
575 | error[E0603]: function `add_to_waitlist` is private | |
576 | --> src/lib.rs:12:30 | |
577 | | | |
578 | 12 | front_of_house::hosting::add_to_waitlist(); | |
579 | | ^^^^^^^^^^^^^^^ private function | |
580 | | | |
581 | note: the function `add_to_waitlist` is defined here | |
582 | --> src/lib.rs:3:9 | |
583 | | | |
584 | 3 | fn add_to_waitlist() {} | |
585 | | ^^^^^^^^^^^^^^^^^^^^ | |
586 | ``` | |
587 | ||
588 | Listing 7-6: Compiler errors from building the code in Listing 7-5 | |
589 | ||
590 | What happened? Adding the `pub` keyword in front of `mod hosting` makes the | |
591 | module public. With this change, if we can access `front_of_house`, we can | |
592 | access `hosting`. But the *contents* of `hosting` are still private; making the | |
593 | module public doesn’t make its contents public. The `pub` keyword on a module | |
923072b8 FG |
594 | only lets code in its ancestor modules refer to it, not access its inner code. |
595 | Because modules are containers, there’s not much we can do by only making the | |
596 | module public; we need to go further and choose to make one or more of the | |
597 | items within the module public as well. | |
5e7ed085 FG |
598 | |
599 | The errors in Listing 7-6 say that the `add_to_waitlist` function is private. | |
600 | The privacy rules apply to structs, enums, functions, and methods as well as | |
601 | modules. | |
602 | ||
603 | Let’s also make the `add_to_waitlist` function public by adding the `pub` | |
604 | keyword before its definition, as in Listing 7-7. | |
605 | ||
606 | Filename: src/lib.rs | |
607 | ||
608 | ``` | |
609 | mod front_of_house { | |
610 | pub mod hosting { | |
611 | pub fn add_to_waitlist() {} | |
612 | } | |
613 | } | |
614 | ||
615 | pub fn eat_at_restaurant() { | |
616 | // Absolute path | |
617 | crate::front_of_house::hosting::add_to_waitlist(); | |
618 | ||
619 | // Relative path | |
620 | front_of_house::hosting::add_to_waitlist(); | |
621 | } | |
622 | ``` | |
623 | ||
624 | Listing 7-7: Adding the `pub` keyword to `mod hosting` and `fn add_to_waitlist` | |
625 | lets us call the function from `eat_at_restaurant` | |
626 | ||
923072b8 FG |
627 | Now the code will compile! To see why adding the `pub` keyword lets us use |
628 | these paths in `add_to_waitlist` with respect to the privacy rules, let’s look | |
629 | at the absolute and the relative paths. | |
5e7ed085 FG |
630 | |
631 | In the absolute path, we start with `crate`, the root of our crate’s module | |
923072b8 FG |
632 | tree. The `front_of_house` module is defined in the crate root. While |
633 | `front_of_house` isn’t public, because the `eat_at_restaurant` function is | |
634 | defined in the same module as `front_of_house` (that is, `eat_at_restaurant` | |
635 | and `front_of_house` are siblings), we can refer to `front_of_house` from | |
636 | `eat_at_restaurant`. Next is the `hosting` module marked with `pub`. We can | |
637 | access the parent module of `hosting`, so we can access `hosting`. Finally, the | |
638 | `add_to_waitlist` function is marked with `pub` and we can access its parent | |
639 | module, so this function call works! | |
5e7ed085 FG |
640 | |
641 | In the relative path, the logic is the same as the absolute path except for the | |
642 | first step: rather than starting from the crate root, the path starts from | |
643 | `front_of_house`. The `front_of_house` module is defined within the same module | |
644 | as `eat_at_restaurant`, so the relative path starting from the module in which | |
645 | `eat_at_restaurant` is defined works. Then, because `hosting` and | |
646 | `add_to_waitlist` are marked with `pub`, the rest of the path works, and this | |
647 | function call is valid! | |
648 | ||
649 | If you plan on sharing your library crate so other projects can use your code, | |
923072b8 FG |
650 | your public API is your contract with users of your crate that determines how |
651 | they can interact with your code. There are many considerations around managing | |
652 | changes to your public API to make it easier for people to depend on your | |
653 | crate. These considerations are out of the scope of this book; if you’re | |
654 | interested in this topic, see The Rust API Guidelines at | |
5e7ed085 FG |
655 | *https://rust-lang.github.io/api-guidelines/*. |
656 | ||
5e7ed085 FG |
657 | |
658 | > #### Best Practices for Packages with a Binary and a Library | |
659 | > | |
660 | > We mentioned a package can contain both a *src/main.rs* binary crate root as | |
661 | > well as a *src/lib.rs* library crate root, and both crates will have the | |
923072b8 FG |
662 | > package name by default. Typically, packages with this pattern of containing |
663 | > both a library and a binary crate will have just | |
5e7ed085 FG |
664 | > enough code in the binary crate to start an executable that calls code with |
665 | > the library crate. This lets other projects benefit from the most | |
666 | > functionality that the package provides, because the library crate’s code can | |
667 | > be shared. | |
668 | > | |
669 | > The module tree should be defined in *src/lib.rs*. Then, any public items can | |
670 | > be used in the binary crate by starting paths with the name of the package. | |
671 | > The binary crate becomes a user of the library crate just like a completely | |
672 | > external crate would use the library crate: it can only use the public API. | |
673 | > This helps you design a good API; not only are you the author, you’re also a | |
674 | > client! | |
675 | > | |
676 | > In Chapter 12, we’ll demonstrate this organizational practice with a | |
677 | > command-line program that will contain both a binary crate and a library | |
678 | > crate. | |
679 | ||
680 | ### Starting Relative Paths with `super` | |
681 | ||
923072b8 FG |
682 | We can construct relative paths that begin in the parent module, rather than |
683 | the current module or the crate root, by using `super` at the start of the | |
684 | path. This is like starting a filesystem path with the `..` syntax. Using | |
685 | `super` allows us to reference an item that we know is in the parent module, | |
686 | which can make rearranging the module tree easier when the module is closely | |
687 | related to the parent, but the parent might be moved elsewhere in the module | |
688 | tree someday. | |
5e7ed085 FG |
689 | |
690 | Consider the code in Listing 7-8 that models the situation in which a chef | |
691 | fixes an incorrect order and personally brings it out to the customer. The | |
692 | function `fix_incorrect_order` defined in the `back_of_house` module calls the | |
693 | function `deliver_order` defined in the parent module by specifying the path to | |
694 | `deliver_order` starting with `super`: | |
695 | ||
696 | Filename: src/lib.rs | |
697 | ||
698 | ``` | |
699 | fn deliver_order() {} | |
700 | ||
701 | mod back_of_house { | |
702 | fn fix_incorrect_order() { | |
703 | cook_order(); | |
704 | super::deliver_order(); | |
705 | } | |
706 | ||
707 | fn cook_order() {} | |
708 | } | |
709 | ``` | |
710 | ||
711 | Listing 7-8: Calling a function using a relative path starting with `super` | |
712 | ||
713 | The `fix_incorrect_order` function is in the `back_of_house` module, so we can | |
714 | use `super` to go to the parent module of `back_of_house`, which in this case | |
715 | is `crate`, the root. From there, we look for `deliver_order` and find it. | |
716 | Success! We think the `back_of_house` module and the `deliver_order` function | |
717 | are likely to stay in the same relationship to each other and get moved | |
718 | together should we decide to reorganize the crate’s module tree. Therefore, we | |
719 | used `super` so we’ll have fewer places to update code in the future if this | |
720 | code gets moved to a different module. | |
721 | ||
722 | ### Making Structs and Enums Public | |
723 | ||
724 | We can also use `pub` to designate structs and enums as public, but there are a | |
923072b8 FG |
725 | few details extra to the usage of `pub` with structs and enums. If we use `pub` |
726 | before a struct definition, we make the struct public, but the struct’s fields | |
727 | will still be private. We can make each field public or not on a case-by-case | |
728 | basis. In Listing 7-9, we’ve defined a public `back_of_house::Breakfast` struct | |
729 | with a public `toast` field but a private `seasonal_fruit` field. This models | |
730 | the case in a restaurant where the customer can pick the type of bread that | |
731 | comes with a meal, but the chef decides which fruit accompanies the meal based | |
732 | on what’s in season and in stock. The available fruit changes quickly, so | |
733 | customers can’t choose the fruit or even see which fruit they’ll get. | |
5e7ed085 FG |
734 | |
735 | Filename: src/lib.rs | |
736 | ||
737 | ``` | |
738 | mod back_of_house { | |
739 | pub struct Breakfast { | |
740 | pub toast: String, | |
741 | seasonal_fruit: String, | |
742 | } | |
743 | ||
744 | impl Breakfast { | |
745 | pub fn summer(toast: &str) -> Breakfast { | |
746 | Breakfast { | |
747 | toast: String::from(toast), | |
748 | seasonal_fruit: String::from("peaches"), | |
749 | } | |
750 | } | |
751 | } | |
752 | } | |
753 | ||
754 | pub fn eat_at_restaurant() { | |
755 | // Order a breakfast in the summer with Rye toast | |
756 | let mut meal = back_of_house::Breakfast::summer("Rye"); | |
757 | // Change our mind about what bread we'd like | |
758 | meal.toast = String::from("Wheat"); | |
759 | println!("I'd like {} toast please", meal.toast); | |
760 | ||
761 | // The next line won't compile if we uncomment it; we're not allowed | |
762 | // to see or modify the seasonal fruit that comes with the meal | |
763 | // meal.seasonal_fruit = String::from("blueberries"); | |
764 | } | |
765 | ``` | |
766 | ||
767 | Listing 7-9: A struct with some public fields and some private fields | |
768 | ||
769 | Because the `toast` field in the `back_of_house::Breakfast` struct is public, | |
770 | in `eat_at_restaurant` we can write and read to the `toast` field using dot | |
771 | notation. Notice that we can’t use the `seasonal_fruit` field in | |
772 | `eat_at_restaurant` because `seasonal_fruit` is private. Try uncommenting the | |
773 | line modifying the `seasonal_fruit` field value to see what error you get! | |
774 | ||
775 | Also, note that because `back_of_house::Breakfast` has a private field, the | |
776 | struct needs to provide a public associated function that constructs an | |
777 | instance of `Breakfast` (we’ve named it `summer` here). If `Breakfast` didn’t | |
778 | have such a function, we couldn’t create an instance of `Breakfast` in | |
779 | `eat_at_restaurant` because we couldn’t set the value of the private | |
780 | `seasonal_fruit` field in `eat_at_restaurant`. | |
781 | ||
782 | In contrast, if we make an enum public, all of its variants are then public. We | |
783 | only need the `pub` before the `enum` keyword, as shown in Listing 7-10. | |
784 | ||
785 | Filename: src/lib.rs | |
786 | ||
787 | ``` | |
788 | mod back_of_house { | |
789 | pub enum Appetizer { | |
790 | Soup, | |
791 | Salad, | |
792 | } | |
793 | } | |
794 | ||
795 | pub fn eat_at_restaurant() { | |
796 | let order1 = back_of_house::Appetizer::Soup; | |
797 | let order2 = back_of_house::Appetizer::Salad; | |
798 | } | |
799 | ``` | |
800 | ||
801 | Listing 7-10: Designating an enum as public makes all its variants public | |
802 | ||
803 | Because we made the `Appetizer` enum public, we can use the `Soup` and `Salad` | |
923072b8 FG |
804 | variants in `eat_at_restaurant`. |
805 | ||
806 | Enums aren’t very useful unless their variants are public; it would be annoying | |
807 | to have to annotate all enum variants with `pub` in every case, so the default | |
808 | for enum variants is to be public. Structs are often useful without their | |
809 | fields being public, so struct fields follow the general rule of everything | |
810 | being private by default unless annotated with `pub`. | |
5e7ed085 FG |
811 | |
812 | There’s one more situation involving `pub` that we haven’t covered, and that is | |
813 | our last module system feature: the `use` keyword. We’ll cover `use` by itself | |
814 | first, and then we’ll show how to combine `pub` and `use`. | |
815 | ||
816 | ## Bringing Paths into Scope with the `use` Keyword | |
817 | ||
923072b8 FG |
818 | Having to write out the paths to call functions can feel inconvenient and |
819 | repetitive. In Listing 7-7, whether we chose the absolute or relative path to | |
820 | the `add_to_waitlist` function, every time we wanted to call `add_to_waitlist` | |
821 | we had to specify `front_of_house` and `hosting` too. Fortunately, there’s a | |
822 | way to simplify this process: we can create a shortcut to a path with the `use` | |
823 | keyword once, and then use the shorter name everywhere else in the scope. | |
5e7ed085 FG |
824 | |
825 | In Listing 7-11, we bring the `crate::front_of_house::hosting` module into the | |
826 | scope of the `eat_at_restaurant` function so we only have to specify | |
827 | `hosting::add_to_waitlist` to call the `add_to_waitlist` function in | |
828 | `eat_at_restaurant`. | |
829 | ||
830 | Filename: src/lib.rs | |
831 | ||
832 | ``` | |
833 | mod front_of_house { | |
834 | pub mod hosting { | |
835 | pub fn add_to_waitlist() {} | |
836 | } | |
837 | } | |
838 | ||
839 | use crate::front_of_house::hosting; | |
840 | ||
841 | pub fn eat_at_restaurant() { | |
842 | hosting::add_to_waitlist(); | |
843 | } | |
844 | ``` | |
845 | ||
846 | Listing 7-11: Bringing a module into scope with `use` | |
847 | ||
848 | Adding `use` and a path in a scope is similar to creating a symbolic link in | |
849 | the filesystem. By adding `use crate::front_of_house::hosting` in the crate | |
850 | root, `hosting` is now a valid name in that scope, just as though the `hosting` | |
851 | module had been defined in the crate root. Paths brought into scope with `use` | |
852 | also check privacy, like any other paths. | |
853 | ||
5e7ed085 FG |
854 | Note that `use` only creates the shortcut for the particular scope in which the |
855 | `use` occurs. Listing 7-12 moves the `eat_at_restaurant` function into a new | |
856 | child module named `customer`, which is then a different scope than the `use` | |
923072b8 | 857 | statement, so the function body won’t compile: |
5e7ed085 FG |
858 | |
859 | Filename: src/lib.rs | |
860 | ||
861 | ``` | |
862 | mod front_of_house { | |
863 | pub mod hosting { | |
864 | pub fn add_to_waitlist() {} | |
865 | } | |
866 | } | |
867 | ||
868 | use crate::front_of_house::hosting; | |
869 | ||
870 | mod customer { | |
871 | pub fn eat_at_restaurant() { | |
872 | hosting::add_to_waitlist(); | |
873 | } | |
874 | } | |
875 | ``` | |
876 | ||
877 | Listing 7-12: A `use` statement only applies in the scope it’s in | |
878 | ||
879 | The compiler error shows that the shortcut no longer applies within the | |
880 | `customer` module: | |
881 | ||
882 | ``` | |
883 | error[E0433]: failed to resolve: use of undeclared crate or module `hosting` | |
884 | --> src/lib.rs:11:9 | |
885 | | | |
886 | 11 | hosting::add_to_waitlist(); | |
887 | | ^^^^^^^ use of undeclared crate or module `hosting` | |
888 | ||
889 | warning: unused import: `crate::front_of_house::hosting` | |
890 | --> src/lib.rs:7:5 | |
891 | | | |
892 | 7 | use crate::front_of_house::hosting; | |
893 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
894 | | | |
895 | = note: `#[warn(unused_imports)]` on by default | |
896 | ``` | |
897 | ||
898 | Notice there’s also a warning that the `use` is no longer used in its scope! To | |
899 | fix this problem, move the `use` within the `customer` module too, or reference | |
900 | the shortcut in the parent module with `super::hosting` within the child | |
901 | `customer` module. | |
902 | ||
903 | ### Creating Idiomatic `use` Paths | |
904 | ||
905 | In Listing 7-11, you might have wondered why we specified `use | |
906 | crate::front_of_house::hosting` and then called `hosting::add_to_waitlist` in | |
907 | `eat_at_restaurant` rather than specifying the `use` path all the way out to | |
908 | the `add_to_waitlist` function to achieve the same result, as in Listing 7-13. | |
909 | ||
910 | Filename: src/lib.rs | |
911 | ||
912 | ``` | |
913 | mod front_of_house { | |
914 | pub mod hosting { | |
915 | pub fn add_to_waitlist() {} | |
916 | } | |
917 | } | |
918 | ||
919 | use crate::front_of_house::hosting::add_to_waitlist; | |
920 | ||
921 | pub fn eat_at_restaurant() { | |
922 | add_to_waitlist(); | |
923 | } | |
924 | ``` | |
925 | ||
926 | Listing 7-13: Bringing the `add_to_waitlist` function into scope with `use`, | |
927 | which is unidiomatic | |
928 | ||
929 | Although both Listing 7-11 and 7-13 accomplish the same task, Listing 7-11 is | |
930 | the idiomatic way to bring a function into scope with `use`. Bringing the | |
931 | function’s parent module into scope with `use` means we have to specify the | |
932 | parent module when calling the function. Specifying the parent module when | |
933 | calling the function makes it clear that the function isn’t locally defined | |
934 | while still minimizing repetition of the full path. The code in Listing 7-13 is | |
935 | unclear as to where `add_to_waitlist` is defined. | |
936 | ||
937 | On the other hand, when bringing in structs, enums, and other items with `use`, | |
938 | it’s idiomatic to specify the full path. Listing 7-14 shows the idiomatic way | |
939 | to bring the standard library’s `HashMap` struct into the scope of a binary | |
940 | crate. | |
941 | ||
942 | Filename: src/main.rs | |
943 | ||
944 | ``` | |
945 | use std::collections::HashMap; | |
946 | ||
947 | fn main() { | |
948 | let mut map = HashMap::new(); | |
949 | map.insert(1, 2); | |
950 | } | |
951 | ``` | |
952 | ||
953 | Listing 7-14: Bringing `HashMap` into scope in an idiomatic way | |
954 | ||
955 | There’s no strong reason behind this idiom: it’s just the convention that has | |
956 | emerged, and folks have gotten used to reading and writing Rust code this way. | |
957 | ||
958 | The exception to this idiom is if we’re bringing two items with the same name | |
959 | into scope with `use` statements, because Rust doesn’t allow that. Listing 7-15 | |
960 | shows how to bring two `Result` types into scope that have the same name but | |
961 | different parent modules and how to refer to them. | |
962 | ||
963 | Filename: src/lib.rs | |
964 | ||
965 | ``` | |
966 | use std::fmt; | |
967 | use std::io; | |
968 | ||
969 | fn function1() -> fmt::Result { | |
970 | // --snip-- | |
971 | } | |
972 | ||
973 | fn function2() -> io::Result<()> { | |
974 | // --snip-- | |
975 | } | |
976 | ``` | |
977 | ||
978 | Listing 7-15: Bringing two types with the same name into the same scope | |
979 | requires using their parent modules. | |
980 | ||
981 | As you can see, using the parent modules distinguishes the two `Result` types. | |
982 | If instead we specified `use std::fmt::Result` and `use std::io::Result`, we’d | |
983 | have two `Result` types in the same scope and Rust wouldn’t know which one we | |
984 | meant when we used `Result`. | |
985 | ||
986 | ### Providing New Names with the `as` Keyword | |
987 | ||
988 | There’s another solution to the problem of bringing two types of the same name | |
989 | into the same scope with `use`: after the path, we can specify `as` and a new | |
923072b8 FG |
990 | local name, or *alias*, for the type. Listing 7-16 shows another way to write |
991 | the code in Listing 7-15 by renaming one of the two `Result` types using `as`. | |
5e7ed085 FG |
992 | |
993 | Filename: src/lib.rs | |
994 | ||
995 | ``` | |
996 | use std::fmt::Result; | |
997 | use std::io::Result as IoResult; | |
998 | ||
999 | fn function1() -> Result { | |
1000 | // --snip-- | |
1001 | } | |
1002 | ||
1003 | fn function2() -> IoResult<()> { | |
1004 | // --snip-- | |
1005 | } | |
1006 | ``` | |
1007 | ||
1008 | Listing 7-16: Renaming a type when it’s brought into scope with the `as` keyword | |
1009 | ||
1010 | In the second `use` statement, we chose the new name `IoResult` for the | |
1011 | `std::io::Result` type, which won’t conflict with the `Result` from `std::fmt` | |
1012 | that we’ve also brought into scope. Listing 7-15 and Listing 7-16 are | |
1013 | considered idiomatic, so the choice is up to you! | |
1014 | ||
1015 | ### Re-exporting Names with `pub use` | |
1016 | ||
1017 | When we bring a name into scope with the `use` keyword, the name available in | |
1018 | the new scope is private. To enable the code that calls our code to refer to | |
1019 | that name as if it had been defined in that code’s scope, we can combine `pub` | |
1020 | and `use`. This technique is called *re-exporting* because we’re bringing | |
1021 | an item into scope but also making that item available for others to bring into | |
1022 | their scope. | |
1023 | ||
1024 | Listing 7-17 shows the code in Listing 7-11 with `use` in the root module | |
1025 | changed to `pub use`. | |
1026 | ||
1027 | Filename: src/lib.rs | |
1028 | ||
1029 | ``` | |
1030 | mod front_of_house { | |
1031 | pub mod hosting { | |
1032 | pub fn add_to_waitlist() {} | |
1033 | } | |
1034 | } | |
1035 | ||
1036 | pub use crate::front_of_house::hosting; | |
1037 | ||
1038 | pub fn eat_at_restaurant() { | |
1039 | hosting::add_to_waitlist(); | |
1040 | } | |
1041 | ``` | |
1042 | ||
1043 | Listing 7-17: Making a name available for any code to use from a new scope with | |
1044 | `pub use` | |
1045 | ||
1046 | Before this change, external code would have to call the `add_to_waitlist` | |
1047 | function by using the path | |
1048 | `restaurant::front_of_house::hosting::add_to_waitlist()`. Now that this `pub | |
1049 | use` has re-exported the `hosting` module from the root module, external code | |
1050 | can now use the path `restaurant::hosting::add_to_waitlist()` instead. | |
1051 | ||
1052 | Re-exporting is useful when the internal structure of your code is different | |
1053 | from how programmers calling your code would think about the domain. For | |
1054 | example, in this restaurant metaphor, the people running the restaurant think | |
1055 | about “front of house” and “back of house.” But customers visiting a restaurant | |
1056 | probably won’t think about the parts of the restaurant in those terms. With | |
1057 | `pub use`, we can write our code with one structure but expose a different | |
1058 | structure. Doing so makes our library well organized for programmers working on | |
1059 | the library and programmers calling the library. We’ll look at another example | |
1060 | of `pub use` and how it affects your crate’s documentation in the “Exporting a | |
1061 | Convenient Public API with `pub use`” section of Chapter 14. | |
1062 | ||
1063 | ### Using External Packages | |
1064 | ||
1065 | In Chapter 2, we programmed a guessing game project that used an external | |
1066 | package called `rand` to get random numbers. To use `rand` in our project, we | |
1067 | added this line to *Cargo.toml*: | |
1068 | ||
1069 | Filename: Cargo.toml | |
1070 | ||
1071 | ``` | |
1072 | rand = "0.8.3" | |
1073 | ``` | |
1074 | ||
1075 | Adding `rand` as a dependency in *Cargo.toml* tells Cargo to download the | |
1076 | `rand` package and any dependencies from *https://crates.io/* and make `rand` | |
1077 | available to our project. | |
1078 | ||
1079 | Then, to bring `rand` definitions into the scope of our package, we added a | |
1080 | `use` line starting with the name of the crate, `rand`, and listed the items we | |
1081 | wanted to bring into scope. Recall that in the “Generating a Random Number” | |
1082 | section in Chapter 2, we brought the `Rng` trait into scope and called the | |
1083 | `rand::thread_rng` function: | |
1084 | ||
1085 | ``` | |
1086 | use rand::Rng; | |
1087 | ||
1088 | fn main() { | |
1089 | let secret_number = rand::thread_rng().gen_range(1..101); | |
1090 | } | |
1091 | ``` | |
1092 | ||
1093 | Members of the Rust community have made many packages available at | |
1094 | *https://crates.io/*, and pulling any of them into your package involves these | |
1095 | same steps: listing them in your package’s *Cargo.toml* file and using `use` to | |
1096 | bring items from their crates into scope. | |
1097 | ||
923072b8 | 1098 | Note that the standard `std` library is also a crate that’s external to our |
5e7ed085 FG |
1099 | package. Because the standard library is shipped with the Rust language, we |
1100 | don’t need to change *Cargo.toml* to include `std`. But we do need to refer to | |
1101 | it with `use` to bring items from there into our package’s scope. For example, | |
1102 | with `HashMap` we would use this line: | |
1103 | ||
1104 | ``` | |
1105 | use std::collections::HashMap; | |
1106 | ``` | |
1107 | ||
1108 | This is an absolute path starting with `std`, the name of the standard library | |
1109 | crate. | |
1110 | ||
1111 | ### Using Nested Paths to Clean Up Large `use` Lists | |
1112 | ||
1113 | If we’re using multiple items defined in the same crate or same module, | |
1114 | listing each item on its own line can take up a lot of vertical space in our | |
1115 | files. For example, these two `use` statements we had in the Guessing Game in | |
1116 | Listing 2-4 bring items from `std` into scope: | |
1117 | ||
1118 | Filename: src/main.rs | |
1119 | ||
1120 | ``` | |
1121 | // --snip-- | |
1122 | use std::cmp::Ordering; | |
1123 | use std::io; | |
1124 | // --snip-- | |
1125 | ``` | |
1126 | ||
1127 | Instead, we can use nested paths to bring the same items into scope in one | |
1128 | line. We do this by specifying the common part of the path, followed by two | |
1129 | colons, and then curly brackets around a list of the parts of the paths that | |
1130 | differ, as shown in Listing 7-18. | |
1131 | ||
1132 | Filename: src/main.rs | |
1133 | ||
1134 | ``` | |
1135 | // --snip-- | |
1136 | use std::{cmp::Ordering, io}; | |
1137 | // --snip-- | |
1138 | ``` | |
1139 | ||
1140 | Listing 7-18: Specifying a nested path to bring multiple items with the same | |
1141 | prefix into scope | |
1142 | ||
1143 | In bigger programs, bringing many items into scope from the same crate or | |
1144 | module using nested paths can reduce the number of separate `use` statements | |
1145 | needed by a lot! | |
1146 | ||
1147 | We can use a nested path at any level in a path, which is useful when combining | |
1148 | two `use` statements that share a subpath. For example, Listing 7-19 shows two | |
1149 | `use` statements: one that brings `std::io` into scope and one that brings | |
1150 | `std::io::Write` into scope. | |
1151 | ||
1152 | Filename: src/lib.rs | |
1153 | ||
1154 | ``` | |
1155 | use std::io; | |
1156 | use std::io::Write; | |
1157 | ``` | |
1158 | ||
1159 | Listing 7-19: Two `use` statements where one is a subpath of the other | |
1160 | ||
1161 | The common part of these two paths is `std::io`, and that’s the complete first | |
1162 | path. To merge these two paths into one `use` statement, we can use `self` in | |
1163 | the nested path, as shown in Listing 7-20. | |
1164 | ||
1165 | Filename: src/lib.rs | |
1166 | ||
1167 | ``` | |
1168 | use std::io::{self, Write}; | |
1169 | ``` | |
1170 | ||
1171 | Listing 7-20: Combining the paths in Listing 7-19 into one `use` statement | |
1172 | ||
1173 | This line brings `std::io` and `std::io::Write` into scope. | |
1174 | ||
1175 | ### The Glob Operator | |
1176 | ||
1177 | If we want to bring *all* public items defined in a path into scope, we can | |
923072b8 | 1178 | specify that path followed by the `*` glob operator: |
5e7ed085 FG |
1179 | |
1180 | ``` | |
1181 | use std::collections::*; | |
1182 | ``` | |
1183 | ||
1184 | This `use` statement brings all public items defined in `std::collections` into | |
1185 | the current scope. Be careful when using the glob operator! Glob can make it | |
1186 | harder to tell what names are in scope and where a name used in your program | |
1187 | was defined. | |
1188 | ||
1189 | The glob operator is often used when testing to bring everything under test | |
1190 | into the `tests` module; we’ll talk about that in the “How to Write Tests” | |
1191 | section in Chapter 11. The glob operator is also sometimes used as part of the | |
1192 | prelude pattern: see the standard library documentation for more information on | |
1193 | that pattern. | |
1194 | ||
1195 | ## Separating Modules into Different Files | |
1196 | ||
1197 | So far, all the examples in this chapter defined multiple modules in one file. | |
1198 | When modules get large, you might want to move their definitions to a separate | |
1199 | file to make the code easier to navigate. | |
1200 | ||
923072b8 FG |
1201 | For example, let’s start from the code in Listing 7-17 that had multiple |
1202 | restaurant modules. We’ll extract modules into files instead of having all the | |
1203 | modules defined in the crate root file. In this case, the crate root file is | |
1204 | *src/lib.rs*, but this procedure also works with binary crates whose crate root | |
1205 | file is *src/main.rs*. | |
5e7ed085 FG |
1206 | |
1207 | First, we’ll extract the `front_of_house` module to its own file. Remove the | |
1208 | code inside the curly brackets for the `front_of_house` module, leaving only | |
1209 | the `mod front_of_house;` declaration, so that *src/lib.rs* contains the code | |
1210 | shown in Listing 7-21. Note that this won’t compile until we create the | |
1211 | *src/front_of_house.rs* file in Listing 7-22. | |
1212 | ||
1213 | Filename: src/lib.rs | |
1214 | ||
1215 | ``` | |
1216 | mod front_of_house; | |
1217 | ||
1218 | pub use crate::front_of_house::hosting; | |
1219 | ||
1220 | pub fn eat_at_restaurant() { | |
1221 | hosting::add_to_waitlist(); | |
1222 | } | |
1223 | ``` | |
1224 | ||
1225 | Listing 7-21: Declaring the `front_of_house` module whose body will be in | |
1226 | *src/front_of_house.rs* | |
1227 | ||
1228 | Next, place the code that was in the curly brackets into a new file named | |
1229 | *src/front_of_house.rs*, as shown in Listing 7-22. The compiler knows to look | |
923072b8 FG |
1230 | in this file because it came across the module declaration in the crate root |
1231 | with the name `front_of_house`. | |
5e7ed085 FG |
1232 | |
1233 | Filename: src/front_of_house.rs | |
1234 | ||
1235 | ``` | |
1236 | pub mod hosting { | |
1237 | pub fn add_to_waitlist() {} | |
1238 | } | |
1239 | ``` | |
1240 | ||
1241 | Listing 7-22: Definitions inside the `front_of_house` module in | |
1242 | *src/front_of_house.rs* | |
1243 | ||
923072b8 FG |
1244 | Note that you only need to load a file using a `mod` declaration *once* in your |
1245 | module tree. Once the compiler knows the file is part of the project (and knows | |
1246 | where in the module tree the code resides because of where you’ve put the `mod` | |
1247 | statement), other files in your project should refer to the loaded file’s code | |
1248 | using a path to where it was declared, as covered in the “Paths for Referring | |
1249 | to an Item in the Module Tree” section. In other words, `mod` is *not* an | |
1250 | “include” operation that you may have seen in other programming languages. | |
1251 | ||
1252 | Next, we’ll extract the `hosting` module to its own file. The process | |
5e7ed085 | 1253 | is a bit different because `hosting` is a child module of `front_of_house`, not |
923072b8 FG |
1254 | of the root module. We’ll place the file for `hosting` in a new directory that |
1255 | will be named for its ancestors in the module tree, in this case | |
1256 | *src/front_of_house/*. | |
5e7ed085 FG |
1257 | |
1258 | To start moving `hosting`, we change *src/front_of_house.rs* to contain only the | |
1259 | declaration of the `hosting` module: | |
1260 | ||
1261 | Filename: src/front_of_house.rs | |
1262 | ||
1263 | ``` | |
1264 | pub mod hosting; | |
1265 | ``` | |
1266 | ||
923072b8 FG |
1267 | Then we create a *src/front_of_house* directory and a file *hosting.rs* to |
1268 | contain the definitions made in the `hosting` module: | |
5e7ed085 FG |
1269 | |
1270 | Filename: src/front_of_house/hosting.rs | |
1271 | ||
1272 | ``` | |
1273 | pub fn add_to_waitlist() {} | |
1274 | ``` | |
1275 | ||
1276 | If we instead put *hosting.rs* in the *src* directory, the compiler would | |
923072b8 FG |
1277 | expect the *hosting.rs* code to be in a `hosting` module declared in the crate |
1278 | root, and not delcared as a child of the `front_of_house` module. The | |
1279 | compiler’s rules for which files to check for which modules’ code means the | |
1280 | directories and files more closely match the module tree. | |
5e7ed085 | 1281 | |
5e7ed085 FG |
1282 | |
1283 | > ### Alternate File Paths | |
1284 | > | |
923072b8 FG |
1285 | > So far we’ve covered the most idiomatic file paths the Rust compiler uses, |
1286 | > but Rust also supports an older style of file path. For a module named | |
1287 | > `front_of_house` declared in the crate root, the compiler will look for the | |
1288 | > module’s code in: | |
5e7ed085 FG |
1289 | > |
1290 | > * *src/front_of_house.rs* (what we covered) | |
923072b8 | 1291 | > * *src/front_of_house/mod.rs* (older style, still supported path) |
5e7ed085 FG |
1292 | > |
1293 | > For a module named `hosting` that is a submodule of `front_of_house`, the | |
1294 | > compiler will look for the module’s code in: | |
1295 | > | |
1296 | > * *src/front_of_house/hosting.rs* (what we covered) | |
923072b8 | 1297 | > * *src/front_of_house/hosting/mod.rs* (older style, still supported path) |
5e7ed085 | 1298 | > |
923072b8 FG |
1299 | > If you use both styles for the same module, you’ll get a compiler error. Using |
1300 | > a mix of both styles for different modules in the same project is allowed, but | |
5e7ed085 FG |
1301 | > might be confusing for people navigating your project. |
1302 | > | |
1303 | > The main downside to the style that uses files named *mod.rs* is that your | |
1304 | > project can end up with many files named *mod.rs*, which can get confusing | |
1305 | > when you have them open in your editor at the same time. | |
1306 | ||
923072b8 FG |
1307 | We’ve moved each module’s code to a separate file, and the module tree remains |
1308 | the same. The function calls in `eat_at_restaurant` will work without any | |
1309 | modification, even though the definitions live in different files. This | |
1310 | technique lets you move modules to new files as they grow in size. | |
5e7ed085 FG |
1311 | |
1312 | Note that the `pub use crate::front_of_house::hosting` statement in | |
1313 | *src/lib.rs* also hasn’t changed, nor does `use` have any impact on what files | |
1314 | are compiled as part of the crate. The `mod` keyword declares modules, and Rust | |
1315 | looks in a file with the same name as the module for the code that goes into | |
1316 | that module. | |
1317 | ||
1318 | ## Summary | |
1319 | ||
1320 | Rust lets you split a package into multiple crates and a crate into modules | |
1321 | so you can refer to items defined in one module from another module. You can do | |
1322 | this by specifying absolute or relative paths. These paths can be brought into | |
1323 | scope with a `use` statement so you can use a shorter path for multiple uses of | |
1324 | the item in that scope. Module code is private by default, but you can make | |
1325 | definitions public by adding the `pub` keyword. | |
1326 | ||
1327 | In the next chapter, we’ll look at some collection data structures in the | |
1328 | standard library that you can use in your neatly organized code. |