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