1
1
% Crates and Modules
2
2
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
4
4
engineering practice to split it up into a bunch of smaller pieces, and then
5
5
fit them together. It's also important to have a well-defined interface, so
6
6
that 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
24
24
two languages for those phrases to be in. We'll use this module layout:
25
25
26
26
``` text
27
- +-----------+
28
- +---| greetings |
29
- | +-----------+
30
- +---------+ |
31
- | english |---+
32
- +---------+ | +-----------+
33
- | +---| farewells |
34
- +---------+ | +-----------+
27
+ +-----------+
28
+ +---| greetings |
29
+ | +-----------+
30
+ +---------+ |
31
+ +--- | english |---+
32
+ | +---------+ | +-----------+
33
+ | +---| farewells |
34
+ +---------+ | +-----------+
35
35
| phrases |---+
36
- +---------+ | +-----------+
37
- | +---| greetings |
38
- +----------+ | +-----------+
39
- | japanese |- --+
40
- +----------+ |
41
- | +-----------+
42
- +---| farewells |
43
- +-----------+
36
+ +---------+ | +-----------+
37
+ | +---| greetings |
38
+ | +----------+ | +-----------+
39
+ +--- | japanese |--+
40
+ +----------+ |
41
+ | +-----------+
42
+ +---| farewells |
43
+ +-----------+
44
44
```
45
45
46
46
In 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
76
76
` src/lib.rs ` look like this:
77
77
78
78
```
79
- // in src/lib.rs
80
-
81
79
mod english {
82
80
mod greetings {
83
-
84
81
}
85
82
86
83
mod farewells {
87
-
88
84
}
89
85
}
90
86
91
87
mod japanese {
92
88
mod greetings {
93
-
94
89
}
95
90
96
91
mod farewells {
97
-
98
92
}
99
93
}
100
94
```
@@ -145,11 +139,7 @@ mod english;
145
139
```
146
140
147
141
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
- ```
142
+ ` english/mod.rs ` file with the contents of our module.
153
143
154
144
Note that in these files, you don't need to re-declare the module: that's
155
145
already been done with the initial ` mod ` declaration.
@@ -181,10 +171,7 @@ $ tree .
181
171
` src/lib.rs ` is our crate root, and looks like this:
182
172
183
173
``` {rust,ignore}
184
- // in src/lib.rs
185
-
186
174
mod english;
187
-
188
175
mod japanese;
189
176
```
190
177
@@ -195,10 +182,7 @@ chosen the second. Both `src/english/mod.rs` and `src/japanese/mod.rs` look
195
182
like this:
196
183
197
184
``` {rust,ignore}
198
- // both src/english/mod.rs and src/japanese/mod.rs
199
-
200
185
mod greetings;
201
-
202
186
mod farewells;
203
187
```
204
188
@@ -214,8 +198,6 @@ both empty at the moment. Let's add some functions.
214
198
Put this in ` src/english/greetings.rs ` :
215
199
216
200
``` rust
217
- // in src/english/greetings.rs
218
-
219
201
fn hello () -> String {
220
202
" Hello!" . to_string ()
221
203
}
@@ -224,8 +206,6 @@ fn hello() -> String {
224
206
Put this in ` src/english/farewells.rs ` :
225
207
226
208
``` rust
227
- // in src/english/farewells.rs
228
-
229
209
fn goodbye () -> String {
230
210
" Goodbye." . to_string ()
231
211
}
@@ -248,8 +228,6 @@ about the module system.
248
228
Put this in ` src/japanese/farewells.rs ` :
249
229
250
230
``` rust
251
- // in src/japanese/farewells.rs
252
-
253
231
fn goodbye () -> String {
254
232
" さようなら" . to_string ()
255
233
}
@@ -265,11 +243,9 @@ another crate.
265
243
We have a library crate. Let's make an executable crate that imports and uses
266
244
our library.
267
245
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):
269
247
270
248
``` rust,ignore
271
- // in src/main.rs
272
-
273
249
extern crate phrases;
274
250
275
251
fn main() {
@@ -320,8 +296,6 @@ keyword. Let's focus on the `english` module first, so let's reduce our `src/mai
320
296
to just this:
321
297
322
298
```{rust,ignore}
323
- // in src/main.rs
324
-
325
299
extern crate phrases;
326
300
327
301
fn main() {
@@ -333,28 +307,20 @@ fn main() {
333
307
In our `src/lib.rs`, let' s add ` pub` to the ` english` module declaration:
334
308
335
309
` ` ` {rust,ignore}
336
- // in src/lib.rs
337
-
338
310
pub mod english;
339
-
340
311
mod japanese;
341
312
` ` `
342
313
343
314
And in our ` src/english/mod.rs` , let' s make both `pub`:
344
315
345
316
```{rust,ignore}
346
- // in src/english/mod.rs
347
-
348
317
pub mod greetings;
349
-
350
318
pub mod farewells;
351
319
```
352
320
353
321
In our `src/english/greetings.rs`, let' s add ` pub` to our ` fn` declaration:
354
322
355
323
` ` ` {rust,ignore}
356
- // in src/english/greetings.rs
357
-
358
324
pub fn hello () -> String {
359
325
" Hello!" .to_string()
360
326
}
@@ -363,8 +329,6 @@ pub fn hello() -> String {
363
329
And also in ` src/english/farewells.rs` :
364
330
365
331
` ` ` {rust,ignore}
366
- // in src/english/farewells.rs
367
-
368
332
pub fn goodbye () -> String {
369
333
" Goodbye." .to_string()
370
334
}
@@ -400,8 +364,6 @@ Rust has a `use` keyword, which allows us to import names into our local scope.
400
364
Let' s change our ` src/main.rs` to look like this:
401
365
402
366
` ` ` {rust,ignore}
403
- // in src/main.rs
404
-
405
367
extern crate phrases;
406
368
407
369
use phrases::english::greetings;
@@ -430,7 +392,7 @@ fn main() {
430
392
}
431
393
```
432
394
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
434
396
naming conflict. In our short program, it' s not a big deal, but as it grows, it
435
397
becomes a problem. If we have conflicting names, Rust will give a compilation
436
398
error. For example, if we made the ` japanese` functions public, and tried to do
@@ -460,21 +422,19 @@ Could not compile `phrases`.
460
422
` ` `
461
423
462
424
If 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:
464
426
465
427
` ` ` {rust,ignore}
466
428
use phrases::english::greetings;
467
429
use phrases::english::farewells;
468
430
` ` `
469
431
470
- You use curly braces :
432
+ We can use this shortcut :
471
433
472
434
` ` ` {rust,ignore}
473
435
use phrases::english::{greetings, farewells};
474
436
` ` `
475
437
476
- These two declarations are equivalent, but the second is a lot less typing.
477
-
478
438
# # Re-exporting with `pub use`
479
439
480
440
You 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.
484
444
Let' s look at an example. Modify your ` src/main.rs` to read like this:
485
445
486
446
` ` ` {rust,ignore}
487
- // in src/main.rs
488
-
489
447
extern crate phrases;
490
448
491
449
use phrases::english::{greetings,farewells};
@@ -503,18 +461,13 @@ fn main() {
503
461
Then, modify your ` src/lib.rs` to make the ` japanese` mod public:
504
462
505
463
` ` ` {rust,ignore}
506
- // in src/lib.rs
507
-
508
464
pub mod english;
509
-
510
465
pub mod japanese;
511
466
` ` `
512
467
513
468
Next, make the two functions public, first in ` src/japanese/greetings.rs` :
514
469
515
470
` ` ` {rust,ignore}
516
- // in src/japanese/greetings.rs
517
-
518
471
pub fn hello () -> String {
519
472
" こんにちは" .to_string()
520
473
}
@@ -523,8 +476,6 @@ pub fn hello() -> String {
523
476
And then in ` src/japanese/farewells.rs` :
524
477
525
478
` ` ` {rust,ignore}
526
- // in src/japanese/farewells.rs
527
-
528
479
pub fn goodbye () -> String {
529
480
" さようなら" .to_string()
530
481
}
@@ -533,13 +484,10 @@ pub fn goodbye() -> String {
533
484
Finally, modify your ` src/japanese/mod.rs` to read like this:
534
485
535
486
` ` ` {rust,ignore}
536
- // in src/japanese/mod.rs
537
-
538
487
pub use self::greetings::hello;
539
488
pub use self::farewells::goodbye;
540
489
541
490
mod greetings;
542
-
543
491
mod farewells;
544
492
` ` `
545
493
@@ -551,9 +499,9 @@ module, we now have a `phrases::japanese::hello()` function and a
551
499
`phrases::japanese::farewells::goodbye()`. Our internal organization doesn' t
552
500
define our external interface.
553
501
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
555
503
` 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::* ` .
557
505
558
506
What about the ` self` ? Well, by default, ` use` declarations are absolute paths,
559
507
starting from your crate root. ` self` makes that path relative to your current
0 commit comments