Fancy apostrophes/single quotes

Or italics when introducing new terms.
This commit is contained in:
Carol (Nichols || Goulding) 2016-11-03 14:10:32 -04:00
parent 0450d6aacc
commit 8260c118f9
4 changed files with 91 additions and 91 deletions

View File

@ -1,7 +1,7 @@
# Modules
When you start writing programs in Rust, your code might live solely in the
`main` function. As your code grows, you'll eventually move functionality out
`main` function. As your code grows, youll eventually move functionality out
into other functions, both for re-use and for better organization. By splitting
your code up into smaller chunks, each chunk is easier to understand on its
own. But what happens if find yourself with too many functions? Rust has a
@ -12,12 +12,12 @@ In the same way that you extract lines of code into a function, you can extract
functions (and other code like structs and enums too) into different modules. A
*module* is a namespace that contains definitions of functions or types, and
you can choose whether those definitions are visible outside their module
(public) or not (private). Here's an overview of how modules work:
(public) or not (private). Heres an overview of how modules work:
* You declare a new module with the keyword `mod`
* By default, everything is set as private, but you can use the `pub` keyword
to make the module public, and therefore visible outside of the namespace.
* The `use` keyword allows you to bring modules, or the definitions inside
modules, into scope so that it's easier to refer to them.
modules, into scope so that its easier to refer to them.
We'll take a look at each of these parts and see how they fit into the whole.
Well take a look at each of these parts and see how they fit into the whole.

View File

@ -1,16 +1,16 @@
## `mod` and the Filesystem
We'll start our module example by making a new project with Cargo, but instead
of creating a binary crate, we're going to make a library crate: a project that
Well start our module example by making a new project with Cargo, but instead
of creating a binary crate, were going to make a library crate: a project that
other people can pull into their projects as a dependency. We saw this with the
`rand` crate in Chapter 2.
We'll create a skeleton of a library that provides some general networking
functionality; we're going to concentrate on the organization of the modules
and functions, but not worry about what code goes in the function bodies. We'll
Well create a skeleton of a library that provides some general networking
functionality; were going to concentrate on the organization of the modules
and functions, but not worry about what code goes in the function bodies. Well
call our library `communicator`. By default, cargo will create a library unless
another type of project is specified, so if we leave off the `--bin` option
that we've been using so far our project will be a library:
that weve been using so far our project will be a library:
```bash
$ cargo new communicator
@ -18,7 +18,7 @@ $ cd communicator
```
Notice that Cargo generated *src/lib.rs* instead of *src/main.rs*. Inside
*src/lib.rs* we'll find this:
*src/lib.rs* well find this:
Filename: src/lib.rs
@ -32,21 +32,21 @@ mod tests {
```
Cargo creates an empty test to help us get our library started, rather
than the "Hello, world!" binary that we get with the `--bin` option. We'll look
than the "Hello, world!" binary that we get with the `--bin` option. Well look
at the `#[]` and `mod tests` syntax a little later, but for now just make sure
to leave it in your *src/lib.rs*.
Since we don't have a *src/main.rs*, there's nothing for Cargo to execute with
Since we dont have a *src/main.rs*, theres nothing for Cargo to execute with
the `cargo run` command. Therefore, we will be using the `cargo build` command
to only compile our library crate's code.
to only compile our library crates code.
We're going to look at different options for organizing your library's code
Were going to look at different options for organizing your librarys code
which will be suitable in a variety of situations, depending on the intentions
you have for your code.
### Module Definitions
For our `communicator` networking library, we're first going to define a module
For our `communicator` networking library, were first going to define a module
named `network` that contains the definition of a function called `connect`.
Every module definition in Rust starts with the `mod` keyword. Add this code to
the beginning of the *lib.rs* file, above the test code:
@ -92,7 +92,7 @@ in *src/lib.rs*
Now we have a `network::connect` function and a `client::connect` function.
These can have completely different functionality, and the function names do
not conflict with each other since they're in different modules.
not conflict with each other since theyre in different modules.
We can also put modules inside of modules. This can be useful as your modules
grow to keep related functionality organized together and separate
@ -122,11 +122,11 @@ Listing 7-2: Moving the `client` module inside of the `network` module
In your *src/lib.rs* file, replace the existing `mod network` and `mod client`
definitions with this one that has the `client` module as an inner module of
`network`. Now we have the functions `network::connect` and
`network::client::connect`: again, the two functions named `connect` don't
conflict with each other since they're in different namespaces.
`network::client::connect`: again, the two functions named `connect` dont
conflict with each other since theyre in different namespaces.
In this way, modules form a hierarchy. The contents of `src/lib.rs` are at the
topmost level, and the submodules are at lower levels. Here's what the
topmost level, and the submodules are at lower levels. Heres what the
organization of our example from Listing 7-1 looks like when thought of this
way:
@ -136,7 +136,7 @@ communicator
└── client
```
And here's the example from Listing 7-2:
And heres the example from Listing 7-2:
```text
communicator
@ -146,16 +146,16 @@ communicator
You can see that in Listing 7-2, `client` is a child of the `network` module,
rather than a sibling. More complicated projects can have a lot of modules, and
they'll need to be orgnaized logically in order to keep track of them. What
theyll need to be orgnaized logically in order to keep track of them. What
"logically" means in your project is up to you and depends on how you and users
of your library think about your project's domain. Use the techniques we've
of your library think about your projects domain. Use the techniques weve
shown here to create side-by-side modules and nested modules in whatever
structure you would like.
### Moving Modules to Other Files
Modules form a hierarchical structure, much like another structure in computing
that you're used to: file systems! We can use Rust's module system along with
that youre used to: file systems! We can use Rusts module system along with
multiple files to split Rust projects up so that not everything lives in
*src/lib.rs*. For this example, we will start with this code in *src/lib.rs*:
@ -195,7 +195,7 @@ communicator
If these modules had many functions, and each function was getting long, we
would have to scroll through this file to find the code we wanted to work with.
This would be a good reason to pull each of the `client`, `network`, and
`server` modules out of *src/lib.rs* and into their own files. Let's start by
`server` modules out of *src/lib.rs* and into their own files. Lets start by
extracting the `client` module into another file. First, replace the `client`
module code in *src/lib.rs* with the following:
@ -217,9 +217,9 @@ mod network {
<!-- I will add wingdings/ghosting in libreoffice /Carol -->
We're still *defining* the `client` module here, but by removing the curly
Were still *defining* the `client` module here, but by removing the curly
braces and definitions inside the `client` module and replacing them with a
semicolon, we're letting Rust know to look in another location for the code
semicolon, were letting Rust know to look in another location for the code
defined inside that module.
So now we need to create the external file with that module name. Create a
@ -234,17 +234,17 @@ fn connect() {
}
```
Note that we don't need a `mod` declaration in this file; that's because we
Note that we dont need a `mod` declaration in this file; thats because we
already declared the `client` module with `mod` in `src/lib.rs`. This file just
provides the *contents* of the `client` module. If we put a `mod client` here,
we'd be giving the `client` module its own submodule named `client`!
wed be giving the `client` module its own submodule named `client`!
Rust only knows to look in *src/lib.rs* by default. If we want to add more
files to our project, we need to tell Rust in *src/lib.rs* to look in other
files; this is why `mod client` needs to be defined in *src/lib.rs* and can't
files; this is why `mod client` needs to be defined in *src/lib.rs* and cant
be defined in *src/client.rs*.
Now, everything should compile successfully, though you'll get a few warnings.
Now, everything should compile successfully, though youll get a few warnings.
Remember to use `cargo build` instead of `cargo run` since we have a library
crate rather than a binary crate:
@ -271,11 +271,11 @@ warning: function is never used: `connect`, #[warn(dead_code)] on by default
| ^
```
These warnings tell us that we have functions that are never used. Don't worry
about those warnings for now; we'll address them later in the chapter. The good
news is that they're just warnings; our project was built successfully!
These warnings tell us that we have functions that are never used. Dont worry
about those warnings for now; well address them later in the chapter. The good
news is that theyre just warnings; our project was built successfully!
Let's extract the `network` module into its own file next, using the same
Lets extract the `network` module into its own file next, using the same
pattern. In `src/lib.rs`, delete the body of the `network` module and add a
semicolon to the declaration, like so:
@ -305,10 +305,10 @@ Notice that we still have a `mod` declaration within this module file;
this is because we still want `server` to be a sub-module of `network`.
Now run `cargo build` again. Success! We have one more module to extract:
`server`. Because it's a sub-module—that is, a module within a module—our
current tactic of extracting a module into a file named after that module won't
work. We're going to try anyway so that we can see the error. First change
*src/network.rs* to have `mod server;` instead of the `server` module's
`server`. Because its a sub-module—that is, a module within a module—our
current tactic of extracting a module into a file named after that module wont
work. Were going to try anyway so that we can see the error. First change
*src/network.rs* to have `mod server;` instead of the `server` modules
contents:
Filename: src/network.rs
@ -330,7 +330,7 @@ fn connect() {
}
```
When we try to `cargo build`, we'll get this error:
When we try to `cargo build`, well get this error:
```bash
$ cargo build
@ -360,10 +360,10 @@ Listing 7-4: Error when trying to extract the `server` submodule into
The error says we `cannot declare a new module at this location` and is
pointing to the `mod server;` line in `src/network.rs`. So `src/network.rs` is
different than `src/lib.rs` somehow; let's keep reading to understand why.
different than `src/lib.rs` somehow; lets keep reading to understand why.
The note in the middle of Listing 7-4 is actually pretty helpful, as it points
out something we haven't yet talked about doing:
out something we havent yet talked about doing:
> note: maybe move this module `network` to its own directory via
`network/mod.rs`
@ -371,7 +371,7 @@ out something we haven't yet talked about doing:
Instead of continuing to follow the same file naming pattern we used
previously, we can do what the note suggests:
1. Make a new *directory* named *network*, the parent module's name
1. Make a new *directory* named *network*, the parent modules name
2. Move the *src/network.rs* file into the new *network* directory and rename
it so that it is now *src/network/mod.rs*
3. Move the submodule file *src/server.rs* into the *network* directory
@ -384,7 +384,7 @@ $ mv src/network.rs src/network/mod.rs
$ mv src/server.rs src/network
```
Now if we try to `cargo build`, compilation will work (we'll still have
Now if we try to `cargo build`, compilation will work (well still have
warnings though). Our module layout still looks like this, which is exactly the
same as it did when we had all the code in *src/lib.rs* in Listing 7-3:
@ -410,10 +410,10 @@ So when we wanted to extract the `network::server` module, why did we have to
also change the *src/network.rs* file into the *src/network/mod.rs* file, and
also put the code for `network::server` in the `network` directory in
*src/network/server.rs*, instead of just being able to extract the
*network::server* into *src/server.rs*? The reason is that Rust wouldn't be
*network::server* into *src/server.rs*? The reason is that Rust wouldnt be
able to tell that `server` was supposed to be a submodule of `network` if the
*server.rs* file was in the *src* directory. To make it clearer why Rust can't
tell, let's consider a different example where we have this module hierarchy
*server.rs* file was in the *src* directory. To make it clearer why Rust cant
tell, lets consider a different example where we have this module hierarchy
with all the definitions in *src/lib.rs*:
```text
@ -427,7 +427,7 @@ In this example, we have three modules again, `client`, `network`, and
`network::client`. If we follow the same steps we originally did above for
extracting modules into files, for the `client` module we would create
*src/client.rs*. For the `network` module, we would create *src/network.rs*.
Then we wouldn't be able to extract the `network::client` module into a
Then we wouldnt be able to extract the `network::client` module into a
*src/client.rs* file, because that already exists for the top-level `client`
module! If we put the code in both the `client` and `network::client` modules
in the *src/client.rs* file, Rust would not have any way to know whether the
@ -459,7 +459,7 @@ In summary, these are the rules of modules with regards to files:
│   └── mod.rs (contains the declarations in `foo`, including `mod bar`)
```
* The modules themselves should be declared in their parent module's file using
* The modules themselves should be declared in their parent modules file using
the `mod` keyword.
Next, we'll talk about the `pub` keyword, and get rid of those warnings!
Next, well talk about the `pub` keyword, and get rid of those warnings!

View File

@ -27,13 +27,13 @@ warning: function is never used: `connect`, #[warn(dead_code)] on by default
| ^
```
So why are we receiving these warnings? After all, we're building a library
So why are we receiving these warnings? After all, were building a library
with functions that are intended to be used by our *users*, and not necessarily
by us within our own project, so it shouldn't matter that these `connect`
by us within our own project, so it shouldnt matter that these `connect`
functions go unused. The point of creating them is that they will be used by
another project and not our own.
To understand why this program invokes these warnings, let's try using the
To understand why this program invokes these warnings, lets try using the
`connect` library as if we were another project, calling it externally. We can
do that by creating a binary crate in the same directory as our library crate,
by making a `src/main.rs` file containing this code:
@ -56,7 +56,7 @@ quite common for executable projects: most functionality is in a library crate,
and the binary crate uses that library crate. This way, other programs can also
use the library crate, and its a nice separation of concerns.
Our binary crate right now just calls our library's `connect` function from the
Our binary crate right now just calls our librarys `connect` function from the
`client` module. However, invoking `cargo build` will now give us an error
after the warnings:
@ -69,9 +69,9 @@ error: module `client` is private
```
Ah ha! This tells us that the `client` module is private, and this is the crux
of the warnings. It's also the first time we've run into the concepts of
'public' and 'private' in the context of Rust. The default state of all code in
Rust is private: no one else is allowed to use the code. If you don't use a
of the warnings. Its also the first time weve run into the concepts of
*public* and *private* in the context of Rust. The default state of all code in
Rust is private: no one else is allowed to use the code. If you dont use a
private function within your own program, since your own program is the only
code allowed to use that function, Rust will warn you that the function has
gone unused.
@ -80,15 +80,15 @@ Once we specify that a function like `client::connect` is public, not only will
our call to that function from our binary crate be allowed, the warning that
the function is unused will go away. Marking something public lets Rust know
that we intend for the function to be used by code outside of our program. Rust
considers the theoretical external usage that's now possible as the function
considers the theoretical external usage thats now possible as the function
"being used." Thus, when something is marked as public, Rust will not require
that it's used in our own program and will stop warning that the item is
that its used in our own program and will stop warning that the item is
unused.
### Making a Function Public
To tell Rust to make something public, we add the `pub` keyword to the start of
the declaration of the item we want to make public. We'll focus on fixing the
the declaration of the item we want to make public. Well focus on fixing the
warning that tells us that `client::connect` has gone unused for now, as well
as the "module `client` is private" error from our binary crate. Modify
`src/lib.rs` to make the `client` module public, like so:
@ -101,7 +101,7 @@ pub mod client;
mod network;
```
The `pub` goes right before `mod`. Let's try building again:
The `pub` goes right before `mod`. Lets try building again:
```bash
<warnings>
@ -113,7 +113,7 @@ error: function `connect` is private
```
Hooray! We have a different error! Yes, different error messages are a cause
for celebration. The new error says "function `connect` is private", so let's
for celebration. The new error says "function `connect` is private", so lets
edit `src/client.rs` to make `client::connect` public too:
Filename: src/client.rs
@ -141,15 +141,15 @@ warning: function is never used: `connect`, #[warn(dead_code)] on by default
It compiled, and the warning about `client::connect` not being used is gone!
Unused code warnings don't always indicate that something needs to be made
public: if you *didn't* want these functions to be part of your public API,
Unused code warnings dont always indicate that something needs to be made
public: if you *didnt* want these functions to be part of your public API,
unused code warnings could be alerting you to code you no longer needed and can
safely delete. They could also be alerting you to a bug, if you had just
accidentally removed all places within your library where this function is
called.
In our case though, we *do* want the other two functions to be part of our
crate's public API, so let's mark them as `pub` as well to try to get rid of
crates public API, so lets mark them as `pub` as well to try to get rid of
the remaining warnings. Modify `src/network/mod.rs` to be:
Filename: src/network/mod.rs
@ -177,10 +177,10 @@ warning: function is never used: `connect`, #[warn(dead_code)] on by default
| ^
```
Hmmm, we're still getting an unused function warning even though
Hmmm, were still getting an unused function warning even though
`network::connect` is set to `pub`. This is because the function is public
within the module, but the `network` module that the function resides in is not
public. We're working from the interior of the library out this time, where
public. Were working from the interior of the library out this time, where
with `client::connect` we worked from the outside in. We need to change
`src/lib.rs` to make `network` public too:
@ -215,8 +215,8 @@ Overall, these are the rules for item visibility:
### Privacy Examples
Let's look at a few more examples to get some practice. Create a new libary
project and enter the code in Listing 7-5 into your new project's `src/lib.rs`:
Lets look at a few more examples to get some practice. Create a new libary
project and enter the code in Listing 7-5 into your new projects `src/lib.rs`:
Filename: src/lib.rs
@ -271,7 +271,7 @@ function is not allowed to call `outermost::inside::inner_function` or
Here are some suggestions for changing the code in an attempt to fix the
errors. Before you try each one, make a guess as to whether it will fix the
errors, then compile to see if you're right and use the privacy rules to
errors, then compile to see if youre right and use the privacy rules to
understand why.
* What if the `inside` module was public?
@ -283,4 +283,4 @@ understand why.
Feel free to design more experiments and try them out!
Next, let's talk about bringing items into a scope with the `use` keyword.
Next, lets talk about bringing items into a scope with the `use` keyword.

View File

@ -1,6 +1,6 @@
## Importing Names
We've covered how to call functions defined within a module using the module
Weve covered how to call functions defined within a module using the module
name as part of the call, as in the call to the `namespaces` function shown
here in Listing 7-6.
@ -21,7 +21,7 @@ fn main() {
```
<caption>
Listing 7-6: Calling a function by fully specifying its enclosing module's
Listing 7-6: Calling a function by fully specifying its enclosing modules
namespaces
</caption>
@ -30,9 +30,9 @@ Luckily, Rust has a keyword to make these calls more concise.
### Concise Imports with `use`
Rust's `use` keyword works to shorten lengthy function calls by bringing the
modules of the function you want to call into a scope. Here's an example of
bringing the `a::series::of` namespace into a binary crate's root scope:
Rusts `use` keyword works to shorten lengthy function calls by bringing the
modules of the function you want to call into a scope. Heres an example of
bringing the `a::series::of` namespace into a binary crates root scope:
Filename: src/main.rs
@ -57,7 +57,7 @@ we would want to refer to the `of` namespace, instead of having to say
`a::series::of`, we can replace that with `of`.
The `use` keyword brings only what we have specified into scope; it does not
bring children of modules into scope. That's why we still have to say
bring children of modules into scope. Thats why we still have to say
`of::namespaces` when we want to call the `namespaces` function.
We could have chosen to bring the function itself into scope, by instead
@ -82,8 +82,8 @@ fn main() {
This allows us to exclude any of the modules and just reference the function at
the callsite.
Since enums also form this kind of namespace, we can import an enum's variants
with `use` as well. For any kind of `use` statement, if you're importing
Since enums also form this kind of namespace, we can import an enums variants
with `use` as well. For any kind of `use` statement, if youre importing
multiple items from one namespace, you can list them using curly braces and
commas in the last position, like so:
@ -99,7 +99,7 @@ use TrafficLight::{Red, Yellow};
fn main() {
let red = Red;
let yellow = Yellow;
let green = TrafficLight::Green; // because we didn't `use` TrafficLight::Green
let green = TrafficLight::Green; // because we didnt `use` TrafficLight::Green
}
```
@ -124,14 +124,14 @@ fn main() {
}
```
The `*` is called a 'glob', and it will import everything that's visible inside
The `*` is called a *glob*, and it will import everything thats visible inside
of the namespace. Globs should be used sparingly: they are convenient, but you
might also pull in more things than you expected and cause naming conflicts.
### Using `super` to Access a Parent Module
As you now know, when you create a library crate, Cargo makes a `tests` module
for you. Let's go into more detail about that now. In your `communicator`
for you. Lets go into more detail about that now. In your `communicator`
project, open `src/lib.rs`.
Filename: src/lib.rs
@ -149,7 +149,7 @@ mod tests {
}
```
We'll explain more about testing in Chapter 12, but parts of this should make
Well explain more about testing in Chapter 12, but parts of this should make
sense now: we have a module named `tests` that lives next to our other modules
and contains one function named `it_works`. Even though there are special
annotations, the `tests` module is just another module! So our module hierarchy
@ -164,9 +164,9 @@ communicator
```
Tests are for exercising the code within our library, so let's try to call
Tests are for exercising the code within our library, so lets try to call
our `client::connect` function from this `it_works` function, even though
we're not going to be checking any functionality right now:
were not going to be checking any functionality right now:
Filename: src/lib.rs
@ -198,7 +198,7 @@ warning: function is never used: `connect`, #[warn(dead_code)] on by default
| ^
```
The compilation failed, but why? We don't need to place `communicator::` in
The compilation failed, but why? We dont need to place `communicator::` in
front of the function like we did in `src/main.rs` because we are definitely
within the `communicator` library crate here. The reason is that paths are
always relative to the current module, which here is `tests`. The only
@ -221,16 +221,16 @@ module:
super::client::connect();
```
These two options don't look all that different in this example, but if you're
These two options dont look all that different in this example, but if youre
deeper in a module hierarchy, starting from the root every time would get long.
In those cases, using `super` to get from the current module to sibling modules
is a good shortcut. Plus, if you've specified the path from the root in many
is a good shortcut. Plus, if youve specified the path from the root in many
places in your code and then you rearrange your modules by moving a subtree to
another place, you'd end up needing to update the path in a lot of places,
another place, youd end up needing to update the path in a lot of places,
which would be tedious.
It would also be annoying to have to type `super::` all the time in each test,
but you've already seen the tool for that solution: `use`! The `super::`
but youve already seen the tool for that solution: `use`! The `super::`
functionality changes the path you give to `use` so that it is relative to the
parent module instead of to the root module.
@ -271,5 +271,5 @@ Now you know techniques for organizing your code! Use these to group related
functionality together, keep files from getting too long, and present a tidy
public API to users of your library.
Next, let's look at some collection data structures in the standard library
Next, lets look at some collection data structures in the standard library
that you can make use of in your nice, neat code!