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