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