]> git.proxmox.com Git - rustc.git/blob - src/doc/book/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md
New upstream version 1.63.0+dfsg1
[rustc.git] / src / doc / book / src / ch07-04-bringing-paths-into-scope-with-the-use-keyword.md
1 ## Bringing Paths into Scope with the `use` Keyword
2
3 Having to write out the paths to call functions can feel inconvenient and
4 repetitive. In Listing 7-7, whether we chose the absolute or relative path to
5 the `add_to_waitlist` function, every time we wanted to call `add_to_waitlist`
6 we had to specify `front_of_house` and `hosting` too. Fortunately, there’s a
7 way to simplify this process: we can create a shortcut to a path with the `use`
8 keyword once, and then use the shorter name everywhere else in the scope.
9
10 In Listing 7-11, we bring the `crate::front_of_house::hosting` module into the
11 scope of the `eat_at_restaurant` function so we only have to specify
12 `hosting::add_to_waitlist` to call the `add_to_waitlist` function in
13 `eat_at_restaurant`.
14
15 <span class="filename">Filename: src/lib.rs</span>
16
17 ```rust,noplayground,test_harness
18 {{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-11/src/lib.rs}}
19 ```
20
21 <span class="caption">Listing 7-11: Bringing a module into scope with
22 `use`</span>
23
24 Adding `use` and a path in a scope is similar to creating a symbolic link in
25 the filesystem. By adding `use crate::front_of_house::hosting` in the crate
26 root, `hosting` is now a valid name in that scope, just as though the `hosting`
27 module had been defined in the crate root. Paths brought into scope with `use`
28 also check privacy, like any other paths.
29
30 Note that `use` only creates the shortcut for the particular scope in which the
31 `use` occurs. Listing 7-12 moves the `eat_at_restaurant` function into a new
32 child module named `customer`, which is then a different scope than the `use`
33 statement, so the function body won’t compile:
34
35 <span class="filename">Filename: src/lib.rs</span>
36
37 ```rust,noplayground,test_harness,does_not_compile,ignore
38 {{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-12/src/lib.rs}}
39 ```
40
41 <span class="caption">Listing 7-12: A `use` statement only applies in the scope
42 it’s in</span>
43
44 The compiler error shows that the shortcut no longer applies within the
45 `customer` module:
46
47 ```console
48 {{#include ../listings/ch07-managing-growing-projects/listing-07-12/output.txt}}
49 ```
50
51 Notice there’s also a warning that the `use` is no longer used in its scope! To
52 fix this problem, move the `use` within the `customer` module too, or reference
53 the shortcut in the parent module with `super::hosting` within the child
54 `customer` module.
55
56 ### Creating Idiomatic `use` Paths
57
58 In Listing 7-11, you might have wondered why we specified `use
59 crate::front_of_house::hosting` and then called `hosting::add_to_waitlist` in
60 `eat_at_restaurant` rather than specifying the `use` path all the way out to
61 the `add_to_waitlist` function to achieve the same result, as in Listing 7-13.
62
63 <span class="filename">Filename: src/lib.rs</span>
64
65 ```rust,noplayground,test_harness
66 {{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-13/src/lib.rs}}
67 ```
68
69 <span class="caption">Listing 7-13: Bringing the `add_to_waitlist` function
70 into scope with `use`, which is unidiomatic</span>
71
72 Although both Listing 7-11 and 7-13 accomplish the same task, Listing 7-11 is
73 the idiomatic way to bring a function into scope with `use`. Bringing the
74 function’s parent module into scope with `use` means we have to specify the
75 parent module when calling the function. Specifying the parent module when
76 calling the function makes it clear that the function isn’t locally defined
77 while still minimizing repetition of the full path. The code in Listing 7-13 is
78 unclear as to where `add_to_waitlist` is defined.
79
80 On the other hand, when bringing in structs, enums, and other items with `use`,
81 it’s idiomatic to specify the full path. Listing 7-14 shows the idiomatic way
82 to bring the standard library’s `HashMap` struct into the scope of a binary
83 crate.
84
85 <span class="filename">Filename: src/main.rs</span>
86
87 ```rust
88 {{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-14/src/main.rs}}
89 ```
90
91 <span class="caption">Listing 7-14: Bringing `HashMap` into scope in an
92 idiomatic way</span>
93
94 There’s no strong reason behind this idiom: it’s just the convention that has
95 emerged, and folks have gotten used to reading and writing Rust code this way.
96
97 The exception to this idiom is if we’re bringing two items with the same name
98 into scope with `use` statements, because Rust doesn’t allow that. Listing 7-15
99 shows how to bring two `Result` types into scope that have the same name but
100 different parent modules and how to refer to them.
101
102 <span class="filename">Filename: src/lib.rs</span>
103
104 ```rust,noplayground
105 {{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-15/src/lib.rs:here}}
106 ```
107
108 <span class="caption">Listing 7-15: Bringing two types with the same name into
109 the same scope requires using their parent modules.</span>
110
111 As you can see, using the parent modules distinguishes the two `Result` types.
112 If instead we specified `use std::fmt::Result` and `use std::io::Result`, we’d
113 have two `Result` types in the same scope and Rust wouldn’t know which one we
114 meant when we used `Result`.
115
116 ### Providing New Names with the `as` Keyword
117
118 There’s another solution to the problem of bringing two types of the same name
119 into the same scope with `use`: after the path, we can specify `as` and a new
120 local name, or *alias*, for the type. Listing 7-16 shows another way to write
121 the code in Listing 7-15 by renaming one of the two `Result` types using `as`.
122
123 <span class="filename">Filename: src/lib.rs</span>
124
125 ```rust,noplayground
126 {{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-16/src/lib.rs:here}}
127 ```
128
129 <span class="caption">Listing 7-16: Renaming a type when it’s brought into
130 scope with the `as` keyword</span>
131
132 In the second `use` statement, we chose the new name `IoResult` for the
133 `std::io::Result` type, which won’t conflict with the `Result` from `std::fmt`
134 that we’ve also brought into scope. Listing 7-15 and Listing 7-16 are
135 considered idiomatic, so the choice is up to you!
136
137 ### Re-exporting Names with `pub use`
138
139 When we bring a name into scope with the `use` keyword, the name available in
140 the new scope is private. To enable the code that calls our code to refer to
141 that name as if it had been defined in that code’s scope, we can combine `pub`
142 and `use`. This technique is called *re-exporting* because we’re bringing
143 an item into scope but also making that item available for others to bring into
144 their scope.
145
146 Listing 7-17 shows the code in Listing 7-11 with `use` in the root module
147 changed to `pub use`.
148
149 <span class="filename">Filename: src/lib.rs</span>
150
151 ```rust,noplayground,test_harness
152 {{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-17/src/lib.rs}}
153 ```
154
155 <span class="caption">Listing 7-17: Making a name available for any code to use
156 from a new scope with `pub use`</span>
157
158 Before this change, external code would have to call the `add_to_waitlist`
159 function by using the path
160 `restaurant::front_of_house::hosting::add_to_waitlist()`. Now that this `pub
161 use` has re-exported the `hosting` module from the root module, external code
162 can now use the path `restaurant::hosting::add_to_waitlist()` instead.
163
164 Re-exporting is useful when the internal structure of your code is different
165 from how programmers calling your code would think about the domain. For
166 example, in this restaurant metaphor, the people running the restaurant think
167 about “front of house” and “back of house.” But customers visiting a restaurant
168 probably won’t think about the parts of the restaurant in those terms. With
169 `pub use`, we can write our code with one structure but expose a different
170 structure. Doing so makes our library well organized for programmers working on
171 the library and programmers calling the library. We’ll look at another example
172 of `pub use` and how it affects your crate’s documentation in the [“Exporting a
173 Convenient Public API with `pub use`”][ch14-pub-use]<!-- ignore --> section of
174 Chapter 14.
175
176 ### Using External Packages
177
178 In Chapter 2, we programmed a guessing game project that used an external
179 package called `rand` to get random numbers. To use `rand` in our project, we
180 added this line to *Cargo.toml*:
181
182 <!-- When updating the version of `rand` used, also update the version of
183 `rand` used in these files so they all match:
184 * ch02-00-guessing-game-tutorial.md
185 * ch14-03-cargo-workspaces.md
186 -->
187
188 <span class="filename">Filename: Cargo.toml</span>
189
190 ```toml
191 {{#include ../listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.toml:9:}}
192 ```
193
194 Adding `rand` as a dependency in *Cargo.toml* tells Cargo to download the
195 `rand` package and any dependencies from [crates.io](https://crates.io/) and
196 make `rand` available to our project.
197
198 Then, to bring `rand` definitions into the scope of our package, we added a
199 `use` line starting with the name of the crate, `rand`, and listed the items
200 we wanted to bring into scope. Recall that in the [“Generating a Random
201 Number”][rand]<!-- ignore --> section in Chapter 2, we brought the `Rng` trait
202 into scope and called the `rand::thread_rng` function:
203
204 ```rust,ignore
205 {{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-03/src/main.rs:ch07-04}}
206 ```
207
208 Members of the Rust community have made many packages available at
209 [crates.io](https://crates.io/), and pulling any of them into your package
210 involves these same steps: listing them in your package’s *Cargo.toml* file and
211 using `use` to bring items from their crates into scope.
212
213 Note that the standard `std` library is also a crate that’s external to our
214 package. Because the standard library is shipped with the Rust language, we
215 don’t need to change *Cargo.toml* to include `std`. But we do need to refer to
216 it with `use` to bring items from there into our package’s scope. For example,
217 with `HashMap` we would use this line:
218
219 ```rust
220 use std::collections::HashMap;
221 ```
222
223 This is an absolute path starting with `std`, the name of the standard library
224 crate.
225
226 ### Using Nested Paths to Clean Up Large `use` Lists
227
228 If we’re using multiple items defined in the same crate or same module,
229 listing each item on its own line can take up a lot of vertical space in our
230 files. For example, these two `use` statements we had in the Guessing Game in
231 Listing 2-4 bring items from `std` into scope:
232
233 <span class="filename">Filename: src/main.rs</span>
234
235 ```rust,ignore
236 {{#rustdoc_include ../listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/src/main.rs:here}}
237 ```
238
239 Instead, we can use nested paths to bring the same items into scope in one
240 line. We do this by specifying the common part of the path, followed by two
241 colons, and then curly brackets around a list of the parts of the paths that
242 differ, as shown in Listing 7-18.
243
244 <span class="filename">Filename: src/main.rs</span>
245
246 ```rust,ignore
247 {{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-18/src/main.rs:here}}
248 ```
249
250 <span class="caption">Listing 7-18: Specifying a nested path to bring multiple
251 items with the same prefix into scope</span>
252
253 In bigger programs, bringing many items into scope from the same crate or
254 module using nested paths can reduce the number of separate `use` statements
255 needed by a lot!
256
257 We can use a nested path at any level in a path, which is useful when combining
258 two `use` statements that share a subpath. For example, Listing 7-19 shows two
259 `use` statements: one that brings `std::io` into scope and one that brings
260 `std::io::Write` into scope.
261
262 <span class="filename">Filename: src/lib.rs</span>
263
264 ```rust,noplayground
265 {{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-19/src/lib.rs}}
266 ```
267
268 <span class="caption">Listing 7-19: Two `use` statements where one is a subpath
269 of the other</span>
270
271 The common part of these two paths is `std::io`, and that’s the complete first
272 path. To merge these two paths into one `use` statement, we can use `self` in
273 the nested path, as shown in Listing 7-20.
274
275 <span class="filename">Filename: src/lib.rs</span>
276
277 ```rust,noplayground
278 {{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-20/src/lib.rs}}
279 ```
280
281 <span class="caption">Listing 7-20: Combining the paths in Listing 7-19 into
282 one `use` statement</span>
283
284 This line brings `std::io` and `std::io::Write` into scope.
285
286 ### The Glob Operator
287
288 If we want to bring *all* public items defined in a path into scope, we can
289 specify that path followed by the `*` glob operator:
290
291 ```rust
292 use std::collections::*;
293 ```
294
295 This `use` statement brings all public items defined in `std::collections` into
296 the current scope. Be careful when using the glob operator! Glob can make it
297 harder to tell what names are in scope and where a name used in your program
298 was defined.
299
300 The glob operator is often used when testing to bring everything under test
301 into the `tests` module; we’ll talk about that in the [“How to Write
302 Tests”][writing-tests]<!-- ignore --> section in Chapter 11. The glob operator
303 is also sometimes used as part of the prelude pattern: see [the standard
304 library documentation](../std/prelude/index.html#other-preludes)<!-- ignore -->
305 for more information on that pattern.
306
307 [ch14-pub-use]: ch14-02-publishing-to-crates-io.html#exporting-a-convenient-public-api-with-pub-use
308 [rand]: ch02-00-guessing-game-tutorial.html#generating-a-random-number
309 [writing-tests]: ch11-01-writing-tests.html#how-to-write-tests