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