diff --git a/src/doc/guide.md b/src/doc/guide.md index f896d37de93..c42cfe46fd5 100644 --- a/src/doc/guide.md +++ b/src/doc/guide.md @@ -2751,197 +2751,8 @@ $ cargo run Hello, world! ``` -Nice! - -There's a common pattern when you're building an executable: you build both an -executable and a library, and put most of your logic in the library. That way, -other programs can use that library to build their own functionality. - -Let's do that with our project. If you remember, libraries and executables -are both crates, so while our project has one crate now, let's make a second: -one for the library, and one for the executable. - -To make the second crate, open up `src/lib.rs` and put this code in it: - -```{rust} -mod hello { - pub fn print_hello() { - println!("Hello, world!"); - } -} -``` - -And change your `src/main.rs` to look like this: - -```{rust,ignore} -extern crate modules; - -fn main() { - modules::hello::print_hello(); -} -``` - -There's been a few changes. First, we moved our `hello` module into its own -file, `src/lib.rs`. This is the file that Cargo expects a library crate to -be named, by convention. - -Next, we added an `extern crate modules` to the top of our `src/main.rs`. This, -as you can guess, lets Rust know that our crate relies on another, external -crate. We also had to modify our call to `print_hello`: now that it's in -another crate, we need to specify that crate first. - -This doesn't _quite_ work yet. Try it: - -```{notrust,ignore} -$ cargo build - Compiling modules v0.0.1 (file:///home/you/projects/modules) -/home/you/projects/modules/src/lib.rs:2:5: 4:6 warning: code is never used: `print_hello`, #[warn(dead_code)] on by default -/home/you/projects/modules/src/lib.rs:2 pub fn print_hello() { -/home/you/projects/modules/src/lib.rs:3 println!("Hello, world!"); -/home/you/projects/modules/src/lib.rs:4 } -/home/you/projects/modules/src/main.rs:4:5: 4:32 error: function `print_hello` is private -/home/you/projects/modules/src/main.rs:4 modules::hello::print_hello(); - ^~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: aborting due to previous error -Could not compile `modules`. -``` - -First, we get a warning that some code is never used. Odd. Next, we get an error: -`print_hello` is private, so we can't call it. Notice that the first error came -from `src/lib.rs`, and the second came from `src/main.rs`: cargo is smart enough -to build it all with one command. Also, after seeing the second error, the warning -makes sense: we never actually call `hello_world`, because we're not allowed to! - -Just like modules, crates also have private visibility by default. Any modules -inside of a crate can only be used by other modules in the crate, unless they -use `pub`. In `src/lib.rs`, change this line: - -```{rust,ignore} -mod hello { -``` - -To this: - -```{rust,ignore} -pub mod hello { -``` - -And everything should work: - -```{notrust,ignore} -$ cargo run - Compiling modules v0.0.1 (file:///home/you/projects/modules) - Running `target/modules` -Hello, world! -``` - -Let's do one more thing: add a `goodbye` module as well. Imagine a `src/lib.rs` -that looks like this: - -```{rust,ignore} -pub mod hello { - pub fn print_hello() { - println!("Hello, world!"); - } -} - -pub mod goodbye { - pub fn print_goodbye() { - println!("Goodbye for now!"); - } -} -``` - -Now, these two modules are pretty small, but imagine we've written a real, large -program: they could both be huge. So maybe we want to move them into their own -files. We can do that pretty easily, and there are two different conventions -for doing it. Let's give each a try. First, make `src/lib.rs` look like this: - -```{rust,ignore} -pub mod hello; -pub mod goodbye; -``` - -This tells Rust that this crate has two public modules: `hello` and `goodbye`. - -Next, make a `src/hello.rs` that contains this: - -```{rust,ignore} -pub fn print_hello() { - println!("Hello, world!"); -} -``` - -When we include a module like this, we don't need to make the `mod` declaration -in `hello.rs`, because it's already been declared in `lib.rs`. `hello.rs` just -contains the body of the module which is defined (by the `pub mod hello`) in -`lib.rs`. This helps prevent 'rightward drift': when you end up indenting so -many times that your code is hard to read. - -Finally, make a new directory, `src/goodbye`, and make a new file in it, -`src/goodbye/mod.rs`: - -```{rust,ignore} -pub fn print_goodbye() { - println!("Bye for now!"); -} -``` - -Same deal, but we can make a folder with a `mod.rs` instead of `mod_name.rs` in -the same directory. If you have a lot of modules, nested folders can make -sense. For example, if the `goodbye` module had its _own_ modules inside of -it, putting all of that in a folder helps keep our directory structure tidy. -And in fact, if you place the modules in separate files, they're required to be -in separate folders. - -This should all compile as usual: - -```{notrust,ignore} -$ cargo build - Compiling modules v0.0.1 (file:///home/you/projects/modules) -``` - -We've seen how the `::` operator can be used to call into modules, but when -we have deep nesting like `modules::hello::say_hello`, it can get tedious. -That's why we have the `use` keyword. - -`use` allows us to bring certain names into another scope. For example, here's -our main program: - -```{rust,ignore} -extern crate modules; - -fn main() { - modules::hello::print_hello(); -} -``` - -We could instead write this: - -```{rust,ignore} -extern crate modules; - -use modules::hello::print_hello; - -fn main() { - print_hello(); -} -``` - -By bringing `print_hello` into scope, we don't need to qualify it anymore. However, -it's considered proper style to do write this code like like this: - -```{rust,ignore} -extern crate modules; - -use modules::hello; - -fn main() { - hello::print_hello(); -} -``` - -By just bringing the module into scope, we can keep one level of namespacing. +Nice! There are more things we can do with modules, including moving them into +their own files. This is enough detail for now. # Testing