3 When a project starts getting large, it’s considered good software
4 engineering practice to split it up into a bunch of smaller pieces, and then
5 fit them together. It is 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.
9 # Basic terminology: Crates and Modules
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 library, depending on the project.
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.
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:
32 | +---------+ | +-----------+
34 +---------+ | +-----------+
36 +---------+ | +-----------+
38 | +----------+ | +-----------+
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.
50 Now that we have a plan, let’s define these modules in code. To start,
51 generate a new crate with Cargo:
58 If you remember, this generates a simple project for us:
70 `src/lib.rs` is our crate root, corresponding to the `phrases` in our diagram
75 To define each of our modules, we use the `mod` keyword. Let’s make our
76 `src/lib.rs` look like this:
96 After the `mod` keyword, you give the name of the module. Module names follow
97 the conventions for other Rust identifiers: `lower_snake_case`. The contents of
98 each module are within curly braces (`{}`).
100 Within a given `mod`, you can declare sub-`mod`s. We can refer to sub-modules
101 with 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
104 parent module, the names don’t conflict: `english::greetings` and
105 `japanese::greetings` are distinct, even though their names are both
108 Because this crate does not have a `main()` function, and is called `lib.rs`,
109 Cargo will build this crate as a library:
113 Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
115 build deps examples libphrases-a7448e02a0468eaa.rlib native
118 `libphrases-hash.rlib` is the compiled crate. Before we see how to use this
119 crate from another crate, let’s break it up into multiple files.
121 # Multiple File Crates
123 If each crate were just one file, these files would get very large. It’s often
124 easier to split up crates into multiple files, and Rust supports this in two
127 Instead of declaring a module like this:
131 // contents of our module go here
135 We can instead declare our module like this:
141 If we do that, Rust will expect to find either a `english.rs` file, or a
142 `english/mod.rs` file with the contents of our module.
144 Note that in these files, you don’t need to re-declare the module: that’s
145 already been done with the initial `mod` declaration.
147 Using these two techniques, we can break up our crate into two directories and
170 ├── libphrases-a7448e02a0468eaa.rlib
174 `src/lib.rs` is our crate root, and looks like this:
181 These 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
183 on our preference. In this case, because our modules have sub-modules, we’ve
184 chosen the second. Both `src/english/mod.rs` and `src/japanese/mod.rs` look
192 Again, these declarations tell Rust to look for either
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
198 their 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!
202 The 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
207 Put this in `src/english/greetings.rs`:
210 fn hello() -> String {
215 Put this in `src/english/farewells.rs`:
218 fn goodbye() -> String {
219 "Goodbye.".to_string()
223 Put this in `src/japanese/greetings.rs`:
226 fn hello() -> String {
231 Of course, you can copy and paste this from this web page, or type
232 something else. It’s not important that you actually put ‘konnichiwa’ to learn
233 about the module system.
235 Put this in `src/japanese/farewells.rs`:
238 fn goodbye() -> String {
243 (This is ‘Sayōnara’, if you’re curious.)
245 Now that we have some functionality in our crate, let’s try to use it from
248 # Importing External Crates
250 We have a library crate. Let’s make an executable crate that imports and uses
253 Make a `src/main.rs` and put this in it (it won’t quite compile yet):
256 extern crate phrases;
259 println!("Hello in English: {}", phrases::english::greetings::hello());
260 println!("Goodbye in English: {}", phrases::english::farewells::goodbye());
262 println!("Hello in Japanese: {}", phrases::japanese::greetings::hello());
263 println!("Goodbye in Japanese: {}", phrases::japanese::farewells::goodbye());
267 The `extern crate` declaration tells Rust that we need to compile and link to
268 the `phrases` crate. We can then use `phrases`’ modules in this one. As we
269 mentioned earlier, you can use double colons to refer to sub-modules and the
270 functions inside of them.
272 (Note: when importing a crate that has dashes in its name "like-this", which is
273 not a valid Rust identifier, it will be converted by changing the dashes to
274 underscores, so you would write `extern crate like_this;`.)
276 Also, Cargo assumes that `src/main.rs` is the crate root of a binary crate,
277 rather than a library crate. Our package now has two crates: `src/lib.rs` and
278 `src/main.rs`. This pattern is quite common for executable crates: most
279 functionality is in a library crate, and the executable crate uses that
280 library. This way, other programs can also use the library crate, and it’s also
281 a nice separation of concerns.
283 This doesn’t quite work yet, though. We get four errors that look similar to
288 Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
289 src/main.rs:4:38: 4:72 error: function `hello` is private
290 src/main.rs:4 println!("Hello in English: {}", phrases::english::greetings::hello());
291 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
292 note: in expansion of format_args!
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!
297 phrases/src/main.rs:4:5: 4:76 note: expansion site
300 By default, everything is private in Rust. Let’s talk about this in some more
303 # Exporting a Public Interface
305 Rust allows you to precisely control which aspects of your interface are
306 public, and so private is the default. To make things public, you use the `pub`
307 keyword. Let’s focus on the `english` module first, so let’s reduce our `src/main.rs`
311 extern crate phrases;
314 println!("Hello in English: {}", phrases::english::greetings::hello());
315 println!("Goodbye in English: {}", phrases::english::farewells::goodbye());
319 In our `src/lib.rs`, let’s add `pub` to the `english` module declaration:
326 And in our `src/english/mod.rs`, let’s make both `pub`:
333 In our `src/english/greetings.rs`, let’s add `pub` to our `fn` declaration:
336 pub fn hello() -> String {
341 And also in `src/english/farewells.rs`:
344 pub fn goodbye() -> String {
345 "Goodbye.".to_string()
349 Now, our crate compiles, albeit with warnings about not using the `japanese`
354 Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
355 src/japanese/greetings.rs:1:1: 3:2 warning: function is never used: `hello`, #[warn(dead_code)] on by default
356 src/japanese/greetings.rs:1 fn hello() -> String {
357 src/japanese/greetings.rs:2 "こんにちは".to_string()
358 src/japanese/greetings.rs:3 }
359 src/japanese/farewells.rs:1:1: 3:2 warning: function is never used: `goodbye`, #[warn(dead_code)] on by default
360 src/japanese/farewells.rs:1 fn goodbye() -> String {
361 src/japanese/farewells.rs:2 "さようなら".to_string()
362 src/japanese/farewells.rs:3 }
363 Running `target/debug/phrases`
364 Hello in English: Hello!
365 Goodbye in English: Goodbye.
368 `pub` also applies to `struct`s and their member fields. In keeping with Rust’s
369 tendency toward safety, simply making a `struct` public won't automatically
370 make its members public: you must mark the fields individually with `pub`.
372 Now 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
374 another keyword for importing names into the current scope, so that you can
375 refer to them with shorter names. Let’s talk about `use`.
377 # Importing Modules with `use`
379 Rust has a `use` keyword, which allows us to import names into our local scope.
380 Let’s change our `src/main.rs` to look like this:
383 extern crate phrases;
385 use phrases::english::greetings;
386 use phrases::english::farewells;
389 println!("Hello in English: {}", greetings::hello());
390 println!("Goodbye in English: {}", farewells::goodbye());
394 The two `use` lines import each module into the local scope, so we can refer to
395 the functions by a much shorter name. By convention, when importing functions, it’s
396 considered best practice to import the module, rather than the function directly. In
397 other words, you _can_ do this:
400 extern crate phrases;
402 use phrases::english::greetings::hello;
403 use phrases::english::farewells::goodbye;
406 println!("Hello in English: {}", hello());
407 println!("Goodbye in English: {}", goodbye());
411 But it is not idiomatic. This is significantly more likely to introduce a
412 naming conflict. In our short program, it’s not a big deal, but as it grows, it
413 becomes a problem. If we have conflicting names, Rust will give a compilation
414 error. For example, if we made the `japanese` functions public, and tried to do
418 extern crate phrases;
420 use phrases::english::greetings::hello;
421 use phrases::japanese::greetings::hello;
424 println!("Hello in English: {}", hello());
425 println!("Hello in Japanese: {}", hello());
429 Rust will give us a compile-time error:
432 Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
433 src/main.rs:4:5: 4:40 error: a value named `hello` has already been imported in this module [E0252]
434 src/main.rs:4 use phrases::japanese::greetings::hello;
435 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
436 error: aborting due to previous error
437 Could not compile `phrases`.
440 If we’re importing multiple names from the same module, we don’t have to type it out
441 twice. Instead of this:
444 use phrases::english::greetings;
445 use phrases::english::farewells;
448 We can use this shortcut:
451 use phrases::english::{greetings, farewells};
454 ## Re-exporting with `pub use`
456 You don’t only use `use` to shorten identifiers. You can also use it inside of your crate
457 to re-export a function inside another module. This allows you to present an external
458 interface that may not directly map to your internal code organization.
460 Let’s look at an example. Modify your `src/main.rs` to read like this:
463 extern crate phrases;
465 use phrases::english::{greetings,farewells};
466 use phrases::japanese;
469 println!("Hello in English: {}", greetings::hello());
470 println!("Goodbye in English: {}", farewells::goodbye());
472 println!("Hello in Japanese: {}", japanese::hello());
473 println!("Goodbye in Japanese: {}", japanese::goodbye());
477 Then, modify your `src/lib.rs` to make the `japanese` mod public:
484 Next, make the two functions public, first in `src/japanese/greetings.rs`:
487 pub fn hello() -> String {
492 And then in `src/japanese/farewells.rs`:
495 pub fn goodbye() -> String {
500 Finally, modify your `src/japanese/mod.rs` to read like this:
503 pub use self::greetings::hello;
504 pub use self::farewells::goodbye;
510 The `pub use` declaration brings the function into scope at this part of our
511 module hierarchy. Because we’ve `pub use`d this inside of our `japanese`
512 module, 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
515 `phrases::japanese::farewells::goodbye()`. Our internal organization doesn’t
516 define our external interface.
518 Here we have a `pub use` for each function we want to bring into the
519 `japanese` scope. We could alternatively use the wildcard syntax to include
520 everything from `greetings` into the current scope: `pub use self::greetings::*`.
522 What about the `self`? Well, by default, `use` declarations are absolute paths,
523 starting from your crate root. `self` makes that path relative to your current
524 place in the hierarchy instead. There’s one more special form of `use`: you can
525 `use super::` to reach one level up the tree from your current location. Some
526 people like to think of `self` as `.` and `super` as `..`, from many shells’
527 display for the current directory and the parent directory.
529 Outside of `use`, paths are relative: `foo::bar()` refers to a function inside
530 of `foo` relative to where we are. If that’s prefixed with `::`, as in
531 `::foo::bar()`, it refers to a different `foo`, an absolute path from your
534 This will build and run:
538 Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
539 Running `target/debug/phrases`
540 Hello in English: Hello!
541 Goodbye in English: Goodbye.
542 Hello in Japanese: こんにちは
543 Goodbye in Japanese: さようなら
548 Rust offers several advanced options that can add compactness and
549 convenience to your `extern crate` and `use` statements. Here is an example:
552 extern crate phrases as sayings;
554 use sayings::japanese::greetings as ja_greetings;
555 use sayings::japanese::farewells::*;
556 use sayings::english::{self, greetings as en_greetings, farewells as en_farewells};
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());
567 What's going on here?
569 First, both `extern crate` and `use` allow renaming the thing that is being
570 imported. So the crate is still called "phrases", but here we will refer
571 to it as "sayings". Similarly, the first `use` statement pulls in the
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
574 ambiguity when importing similarly-named items from different places.
576 The second `use` statement uses a star glob to bring in all public symbols from
577 the `sayings::japanese::farewells` module. As you can see we can later refer to
578 the Japanese `goodbye` function with no module qualifiers. This kind of glob
579 should be used sparingly. It’s worth noting that it only imports the public
580 symbols, even if the code doing the globbing is in the same module.
582 The third `use` statement bears more explanation. It's using "brace expansion"
583 globbing to compress three `use` statements into one (this sort of syntax
584 may be familiar if you've written Linux shell scripts before). The
585 uncompressed form of this statement would be:
588 use sayings::english;
589 use sayings::english::greetings as en_greetings;
590 use sayings::english::farewells as en_farewells;
593 As you can see, the curly brackets compress `use` statements for several items
594 under the same path, and in this context `self` refers back to that path.
595 Note: The curly brackets cannot be nested or mixed with star globbing.