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