11% Crates and Modules
22
3- When a project starts getting large, it's considered a good software
3+ When a project starts getting large, it's considered good software
44engineering practice to split it up into a bunch of smaller pieces, and then
55fit them together. It's also important to have a well-defined interface, so
66that some of your functionality is private, and some is public. To facilitate
@@ -24,23 +24,23 @@ in different languages. To keep things simple, we'll stick to "greetings" and
2424two languages for those phrases to be in. We'll use this module layout:
2525
2626``` text
27- +-----------+
28- +---| greetings |
29- | +-----------+
30- +---------+ |
31- | english |---+
32- +---------+ | +-----------+
33- | +---| farewells |
34- +---------+ | +-----------+
27+ +-----------+
28+ +---| greetings |
29+ | +-----------+
30+ +---------+ |
31+ +--- | english |---+
32+ | +---------+ | +-----------+
33+ | +---| farewells |
34+ +---------+ | +-----------+
3535| phrases |---+
36- +---------+ | +-----------+
37- | +---| greetings |
38- +----------+ | +-----------+
39- | japanese |- --+
40- +----------+ |
41- | +-----------+
42- +---| farewells |
43- +-----------+
36+ +---------+ | +-----------+
37+ | +---| greetings |
38+ | +----------+ | +-----------+
39+ +--- | japanese |--+
40+ +----------+ |
41+ | +-----------+
42+ +---| farewells |
43+ +-----------+
4444```
4545
4646In this example, ` phrases ` is the name of our crate. All of the rest are
@@ -76,25 +76,19 @@ To define each of our modules, we use the `mod` keyword. Let's make our
7676` src/lib.rs ` look like this:
7777
7878```
79- // in src/lib.rs
80-
8179mod english {
8280 mod greetings {
83-
8481 }
8582
8683 mod farewells {
87-
8884 }
8985}
9086
9187mod japanese {
9288 mod greetings {
93-
9489 }
9590
9691 mod farewells {
97-
9892 }
9993}
10094```
@@ -145,11 +139,7 @@ mod english;
145139```
146140
147141If 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- ```
142+ ` english/mod.rs ` file with the contents of our module.
153143
154144Note that in these files, you don't need to re-declare the module: that's
155145already been done with the initial ` mod ` declaration.
@@ -181,10 +171,7 @@ $ tree .
181171` src/lib.rs ` is our crate root, and looks like this:
182172
183173``` {rust,ignore}
184- // in src/lib.rs
185-
186174mod english;
187-
188175mod japanese;
189176```
190177
@@ -195,10 +182,7 @@ chosen the second. Both `src/english/mod.rs` and `src/japanese/mod.rs` look
195182like this:
196183
197184``` {rust,ignore}
198- // both src/english/mod.rs and src/japanese/mod.rs
199-
200185mod greetings;
201-
202186mod farewells;
203187```
204188
@@ -214,8 +198,6 @@ both empty at the moment. Let's add some functions.
214198Put this in ` src/english/greetings.rs ` :
215199
216200``` rust
217- // in src/english/greetings.rs
218-
219201fn hello () -> String {
220202 " Hello!" . to_string ()
221203}
@@ -224,8 +206,6 @@ fn hello() -> String {
224206Put this in ` src/english/farewells.rs ` :
225207
226208``` rust
227- // in src/english/farewells.rs
228-
229209fn goodbye () -> String {
230210 " Goodbye." . to_string ()
231211}
@@ -248,8 +228,6 @@ about the module system.
248228Put this in ` src/japanese/farewells.rs ` :
249229
250230``` rust
251- // in src/japanese/farewells.rs
252-
253231fn goodbye () -> String {
254232 " さようなら" . to_string ()
255233}
@@ -265,11 +243,9 @@ another crate.
265243We have a library crate. Let's make an executable crate that imports and uses
266244our library.
267245
268- Make a ` src/main.rs ` and put this in it: (it won't quite compile yet)
246+ Make a ` src/main.rs ` and put this in it (it won't quite compile yet):
269247
270248``` rust,ignore
271- // in src/main.rs
272-
273249extern crate phrases;
274250
275251fn main() {
@@ -320,8 +296,6 @@ keyword. Let's focus on the `english` module first, so let's reduce our `src/mai
320296to just this:
321297
322298```{rust,ignore}
323- // in src/main.rs
324-
325299extern crate phrases;
326300
327301fn main() {
@@ -333,28 +307,20 @@ fn main() {
333307In our `src/lib.rs`, let' s add ` pub` to the ` english` module declaration:
334308
335309` ` ` {rust,ignore}
336- // in src/lib.rs
337-
338310pub mod english;
339-
340311mod japanese;
341312` ` `
342313
343314And in our ` src/english/mod.rs` , let' s make both `pub`:
344315
345316```{rust,ignore}
346- // in src/english/mod.rs
347-
348317pub mod greetings;
349-
350318pub mod farewells;
351319```
352320
353321In our `src/english/greetings.rs`, let' s add ` pub` to our ` fn` declaration:
354322
355323` ` ` {rust,ignore}
356- // in src/english/greetings.rs
357-
358324pub fn hello () -> String {
359325 " Hello!" .to_string()
360326}
@@ -363,8 +329,6 @@ pub fn hello() -> String {
363329And also in ` src/english/farewells.rs` :
364330
365331` ` ` {rust,ignore}
366- // in src/english/farewells.rs
367-
368332pub fn goodbye () -> String {
369333 " Goodbye." .to_string()
370334}
@@ -400,8 +364,6 @@ Rust has a `use` keyword, which allows us to import names into our local scope.
400364Let' s change our ` src/main.rs` to look like this:
401365
402366` ` ` {rust,ignore}
403- // in src/main.rs
404-
405367extern crate phrases;
406368
407369use phrases::english::greetings;
@@ -430,7 +392,7 @@ fn main() {
430392}
431393```
432394
433- But it is not idiomatic. This is significantly more likely to introducing a
395+ But it is not idiomatic: it is more likely to introduce a
434396naming conflict. In our short program, it' s not a big deal, but as it grows, it
435397becomes a problem. If we have conflicting names, Rust will give a compilation
436398error. For example, if we made the ` japanese` functions public, and tried to do
@@ -460,21 +422,19 @@ Could not compile `phrases`.
460422` ` `
461423
462424If we' re importing multiple names from the same module, we don' t have to type it out
463- twice. Rust has a shortcut syntax for writing this:
425+ twice. Instead of this:
464426
465427` ` ` {rust,ignore}
466428use phrases::english::greetings;
467429use phrases::english::farewells;
468430` ` `
469431
470- You use curly braces :
432+ We can use this shortcut :
471433
472434` ` ` {rust,ignore}
473435use phrases::english::{greetings, farewells};
474436` ` `
475437
476- These two declarations are equivalent, but the second is a lot less typing.
477-
478438# # Re-exporting with `pub use`
479439
480440You don' t just use `use` to shorten identifiers. You can also use it inside of your crate
@@ -484,8 +444,6 @@ interface that may not directly map to your internal code organization.
484444Let' s look at an example. Modify your ` src/main.rs` to read like this:
485445
486446` ` ` {rust,ignore}
487- // in src/main.rs
488-
489447extern crate phrases;
490448
491449use phrases::english::{greetings,farewells};
@@ -503,18 +461,13 @@ fn main() {
503461Then, modify your ` src/lib.rs` to make the ` japanese` mod public:
504462
505463` ` ` {rust,ignore}
506- // in src/lib.rs
507-
508464pub mod english;
509-
510465pub mod japanese;
511466` ` `
512467
513468Next, make the two functions public, first in ` src/japanese/greetings.rs` :
514469
515470` ` ` {rust,ignore}
516- // in src/japanese/greetings.rs
517-
518471pub fn hello () -> String {
519472 " こんにちは" .to_string()
520473}
@@ -523,8 +476,6 @@ pub fn hello() -> String {
523476And then in ` src/japanese/farewells.rs` :
524477
525478` ` ` {rust,ignore}
526- // in src/japanese/farewells.rs
527-
528479pub fn goodbye () -> String {
529480 " さようなら" .to_string()
530481}
@@ -533,13 +484,10 @@ pub fn goodbye() -> String {
533484Finally, modify your ` src/japanese/mod.rs` to read like this:
534485
535486` ` ` {rust,ignore}
536- // in src/japanese/mod.rs
537-
538487pub use self::greetings::hello;
539488pub use self::farewells::goodbye;
540489
541490mod greetings;
542-
543491mod farewells;
544492` ` `
545493
@@ -551,9 +499,9 @@ module, we now have a `phrases::japanese::hello()` function and a
551499`phrases::japanese::farewells::goodbye()`. Our internal organization doesn' t
552500define our external interface.
553501
554- Here we have a ` pub use` for each function we want to bring into the
502+ Here we have a ` pub use` for each function we want to bring into the
555503` japanese` scope. We could alternatively use the wildcard syntax to include
556- everything from ` greetings` into the current scope: ` pub use self::greetings::* ` .
504+ everything from ` greetings` into the current scope: ` pub use self::greetings::* ` .
557505
558506What about the ` self` ? Well, by default, ` use` declarations are absolute paths,
559507starting from your crate root. ` self` makes that path relative to your current
0 commit comments