]> git.lizzy.rs Git - rust.git/blob - src/doc/trpl/crates-and-modules.md
Rollup merge of #21357 - kimroen:patch-1, r=sanxiyn
[rust.git] / src / doc / trpl / crates-and-modules.md
1 % Crates and Modules
2
3 When a project starts getting large, it's considered a good software
4 engineering practice to split it up into a bunch of smaller pieces, and then
5 fit them together. It's also important to have a well-defined interface, so
6 that some of your functionality is private, and some is public. To facilitate
7 these kinds of things, Rust has a module system.
8
9 # Basic terminology: Crates and Modules
10
11 Rust has two distinct terms that relate to the module system: *crate* and
12 *module*. A crate is synonymous with a *library* or *package* in other
13 languages. Hence "Cargo" as the name of Rust's package management tool: you
14 ship your crates to others with Cargo. Crates can produce an executable or a
15 shared library, depending on the project.
16
17 Each crate has an implicit *root module* that contains the code for that crate.
18 You can then define a tree of sub-modules under that root module. Modules allow
19 you to partition your code within the crate itself.
20
21 As an example, let's make a *phrases* crate, which will give us various phrases
22 in different languages. To keep things simple, we'll stick to "greetings" and
23 "farewells" as two kinds of phrases, and use English and Japanese (日本語) as
24 two languages for those phrases to be in. We'll use this module layout:
25
26 ```text
27                                 +-----------+
28                             +---| greetings |
29                             |   +-----------+
30               +---------+   |
31               | english |---+
32               +---------+   |   +-----------+
33               |             +---| farewells |
34 +---------+   |                 +-----------+
35 | phrases |---+
36 +---------+   |                  +-----------+
37               |              +---| greetings |
38               +----------+   |   +-----------+
39               | japanese |---+
40               +----------+   |
41                              |   +-----------+
42                              +---| farewells |
43                                  +-----------+
44 ```
45
46 In this example, `phrases` is the name of our crate. All of the rest are
47 modules.  You can see that they form a tree, branching out from the crate
48 *root*, which is the root of the tree: `phrases` itself.
49
50 Now that we have a plan, let's define these modules in code. To start,
51 generate a new crate with Cargo:
52
53 ```bash
54 $ cargo new phrases
55 $ cd phrases
56 ```
57
58 If you remember, this generates a simple project for us:
59
60 ```bash
61 $ tree .
62 .
63 ├── Cargo.toml
64 └── src
65     └── lib.rs
66
67 1 directory, 2 files
68 ```
69
70 `src/lib.rs` is our crate root, corresponding to the `phrases` in our diagram
71 above.
72
73 # Defining Modules
74
75 To define each of our modules, we use the `mod` keyword. Let's make our
76 `src/lib.rs` look like this:
77
78 ```
79 // in src/lib.rs
80
81 mod english {
82     mod greetings {
83
84     }
85
86     mod farewells {
87
88     }
89 }
90
91 mod japanese {
92     mod greetings {
93
94     }
95
96     mod farewells {
97
98     }
99 }
100 ```
101
102 After the `mod` keyword, you give the name of the module. Module names follow
103 the conventions for other Rust identifiers: `lower_snake_case`. The contents of
104 each module are within curly braces (`{}`).
105
106 Within a given `mod`, you can declare sub-`mod`s. We can refer to sub-modules
107 with double-colon (`::`) notation: our four nested modules are
108 `english::greetings`, `english::farewells`, `japanese::greetings`, and
109 `japanese::farewells`. Because these sub-modules are namespaced under their
110 parent module, the names don't conflict: `english::greetings` and
111 `japanese::greetings` are distinct, even though their names are both
112 `greetings`.
113
114 Because this crate does not have a `main()` function, and is called `lib.rs`,
115 Cargo will build this crate as a library:
116
117 ```bash
118 $ cargo build
119    Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
120 $ ls target
121 deps  libphrases-a7448e02a0468eaa.rlib  native
122 ```
123
124 `libphrase-hash.rlib` is the compiled crate. Before we see how to use this
125 crate from another crate, let's break it up into multiple files.
126
127 # Multiple file crates
128
129 If each crate were just one file, these files would get very large. It's often
130 easier to split up crates into multiple files, and Rust supports this in two
131 ways.
132
133 Instead of declaring a module like this:
134
135 ```{rust,ignore}
136 mod english {
137     // contents of our module go here
138 }
139 ```
140
141 We can instead declare our module like this:
142
143 ```{rust,ignore}
144 mod english;
145 ```
146
147 If we do that, Rust will expect to find either a `english.rs` file, or a
148 `english/mod.rs` file with the contents of our module:
149
150 ```{rust,ignore}
151 // contents of our module go here
152 ```
153
154 Note that in these files, you don't need to re-declare the module: that's
155 already been done with the initial `mod` declaration.
156
157 Using these two techniques, we can break up our crate into two directories and
158 seven files:
159
160 ```bash
161 $ tree .
162 .
163 ├── Cargo.lock
164 ├── Cargo.toml
165 ├── src
166 │   ├── english
167 │   │   ├── farewells.rs
168 │   │   ├── greetings.rs
169 │   │   └── mod.rs
170 │   ├── japanese
171 │   │   ├── farewells.rs
172 │   │   ├── greetings.rs
173 │   │   └── mod.rs
174 │   └── lib.rs
175 └── target
176     ├── deps
177     ├── libphrases-a7448e02a0468eaa.rlib
178     └── native
179 ```
180
181 `src/lib.rs` is our crate root, and looks like this:
182
183 ```{rust,ignore}
184 // in src/lib.rs
185
186 mod english;
187
188 mod japanese;
189 ```
190
191 These two declarations tell Rust to look for either `src/english.rs` and
192 `src/japanese.rs`, or `src/english/mod.rs` and `src/japanese/mod.rs`, depending
193 on our preference. In this case, because our modules have sub-modules, we've
194 chosen the second. Both `src/english/mod.rs` and `src/japanese/mod.rs` look
195 like this:
196
197 ```{rust,ignore}
198 // both src/english/mod.rs and src/japanese/mod.rs
199
200 mod greetings;
201
202 mod farewells;
203 ```
204
205 Again, these declarations tell Rust to look for either
206 `src/english/greetings.rs` and `src/japanese/greetings.rs` or
207 `src/english/farewells/mod.rs` and `src/japanese/farewells/mod.rs`. Because
208 these sub-modules don't have their own sub-modules, we've chosen to make them
209 `src/english/greetings.rs` and `src/japanese/farewells.rs`. Whew!
210
211 The contents of `src/english/greetings.rs` and `src/japanese/farewells.rs` are
212 both empty at the moment. Let's add some functions.
213
214 Put this in `src/english/greetings.rs`:
215
216 ```rust
217 // in src/english/greetings.rs
218
219 fn hello() -> String {
220     "Hello!".to_string()
221 }
222 ```
223
224 Put this in `src/english/farewells.rs`:
225
226 ```rust
227 // in src/english/farewells.rs
228
229 fn goodbye() -> String {
230     "Goodbye.".to_string()
231 }
232 ```
233
234 Put this in `src/japanese/greetings.rs`:
235
236 ```rust
237 // in src/japanese/greetings.rs
238
239 fn hello() -> String {
240     "こんにちは".to_string()
241 }
242 ```
243
244 Of course, you can copy and paste this from this web page, or just type
245 something else. It's not important that you actually put "konnichiwa" to learn
246 about the module system.
247
248 Put this in `src/japanese/farewells.rs`:
249
250 ```rust
251 // in src/japanese/farewells.rs
252
253 fn goodbye() -> String {
254     "さようなら".to_string()
255 }
256 ```
257
258 (This is "Sayōnara", if you're curious.)
259
260 Now that we have our some functionality in our crate, let's try to use it from
261 another crate.
262
263 # Importing External Crates
264
265 We have a library crate. Let's make an executable crate that imports and uses
266 our library.
267
268 Make a `src/main.rs` and put this in it: (it won't quite compile yet)
269
270 ```rust,ignore
271 // in src/main.rs
272
273 extern crate phrases;
274
275 fn main() {
276     println!("Hello in English: {}", phrases::english::greetings::hello());
277     println!("Goodbye in English: {}", phrases::english::farewells::goodbye());
278
279     println!("Hello in Japanese: {}", phrases::japanese::greetings::hello());
280     println!("Goodbye in Japanese: {}", phrases::japanese::farewells::goodbye());
281 }
282 ```
283
284 The `extern crate` declaration tells Rust that we need to compile and link to
285 the `phrases` crate. We can then use `phrases`' modules in this one. As we
286 mentioned earlier, you can use double colons to refer to sub-modules and the
287 functions inside of them.
288
289 Also, Cargo assumes that `src/main.rs` is the crate root of a binary crate,
290 rather than a library crate. Once we compile `src/main.rs`, we'll get an
291 executable that we can run. Our package now has two crates: `src/lib.rs` and
292 `src/main.rs`. This pattern is quite common for executable crates: most
293 functionality is in a library crate, and the executable crate uses that
294 library. This way, other programs can also use the library crate, and it's also
295 a nice separation of concerns.
296
297 This doesn't quite work yet, though. We get four errors that look similar to
298 this:
299
300 ```bash
301 $ cargo build
302    Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
303 /home/you/projects/phrases/src/main.rs:4:38: 4:72 error: function `hello` is private
304 /home/you/projects/phrases/src/main.rs:4     println!("Hello in English: {}", phrases::english::greetings::hello());
305                                                                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
306 note: in expansion of format_args!
307 <std macros>:2:23: 2:77 note: expansion site
308 <std macros>:1:1: 3:2 note: in expansion of println!
309 /home/you/projects/phrases/src/main.rs:4:5: 4:76 note: expansion site
310
311 ```
312
313 By default, everything is private in Rust. Let's talk about this in some more
314 depth.
315
316 # Exporting a Public Interface
317
318 Rust allows you to precisely control which aspects of your interface are
319 public, and so private is the default. To make things public, you use the `pub`
320 keyword. Let's focus on the `english` module first, so let's reduce our `src/main.rs`
321 to just this:
322
323 ```{rust,ignore}
324 // in src/main.rs
325
326 extern crate phrases;
327
328 fn main() {
329     println!("Hello in English: {}", phrases::english::greetings::hello());
330     println!("Goodbye in English: {}", phrases::english::farewells::goodbye());
331 }
332 ```
333
334 In our `src/lib.rs`, let's add `pub` to the `english` module declaration:
335
336 ```{rust,ignore}
337 // in src/lib.rs
338
339 pub mod english;
340
341 mod japanese;
342 ```
343
344 And in our `src/english/mod.rs`, let's make both `pub`:
345
346 ```{rust,ignore}
347 // in src/english/mod.rs
348
349 pub mod greetings;
350
351 pub mod farewells;
352 ```
353
354 In our `src/english/greetings.rs`, let's add `pub` to our `fn` declaration:
355
356 ```{rust,ignore}
357 // in src/english/greetings.rs
358
359 pub fn hello() -> String {
360     "Hello!".to_string()
361 }
362 ```
363
364 And also in `src/english/farewells.rs`:
365
366 ```{rust,ignore}
367 // in src/english/farewells.rs
368
369 pub fn goodbye() -> String {
370     "Goodbye.".to_string()
371 }
372 ```
373
374 Now, our crate compiles, albeit with warnings about not using the `japanese`
375 functions:
376
377 ```bash
378 $ cargo run
379    Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
380 /home/you/projects/phrases/src/japanese/greetings.rs:1:1: 3:2 warning: code is never used: `hello`, #[warn(dead_code)] on by default
381 /home/you/projects/phrases/src/japanese/greetings.rs:1 fn hello() -> String {
382 /home/you/projects/phrases/src/japanese/greetings.rs:2     "こんにちは".to_string()
383 /home/you/projects/phrases/src/japanese/greetings.rs:3 }
384 /home/you/projects/phrases/src/japanese/farewells.rs:1:1: 3:2 warning: code is never used: `goodbye`, #[warn(dead_code)] on by default
385 /home/you/projects/phrases/src/japanese/farewells.rs:1 fn goodbye() -> String {
386 /home/you/projects/phrases/src/japanese/farewells.rs:2     "さようなら".to_string()
387 /home/you/projects/phrases/src/japanese/farewells.rs:3 }
388      Running `target/phrases`
389 Hello in English: Hello!
390 Goodbye in English: Goodbye.
391 ```
392
393 Now that our functions are public, we can use them. Great! However, typing out
394 `phrases::english::greetings::hello()` is very long and repetitive. Rust has
395 another keyword for importing names into the current scope, so that you can
396 refer to them with shorter names. Let's talk about `use`.
397
398 # Importing Modules with `use`
399
400 Rust has a `use` keyword, which allows us to import names into our local scope.
401 Let's change our `src/main.rs` to look like this:
402
403 ```{rust,ignore}
404 // in src/main.rs
405
406 extern crate phrases;
407
408 use phrases::english::greetings;
409 use phrases::english::farewells;
410
411 fn main() {
412     println!("Hello in English: {}", greetings::hello());
413     println!("Goodbye in English: {}", farewells::goodbye());
414 }
415 ```
416
417 The two `use` lines import each module into the local scope, so we can refer to
418 the functions by a much shorter name. By convention, when importing functions, it's
419 considered best practice to import the module, rather than the function directly. In
420 other words, you _can_ do this:
421
422 ```{rust,ignore}
423 extern crate phrases;
424
425 use phrases::english::greetings::hello;
426 use phrases::english::farewells::goodbye;
427
428 fn main() {
429     println!("Hello in English: {}", hello());
430     println!("Goodbye in English: {}", goodbye());
431 }
432 ```
433
434 But it is not idiomatic. This is significantly more likely to introducing a
435 naming conflict. In our short program, it's not a big deal, but as it grows, it
436 becomes a problem. If we have conflicting names, Rust will give a compilation
437 error. For example, if we made the `japanese` functions public, and tried to do
438 this:
439
440 ```{rust,ignore}
441 extern crate phrases;
442
443 use phrases::english::greetings::hello;
444 use phrases::japanese::greetings::hello;
445
446 fn main() {
447     println!("Hello in English: {}", hello());
448     println!("Hello in Japanese: {}", hello());
449 }
450 ```
451
452 Rust will give us a compile-time error:
453
454 ```text
455    Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
456 /home/you/projects/phrases/src/main.rs:4:5: 4:40 error: a value named `hello` has already been imported in this module
457 /home/you/projects/phrases/src/main.rs:4 use phrases::japanese::greetings::hello;
458                                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
459 error: aborting due to previous error
460 Could not compile `phrases`.
461 ```
462
463 If we're importing multiple names from the same module, we don't have to type it out
464 twice. Rust has a shortcut syntax for writing this:
465
466 ```{rust,ignore}
467 use phrases::english::greetings;
468 use phrases::english::farewells;
469 ```
470
471 You use curly braces:
472
473 ```{rust,ignore}
474 use phrases::english::{greetings, farewells};
475 ```
476
477 These two declarations are equivalent, but the second is a lot less typing.
478
479 ## Re-exporting with `pub use`
480
481 You don't just use `use` to shorten identifiers. You can also use it inside of your crate
482 to re-export a function inside another module. This allows you to present an external
483 interface that may not directly map to your internal code organization.
484
485 Let's look at an example. Modify your `src/main.rs` to read like this:
486
487 ```{rust,ignore}
488 // in src/main.rs
489
490 extern crate phrases;
491
492 use phrases::english::{greetings,farewells};
493 use phrases::japanese;
494
495 fn main() {
496     println!("Hello in English: {}", greetings::hello());
497     println!("Goodbye in English: {}", farewells::goodbye());
498
499     println!("Hello in Japanese: {}", japanese::hello());
500     println!("Goodbye in Japanese: {}", japanese::goodbye());
501 }
502 ```
503
504 Then, modify your `src/lib.rs` to make the `japanese` mod public:
505
506 ```{rust,ignore}
507 // in src/lib.rs
508
509 pub mod english;
510
511 pub mod japanese;
512 ```
513
514 Next, make the two functions public, first in `src/japanese/greetings.rs`:
515
516 ```{rust,ignore}
517 // in src/japanese/greetings.rs
518
519 pub fn hello() -> String {
520     "こんにちは".to_string()
521 }
522 ```
523
524 And then in `src/japanese/farewells.rs`:
525
526 ```{rust,ignore}
527 // in src/japanese/farewells.rs
528
529 pub fn goodbye() -> String {
530     "さようなら".to_string()
531 }
532 ```
533
534 Finally, modify your `src/japanese/mod.rs` to read like this:
535
536 ```{rust,ignore}
537 // in src/japanese/mod.rs
538
539 pub use self::greetings::hello;
540 pub use self::farewells::goodbye;
541
542 mod greetings;
543
544 mod farewells;
545 ```
546
547 The `pub use` declaration brings the function into scope at this part of our
548 module hierarchy. Because we've `pub use`d this inside of our `japanese`
549 module, we now have a `phrases::japanese::hello()` function and a
550 `phrases::japanese::goodbye()` function, even though the code for them lives in
551 `phrases::japanese::greetings::hello()` and
552 `phrases::japanese::farewells::goodbye()`. Our internal organization doesn't
553 define our external interface.
554
555 Also, note that we `pub use`d before we declared our `mod`s. Rust requires that
556 `use` declarations go first.
557
558 This will build and run:
559
560 ```bash
561 $ cargo run
562    Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
563      Running `target/phrases`
564 Hello in English: Hello!
565 Goodbye in English: Goodbye.
566 Hello in Japanese: こんにちは
567 Goodbye in Japanese: さようなら
568 ```