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