@@ -1770,7 +1770,7 @@ fn main() {
1770
1770
1771
1771
``` {notrust,ignore}
1772
1772
$ cargo build
1773
- Compiling guessing_game v0.1.0 (file:/home/steve/tmp /guessing_game)
1773
+ Compiling guessing_game v0.1.0 (file:/home/you/projects /guessing_game)
1774
1774
$
1775
1775
```
1776
1776
@@ -2042,7 +2042,7 @@ Let's try it out!
2042
2042
2043
2043
``` {notrust,ignore}
2044
2044
$ cargo build
2045
- Compiling guessing_game v0.1.0 (file:/home/steve/tmp /guessing_game)
2045
+ Compiling guessing_game v0.1.0 (file:/home/you/projects /guessing_game)
2046
2046
src/guessing_game.rs:22:15: 22:24 error: mismatched types: expected `uint` but found `core::option::Option<uint>` (expected uint but found enum core::option::Option)
2047
2047
src/guessing_game.rs:22 match cmp(input_num, secret_number) {
2048
2048
^~~~~~~~~
@@ -2246,7 +2246,7 @@ that `return`? If we give a non-number answer, we'll `return` and quit. Observe:
2246
2246
``` {notrust,ignore}
2247
2247
$ cargo build
2248
2248
Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
2249
- steve@computer:~/tmp/guessing_game $ ./target/guessing_game
2249
+ $ ./target/guessing_game
2250
2250
Guess the number!
2251
2251
The secret number is: 59
2252
2252
Please input your guess.
@@ -2462,19 +2462,361 @@ rest of your Rust education.
2462
2462
Now that you're an expert at the basics, it's time to learn about some of
2463
2463
Rust's more unique features.
2464
2464
2465
- # iterators
2465
+ # Crates and Modules
2466
2466
2467
- # Lambdas
2467
+ Rust features a strong module system, but it works a bit differently than in
2468
+ other programming languages. Rust's module system has two main components:
2469
+ ** crate** s, and ** module** s.
2470
+
2471
+ A crate is Rust's unit of independent compilation. Rust always compiles one
2472
+ crate at a time, producing either a library or an executable. However, executables
2473
+ usually depend on libraries, and many libraries depend on other libraries as well.
2474
+ To support this, crates can depend on other crates.
2475
+
2476
+ Each crate contains a hierarchy of modules. This tree starts off with a single
2477
+ module, called the ** crate root** . Within the crate root, we can declare other
2478
+ modules, which can contain other modules, as deeply as you'd like.
2479
+
2480
+ Note that we haven't mentioned anything about files yet. Rust does not impose a
2481
+ particular relationship between your filesystem structure and your module
2482
+ structure. That said, there is a conventional approach to how Rust looks for
2483
+ modules on the file system, but it's also overrideable.
2484
+
2485
+ Enough talk, let's build something! Let's make a new project called ` modules ` .
2486
+
2487
+ ``` {bash,ignore}
2488
+ $ cd ~/projects
2489
+ $ mkdir modules
2490
+ $ cd modules
2491
+ $ mkdir src
2492
+ ```
2493
+
2494
+ We need to make our two 'hello world' files. In ` src/main.rs ` :
2495
+
2496
+ ``` {rust}
2497
+ fn main() {
2498
+ println!("Hello, world!");
2499
+ }
2500
+ ```
2501
+
2502
+ And in ` Cargo.toml ` :
2503
+
2504
+ ``` {notrust,ignore}
2505
+ [package]
2506
+
2507
+ name = "modules"
2508
+ version = "0.1.0"
2509
+ authors = [ "someone@example.com" ]
2510
+ ```
2511
+
2512
+ Let's double check our work by compiling:
2513
+
2514
+ ``` {bash,ignore}
2515
+ $ cargo build
2516
+ Compiling modules v0.1.0 (file:/home/you/projects/modules)
2517
+ $ ./target/modules
2518
+ Hello, world!
2519
+ ```
2520
+
2521
+ Excellent! So, we already have a single crate here: our ` src/main.rs ` is a crate.
2522
+ Everything in that file is in the crate root. A crate that generates an executable
2523
+ defines a ` main ` function inside its root, as we've done here.
2524
+
2525
+ Let's define a new module inside our crate. Edit ` src/main.rs ` to look
2526
+ like this:
2527
+
2528
+ ```
2529
+ fn main() {
2530
+ println!("Hello, world!");
2531
+ }
2532
+
2533
+ mod hello {
2534
+ fn print_hello() {
2535
+ println!("Hello, world!");
2536
+ }
2537
+ }
2538
+ ```
2539
+
2540
+ We now have a module named ` hello ` inside of our crate root. Modules use
2541
+ ` snake_case ` naming, like functions and variable bindings.
2542
+
2543
+ Inside the ` hello ` module, we've defined a ` print_hello ` function. This will
2544
+ also print out our hello world message. Modules allow you to split up your
2545
+ program into nice neat boxes of functionality, grouping common things together,
2546
+ and keeping different things apart. It's kinda like having a set of shelves:
2547
+ a place for everything and everything in its place.
2548
+
2549
+ To call our ` print_hello ` function, we use the double colon (` :: ` ):
2550
+
2551
+ ``` {rust,ignore}
2552
+ hello::print_hello();
2553
+ ```
2554
+
2555
+ You've seen this before, with ` io::stdin() ` and ` rand::random() ` . Now you know
2556
+ how to make your own. However, crates and modules have rules about
2557
+ ** visibility** , which controls who exactly may use the functions defined in a
2558
+ given module. By default, everything in a module is private, which means that
2559
+ it can only be used by other functions in the same module. This will not
2560
+ compile:
2561
+
2562
+ ``` {rust,ignore}
2563
+ fn main() {
2564
+ hello::print_hello();
2565
+ }
2566
+
2567
+ mod hello {
2568
+ fn print_hello() {
2569
+ println!("Hello, world!");
2570
+ }
2571
+ }
2572
+ ```
2573
+
2574
+ It gives an error:
2575
+
2576
+ ``` {notrust,ignore}
2577
+ Compiling modules v0.1.0 (file:/home/you/projects/modules)
2578
+ src/modules.rs:2:5: 2:23 error: function `print_hello` is private
2579
+ src/modules.rs:2 hello::print_hello();
2580
+ ^~~~~~~~~~~~~~~~~~
2581
+ ```
2582
+
2583
+ To make it public, we use the ` pub ` keyword:
2584
+
2585
+ ``` {rust}
2586
+ fn main() {
2587
+ hello::print_hello();
2588
+ }
2589
+
2590
+ mod hello {
2591
+ pub fn print_hello() {
2592
+ println!("Hello, world!");
2593
+ }
2594
+ }
2595
+ ```
2596
+
2597
+ This will work:
2598
+
2599
+ ``` {notrust,ignore}
2600
+ $ cargo build
2601
+ Compiling modules v0.1.0 (file:/home/you/projects/modules)
2602
+ $
2603
+ ```
2604
+
2605
+ Before we move on, let me show you one more Cargo command: ` run ` . ` cargo run `
2606
+ is kind of like ` cargo build ` , but it also then runs the produced exectuable.
2607
+ Try it out:
2608
+
2609
+ ``` {notrust,ignore}
2610
+ $ cargo run
2611
+ Compiling modules v0.1.0 (file:/home/steve/tmp/modules)
2612
+ Running `target/modules`
2613
+ Hello, world!
2614
+ $
2615
+ ```
2616
+
2617
+ Nice!
2618
+
2619
+ There's a common pattern when you're building an executable: you build both an
2620
+ executable and a library, and put most of your logic in the library. That way,
2621
+ other programs can use that library to build their own functionality.
2622
+
2623
+ Let's do that with our project. If you remember, libraries and executables
2624
+ are both crates, so while our project has one crate now, let's make a second:
2625
+ one for the library, and one for the executable.
2626
+
2627
+ To make the second crate, open up ` src/lib.rs ` and put this code in it:
2628
+
2629
+ ``` {rust}
2630
+ mod hello {
2631
+ pub fn print_hello() {
2632
+ println!("Hello, world!");
2633
+ }
2634
+ }
2635
+ ```
2636
+
2637
+ And change your ` src/main.rs ` to look like this:
2638
+
2639
+ ``` {rust,ignore}
2640
+ extern crate modules;
2641
+
2642
+ fn main() {
2643
+ modules::hello::print_hello();
2644
+ }
2645
+ ```
2646
+
2647
+ There's been a few changes. First, we moved our ` hello ` module into its own
2648
+ file, ` src/lib.rs ` . This is the file that Cargo expects a library crate to
2649
+ be named, by convention.
2650
+
2651
+ Next, we added an ` extern crate modules ` to the top of our ` src/main.rs ` . This,
2652
+ as you can guess, lets Rust know that our crate relies on another, external
2653
+ crate. We also had to modify our call to ` print_hello ` : now that it's in
2654
+ another crate, we need to first specify the crate, then the module inside of it,
2655
+ then the function name.
2656
+
2657
+ This doesn't _ quite_ work yet. Try it:
2658
+
2659
+ ``` {notrust,ignore}
2660
+ $ cargo build
2661
+ Compiling modules v0.1.0 (file:/home/you/projects/modules)
2662
+ /home/you/projects/modules/src/lib.rs:2:5: 4:6 warning: code is never used: `print_hello`, #[warn(dead_code)] on by default
2663
+ /home/you/projects/modules/src/lib.rs:2 pub fn print_hello() {
2664
+ /home/you/projects/modules/src/lib.rs:3 println!("Hello, world!");
2665
+ /home/you/projects/modules/src/lib.rs:4 }
2666
+ /home/you/projects/modules/src/main.rs:4:5: 4:32 error: function `print_hello` is private
2667
+ /home/you/projects/modules/src/main.rs:4 modules::hello::print_hello();
2668
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~
2669
+ error: aborting due to previous error
2670
+ Could not compile `modules`.
2671
+ ```
2672
+
2673
+ First, we get a warning that some code is never used. Odd. Next, we get an error:
2674
+ ` print_hello ` is private, so we can't call it. Notice that the first error came
2675
+ from ` src/lib.rs ` , and the second came from ` src/main.rs ` : cargo is smart enough
2676
+ to build it all with one command. Also, after seeing the second error, the warning
2677
+ makes sense: we never actually call ` hello_world ` , because we're not allowed to!
2678
+
2679
+ Just like modules, crates also have private visibility by default. Any modules
2680
+ inside of a crate can only be used by other modules in the crate, unless they
2681
+ use ` pub ` . In ` src/lib.rs ` , change this line:
2682
+
2683
+ ``` {rust,ignore}
2684
+ mod hello {
2685
+ ```
2686
+
2687
+ To this:
2688
+
2689
+ ``` {rust,ignore}
2690
+ pub mod hello {
2691
+ ```
2692
+
2693
+ And everything should work:
2694
+
2695
+ ``` {notrust,ignore}
2696
+ $ cargo run
2697
+ Compiling modules v0.1.0 (file:/home/you/projects/modules)
2698
+ Running `target/modules`
2699
+ Hello, world!
2700
+ ```
2701
+
2702
+ Let's do one more thing: add a ` goodbye ` module as well. Imagine a ` src/lib.rs `
2703
+ that looks like this:
2704
+
2705
+ ``` {rust,ignore}
2706
+ pub mod hello {
2707
+ pub fn print_hello() {
2708
+ println!("Hello, world!");
2709
+ }
2710
+ }
2711
+
2712
+ pub mod goodbye {
2713
+ pub fn print_goodbye() {
2714
+ println!("Goodbye for now!");
2715
+ }
2716
+ }
2717
+ ```
2718
+
2719
+ Now, these two modules are pretty small, but imagine we've written a real, large
2720
+ program: they could both be huge. So maybe we want to move them into their own
2721
+ files. We can do that pretty easily, and there are two different conventions
2722
+ for doing it. Let's give each a try. First, make ` src/lib.rs ` look like this:
2723
+
2724
+ ``` {rust,ignore}
2725
+ pub mod hello;
2726
+ pub mod goodbye;
2727
+ ```
2728
+
2729
+ This tells Rust that this crate has two public modules: ` hello ` and ` goodbye ` .
2730
+
2731
+ Next, make a ` src/hello.rs ` that contains this:
2732
+
2733
+ ``` {rust,ignore}
2734
+ pub fn print_hello() {
2735
+ println!("Hello, world!");
2736
+ }
2737
+ ```
2738
+
2739
+ When we include a module like this, we don't need to make the ` mod ` declaration,
2740
+ it's just understood. This helps prevent 'rightward drift': when you end up
2741
+ indenting so many times that your code is hard to read.
2742
+
2743
+ Finally, make a new directory, ` src/goodbye ` , and make a new file in it,
2744
+ ` src/goodbye/mod.rs ` :
2745
+
2746
+ ``` {rust,ignore}
2747
+ pub fn print_goodbye() {
2748
+ println!("Bye for now!");
2749
+ }
2750
+ ```
2751
+
2752
+ Same deal, but we can make a folder with a ` mod.rs ` instead of ` mod_name.rs ` in
2753
+ the same directory. If you have a lot of modules, nested folders can make
2754
+ sense. For example, if the ` goodbye ` module had its _ own_ modules inside of
2755
+ it, putting all of that in a folder helps keep our directory structure tidy.
2756
+ And in fact, if you place the modules in separate files, they're required to be
2757
+ in separate folders.
2758
+
2759
+ This should all compile as usual:
2760
+
2761
+ ``` {notrust,ignore}
2762
+ $ cargo build
2763
+ Compiling modules v0.1.0 (file:/home/you/projects/modules)
2764
+ $
2765
+ ```
2766
+
2767
+ We've seen how the ` :: ` operator can be used to call into modules, but when
2768
+ we have deep nesting like ` modules::hello::say_hello ` , it can get tedious.
2769
+ That's why we have the ` use ` keyword.
2770
+
2771
+ ` use ` allows us to bring certain names into another scope. For example, here's
2772
+ our main program:
2773
+
2774
+ ``` {rust,ignore}
2775
+ extern crate modules;
2776
+
2777
+ fn main() {
2778
+ modules::hello::print_hello();
2779
+ }
2780
+ ```
2781
+
2782
+ We could instead write this:
2783
+
2784
+ ``` {rust,ignore}
2785
+ extern crate modules;
2786
+
2787
+ use modules::hello::print_hello;
2788
+
2789
+ fn main() {
2790
+ print_hello();
2791
+ }
2792
+ ```
2793
+
2794
+ By bringing ` print_hello ` into scope, we don't need to qualify it anymore. However,
2795
+ it's considered proper style to do write this code like like this:
2796
+
2797
+ ``` {rust,ignore}
2798
+ extern crate modules;
2799
+
2800
+ use modules::hello;
2801
+
2802
+ fn main() {
2803
+ hello::print_hello();
2804
+ }
2805
+ ```
2806
+
2807
+ By just bringing the module into scope, we can keep one level of namespacing.
2468
2808
2469
2809
# Testing
2470
2810
2471
- attributes
2811
+ ## Attributes
2472
2812
2473
- stability markers
2813
+ ## Stability Markers
2474
2814
2475
- # Crates and Modules
2815
+ # Pointers
2476
2816
2477
- visibility
2817
+ # Lambdas
2818
+
2819
+ # iterators
2478
2820
2479
2821
2480
2822
# Generics
0 commit comments