]> git.lizzy.rs Git - rust.git/blob - src/doc/guide-crates.md
rollup merge of #19849: alexcrichton/second-pass-option
[rust.git] / src / doc / guide-crates.md
1 % The Rust Crates and Modules Guide
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 Right now, the contents of `src/english/greetings.rs` and
212 `src/japanese/farewells.rs` are both empty at the moment. Let's add some
213 functions.
214
215 Put this in `src/english/greetings.rs`:
216
217 ```rust
218 // in src/english/greetings.rs
219
220 fn hello() -> String {
221     "Hello!".to_string()
222 }
223 ```
224
225 Put this in `src/english/farewells.rs`:
226
227 ```rust
228 // in src/english/farewells.rs
229
230 fn goodbye() -> String {
231     "Goodbye.".to_string()
232 }
233 ```
234
235 Put this in `src/japanese/greetings.rs`:
236
237 ```rust
238 // in src/japanese/greetings.rs
239
240 fn hello() -> String {
241     "こんにちは".to_string()
242 }
243 ```
244
245 Of course, you can copy and paste this from this web page, or just type
246 something else. It's not important that you actually put "konnichiwa" to learn
247 about the module system.
248
249 Put this in `src/japanese/farewells.rs`:
250
251 ```rust
252 // in src/japanese/farewells.rs
253
254 fn goodbye() -> String {
255     "さようなら".to_string()
256 }
257 ```
258
259 (This is "Sayoonara", if you're curious.)
260
261 Now that we have our some functionality in our crate, let's try to use it from
262 another crate.
263
264 # Importing External Crates
265
266 We have a library crate. Let's make an executable crate that imports and uses
267 our library.
268
269 Make a `src/main.rs` and put this in it: (it won't quite compile yet)
270
271 ```rust,ignore
272 // in src/main.rs
273
274 extern crate phrases;
275
276 fn main() {
277     println!("Hello in English: {}", phrases::english::greetings::hello());
278     println!("Goodbye in English: {}", phrases::english::farewells::goodbye());
279
280     println!("Hello in Japanese: {}", phrases::japanese::greetings::hello());
281     println!("Goodbye in Japanese: {}", phrases::japanese::farewells::goodbye());
282 }
283 ```
284
285 The `extern crate` declaration tells Rust that we need to compile and link to
286 the `phrases` crate. We can then use `phrases`' modules in this one. As we
287 mentioned earlier, you can use double colons to refer to sub-modules and the
288 functions inside of them.
289
290 Also, Cargo assumes that `src/main.rs` is the crate root of a binary crate,
291 rather than a library crate. Once we compile `src/main.rs`, we'll get an
292 executable that we can run. Our package now has two crates: `src/lib.rs` and
293 `src/main.rs`. This pattern is quite common for executable crates: most
294 functionality is in a library crate, and the executable crate uses that
295 library. This way, other programs can also use the library crate, and it's also
296 a nice separation of concerns.
297
298 This doesn't quite work yet, though. We get four errors that look similar to
299 this:
300
301 ```bash
302 $ cargo build
303    Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
304 /home/you/projects/phrases/src/main.rs:4:38: 4:72 error: function `hello` is private
305 /home/you/projects/phrases/src/main.rs:4     println!("Hello in English: {}", phrases::english::greetings::hello());
306                                                                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
307 note: in expansion of format_args!
308 <std macros>:2:23: 2:77 note: expansion site
309 <std macros>:1:1: 3:2 note: in expansion of println!
310 /home/you/projects/phrases/src/main.rs:4:5: 4:76 note: expansion site
311
312 ```
313
314 By default, everything is private in Rust. Let's talk about this in some more
315 depth.
316
317 # Exporting a Public Interface
318
319 Rust allows you to precisely control which aspects of your interface are
320 public, and so private is the default. To make things public, you use the `pub`
321 keyword. Let's focus on the `english` module first, so let's reduce our `src/main.rs`
322 to just this:
323
324 ```{rust,ignore}
325 // in src/main.rs
326
327 extern crate phrases;
328
329 fn main() {
330     println!("Hello in English: {}", phrases::english::greetings::hello());
331     println!("Goodbye in English: {}", phrases::english::farewells::goodbye());
332 }
333 ```
334
335 In our `src/lib.rs`, let's add `pub` to the `english` module declaration:
336
337 ```{rust,ignore}
338 // in src/lib.rs
339
340 pub mod english;
341
342 mod japanese;
343 ```
344
345 And in our `src/english/mod.rs`, let's make both `pub`:
346
347 ```{rust,ignore}
348 // in src/english/mod.rs
349
350 pub mod greetings;
351
352 pub mod farewells;
353 ```
354
355 In our `src/english/greetings.rs`, let's add `pub` to our `fn` declaration:
356
357 ```{rust,ignore}
358 // in src/english/greetings.rs
359
360 pub fn hello() -> String {
361     "Hello!".to_string()
362 }
363 ```
364
365 And also in `src/english/farewells.rs`:
366
367 ```{rust,ignore}
368 // in src/english/farewells.rs
369
370 pub fn goodbye() -> String {
371     "Goodbye.".to_string()
372 }
373 ```
374
375 Now, our crate compiles, albeit with warnings about not using the `japanese`
376 functions:
377
378 ```bash
379 $ cargo run
380    Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
381 /home/you/projects/phrases/src/japanese/greetings.rs:1:1: 3:2 warning: code is never used: `hello`, #[warn(dead_code)] on by default
382 /home/you/projects/phrases/src/japanese/greetings.rs:1 fn hello() -> String {
383 /home/you/projects/phrases/src/japanese/greetings.rs:2     "こんにちは".to_string()
384 /home/you/projects/phrases/src/japanese/greetings.rs:3 }
385 /home/you/projects/phrases/src/japanese/farewells.rs:1:1: 3:2 warning: code is never used: `goodbye`, #[warn(dead_code)] on by default
386 /home/you/projects/phrases/src/japanese/farewells.rs:1 fn goodbye() -> String {
387 /home/you/projects/phrases/src/japanese/farewells.rs:2     "さようなら".to_string()
388 /home/you/projects/phrases/src/japanese/farewells.rs:3 }
389      Running `target/phrases`
390 Hello in English: Hello!
391 Goodbye in English: Goodbye.
392 ```
393
394 Now that our functions are public, we can use them. Great! However, typing out
395 `phrases::english::greetings::hello()` is very long and repetitive. Rust has
396 another keyword for importing names into the current scope, so that you can
397 refer to them with shorter names. Let's talk about `use`.
398
399 # Importing Modules with `use`
400
401 Rust has a `use` keyword, which allows us to import names into our local scope.
402 Let's change our `src/main.rs` to look like this:
403
404 ```{rust,ignore}
405 // in src/main.rs
406
407 extern crate phrases;
408
409 use phrases::english::greetings;
410 use phrases::english::farewells;
411
412 fn main() {
413     println!("Hello in English: {}", greetings::hello());
414     println!("Goodbye in English: {}", farewells::goodbye());
415 }
416 ```
417
418 The two `use` lines import each module into the local scope, so we can refer to
419 the functions by a much shorter name. By convention, when importing functions, it's
420 considered best practice to import the module, rather than the function directly. In
421 other words, you _can_ do this:
422
423 ```{rust,ignore}
424 extern crate phrases;
425
426 use phrases::english::greetings::hello;
427 use phrases::english::farewells::goodbye;
428
429 fn main() {
430     println!("Hello in English: {}", hello());
431     println!("Goodbye in English: {}", goodbye());
432 }
433 ```
434
435 But it is not idiomatic. This is significantly more likely to introducing a
436 naming conflict. In our short program, it's not a big deal, but as it grows, it
437 becomes a problem. If we have conflicting names, Rust will give a compilation
438 error. For example, if we made the `japanese` functions public, and tried to do
439 this:
440
441 ```{rust,ignore}
442 extern crate phrases;
443
444 use phrases::english::greetings::hello;
445 use phrases::japanese::greetings::hello;
446
447 fn main() {
448     println!("Hello in English: {}", hello());
449     println!("Hello in Japanese: {}", hello());
450 }
451 ```
452
453 Rust will give us a compile-time error:
454
455 ```text
456    Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
457 /home/you/projects/phrases/src/main.rs:4:5: 4:40 error: a value named `hello` has already been imported in this module
458 /home/you/projects/phrases/src/main.rs:4 use phrases::japanese::greetings::hello;
459                                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
460 error: aborting due to previous error
461 Could not compile `phrases`.
462 ```
463
464 If we're importing multiple names from the same module, we don't have to type it out
465 twice. Rust has a shortcut syntax for writing this:
466
467 ```{rust,ignore}
468 use phrases::english::greetings;
469 use phrases::english::farewells;
470 ```
471
472 You use curly braces:
473
474 ```{rust,ignore}
475 use phrases::english::{greetings, farewells};
476 ```
477
478 These two declarations are equivalent, but the second is a lot less typing.
479
480 ## Re-exporting with `pub use`
481
482 You don't just use `use` to shorten identifiers. You can also use it inside of your crate
483 to re-export a function inside another module. This allows you to present an external
484 interface that may not directly map to your internal code organization.
485
486 Let's look at an example. Modify your `src/main.rs` to read like this:
487
488 ```{rust,ignore}
489 // in src/main.rs
490
491 extern crate phrases;
492
493 use phrases::english::{greetings,farewells};
494 use phrases::japanese;
495
496 fn main() {
497     println!("Hello in English: {}", greetings::hello());
498     println!("Goodbye in English: {}", farewells::goodbye());
499
500     println!("Hello in Japanese: {}", japanese::hello());
501     println!("Goodbye in Japanese: {}", japanese::goodbye());
502 }
503 ```
504
505 Then, modify your `src/lib.rs` to make the `japanese` mod public:
506
507 ```{rust,ignore}
508 // in src/lib.rs
509
510 pub mod english;
511
512 pub mod japanese;
513 ```
514
515 Next, make the two functions public, first in `src/japanese/greetings.rs`:
516
517 ```{rust,ignore}
518 // in src/japanese/greetings.rs
519
520 pub fn hello() -> String {
521     "こんにちは".to_string()
522 }
523 ```
524
525 And then in `src/japanese/farewells.rs`:
526
527 ```{rust,ignore}
528 // in src/japanese/farewells.rs
529
530 pub fn goodbye() -> String {
531     "さようなら".to_string()
532 }
533 ```
534
535 Finally, modify your `src/japanese/mod.rs` to read like this:
536
537 ```{rust,ignore}
538 // in src/japanese/mod.rs
539
540 pub use self::greetings::hello;
541 pub use self::farewells::goodbye;
542
543 mod greetings;
544
545 mod farewells;
546 ```
547
548 The `pub use` declaration brings the function into scope at this part of our
549 module hierarchy. Because we've `pub use`d this inside of our `japanese`
550 module, we now have a `phrases::japanese::hello()` function and a
551 `phrases::japanese::goodbye()` function, even though the code for them lives in
552 `phrases::japanese::greetings::hello()` and
553 `phrases::japanese::farewells::goodbye()`. Our internal organization doesn't
554 define our external interface.
555
556 Also, note that we `pub use`d before we declared our `mod`s. Rust requires that
557 `use` declarations go first.
558
559 This will build and run:
560
561 ```bash
562 $ cargo build
563    Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
564      Running `target/phrases`
565 Hello in English: Hello!
566 Goodbye in English: Goodbye.
567 Hello in Japanese: こんにちは
568 Goodbye in Japanese: さようなら
569 ```