summaryrefslogtreecommitdiffstats
path: root/src/doc/book/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/doc/book/src/appendix-04-useful-development-tools.md15
-rw-r--r--src/doc/book/src/appendix-06-translation.md1
-rw-r--r--src/doc/book/src/ch00-00-introduction.md47
-rw-r--r--src/doc/book/src/ch01-01-installation.md58
-rw-r--r--src/doc/book/src/ch01-02-hello-world.md20
-rw-r--r--src/doc/book/src/ch01-03-hello-cargo.md24
-rw-r--r--src/doc/book/src/ch02-00-guessing-game-tutorial.md246
-rw-r--r--src/doc/book/src/ch03-00-common-programming-concepts.md6
-rw-r--r--src/doc/book/src/ch03-01-variables-and-mutability.md55
-rw-r--r--src/doc/book/src/ch03-02-data-types.md82
-rw-r--r--src/doc/book/src/ch03-03-how-functions-work.md22
-rw-r--r--src/doc/book/src/ch03-04-comments.md5
-rw-r--r--src/doc/book/src/ch03-05-control-flow.md84
-rw-r--r--src/doc/book/src/ch04-01-what-is-ownership.md88
-rw-r--r--src/doc/book/src/ch04-02-references-and-borrowing.md36
-rw-r--r--src/doc/book/src/ch04-03-slices.md50
-rw-r--r--src/doc/book/src/ch05-02-example-structs.md2
-rw-r--r--src/doc/book/src/ch08-02-strings.md4
-rw-r--r--src/doc/book/src/ch09-01-unrecoverable-errors-with-panic.md18
-rw-r--r--src/doc/book/src/ch09-02-recoverable-errors-with-result.md8
-rw-r--r--src/doc/book/src/ch13-02-iterators.md2
-rw-r--r--src/doc/book/src/ch14-02-publishing-to-crates-io.md9
-rw-r--r--src/doc/book/src/ch14-03-cargo-workspaces.md13
-rw-r--r--src/doc/book/src/ch14-04-installing-binaries.md8
-rw-r--r--src/doc/book/src/ch15-00-smart-pointers.md6
-rw-r--r--src/doc/book/src/ch15-01-box.md6
-rw-r--r--src/doc/book/src/ch15-02-deref.md11
-rw-r--r--src/doc/book/src/ch15-03-drop.md2
-rw-r--r--src/doc/book/src/ch15-05-interior-mutability.md8
-rw-r--r--src/doc/book/src/ch15-06-reference-cycles.md2
-rw-r--r--src/doc/book/src/ch16-01-threads.md4
-rw-r--r--src/doc/book/src/ch16-03-shared-state.md6
32 files changed, 497 insertions, 451 deletions
diff --git a/src/doc/book/src/appendix-04-useful-development-tools.md b/src/doc/book/src/appendix-04-useful-development-tools.md
index b357f64e2..40b076153 100644
--- a/src/doc/book/src/appendix-04-useful-development-tools.md
+++ b/src/doc/book/src/appendix-04-useful-development-tools.md
@@ -130,14 +130,15 @@ fn main() {
Running `cargo clippy` on this project results in this error:
```text
-error: approximate value of `f{32, 64}::consts::PI` found. Consider using it directly
+error: approximate value of `f{32, 64}::consts::PI` found
--> src/main.rs:2:13
|
2 | let x = 3.1415;
| ^^^^^^
|
- = note: #[deny(clippy::approx_constant)] on by default
- = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/master/index.html#approx_constant
+ = note: `#[deny(clippy::approx_constant)]` on by default
+ = help: consider using the constant directly
+ = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant
```
This error lets you know that Rust already has a more precise `PI` constant
@@ -171,9 +172,9 @@ communicate with each other. Different clients can use `rust-analyzer`, such as
[lsp]: http://langserver.org/
[vscode]: https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer
-Visit the `rust-analyzer` project’s [home page][rust-analyzer] for installation
-instructions, then install the language server support in your particular IDE.
-Your IDE will gain abilities such as autocompletion, jump to definition, and
-inline errors.
+Visit the `rust-analyzer` project’s [home page][rust-analyzer]<!-- ignore -->
+for installation instructions, then install the language server support in your
+particular IDE. Your IDE will gain abilities such as autocompletion, jump to
+definition, and inline errors.
[rust-analyzer]: https://rust-analyzer.github.io
diff --git a/src/doc/book/src/appendix-06-translation.md b/src/doc/book/src/appendix-06-translation.md
index 0bc6aabd9..2c5734354 100644
--- a/src/doc/book/src/appendix-06-translation.md
+++ b/src/doc/book/src/appendix-06-translation.md
@@ -24,7 +24,6 @@ For resources in languages other than English. Most are still in progress; see
- [Svenska](https://github.com/sebras/book)
- [Farsi](https://github.com/pomokhtari/rust-book-fa)
- [Deutsch](https://github.com/rust-lang-de/rustbook-de)
-- [Turkish](https://github.com/RustDili/dokuman/tree/master/ceviriler), [online](https://rustdili.github.io/)
- [हिंदी](https://github.com/venkatarun95/rust-book-hindi)
- [ไทย](https://github.com/rust-lang-th/book-th)
- [Danske](https://github.com/DanKHansen/book-dk)
diff --git a/src/doc/book/src/ch00-00-introduction.md b/src/doc/book/src/ch00-00-introduction.md
index ba7b9ea0e..9df8e6c88 100644
--- a/src/doc/book/src/ch00-00-introduction.md
+++ b/src/doc/book/src/ch00-00-introduction.md
@@ -24,8 +24,8 @@ the most important groups.
Rust is proving to be a productive tool for collaborating among large teams of
developers with varying levels of systems programming knowledge. Low-level code
-is prone to a variety of subtle bugs, which in most other languages can be
-caught only through extensive testing and careful code review by experienced
+is prone to various subtle bugs, which in most other languages can be caught
+only through extensive testing and careful code review by experienced
developers. In Rust, the compiler plays a gatekeeper role by refusing to
compile code with these elusive bugs, including concurrency bugs. By working
alongside the compiler, the team can spend their time focusing on the program’s
@@ -36,7 +36,8 @@ Rust also brings contemporary developer tools to the systems programming world:
* Cargo, the included dependency manager and build tool, makes adding,
compiling, and managing dependencies painless and consistent across the Rust
ecosystem.
-* Rustfmt ensures a consistent coding style across developers.
+* The Rustfmt formatting tool ensures a consistent coding style across
+ developers.
* The Rust Language Server powers Integrated Development Environment (IDE)
integration for code completion and inline error messages.
@@ -55,8 +56,8 @@ programming.
### Companies
Hundreds of companies, large and small, use Rust in production for a variety of
-tasks. Those tasks include command line tools, web services, DevOps tooling,
-embedded devices, audio and video analysis and transcoding, cryptocurrencies,
+tasks, including command line tools, web services, DevOps tooling, embedded
+devices, audio and video analysis and transcoding, cryptocurrencies,
bioinformatics, search engines, Internet of Things applications, machine
learning, and even major parts of the Firefox web browser.
@@ -69,13 +70,13 @@ language.
### People Who Value Speed and Stability
Rust is for people who crave speed and stability in a language. By speed, we
-mean the speed of the programs that you can create with Rust and the speed at
-which Rust lets you write them. The Rust compiler’s checks ensure stability
-through feature additions and refactoring. This is in contrast to the brittle
-legacy code in languages without these checks, which developers are often
-afraid to modify. By striving for zero-cost abstractions, higher-level features
-that compile to lower-level code as fast as code written manually, Rust
-endeavors to make safe code be fast code as well.
+mean both how quickly Rust code can run and the speed at which Rust lets you
+write programs. The Rust compiler’s checks ensure stability through feature
+additions and refactoring. This is in contrast to the brittle legacy code in
+languages without these checks, which developers are often afraid to modify. By
+striving for zero-cost abstractions, higher-level features that compile to
+lower-level code as fast as code written manually, Rust endeavors to make safe
+code be fast code as well.
The Rust language hopes to support many other users as well; those mentioned
here are merely some of the biggest stakeholders. Overall, Rust’s greatest
@@ -96,8 +97,8 @@ reading a book that specifically provides an introduction to programming.
In general, this book assumes that you’re reading it in sequence from front to
back. Later chapters build on concepts in earlier chapters, and earlier
-chapters might not delve into details on a topic; we typically revisit the
-topic in a later chapter.
+chapters might not delve into details on a particular topic but will revisit
+the topic in a later chapter.
You’ll find two kinds of chapters in this book: concept chapters and project
chapters. In concept chapters, you’ll learn about an aspect of Rust. In project
@@ -106,15 +107,15 @@ far. Chapters 2, 12, and 20 are project chapters; the rest are concept chapters.
Chapter 1 explains how to install Rust, how to write a “Hello, world!” program,
and how to use Cargo, Rust’s package manager and build tool. Chapter 2 is a
-hands-on introduction to the Rust language. Here we cover concepts at a high
-level, and later chapters will provide additional detail. If you want to get
-your hands dirty right away, Chapter 2 is the place for that. At first, you
-might even want to skip Chapter 3, which covers Rust features similar to those
-of other programming languages, and head straight to Chapter 4 to learn about
-Rust’s ownership system. However, if you’re a particularly meticulous learner
-who prefers to learn every detail before moving on to the next, you might want
-to skip Chapter 2 and go straight to Chapter 3, returning to Chapter 2 when
-you’d like to work on a project applying the details you’ve learned.
+hands-on introduction to writing a program in Rust, having you build up a
+number guessing game. Here we cover concepts at a high level, and later
+chapters will provide additional detail. If you want to get your hands dirty
+right away, Chapter 2 is the place for that. Chapter 3 covers Rust features
+that are similar to those of other programming languages, and in Chapter 4
+you’ll learn about Rust’s ownership system. If you’re a particularly meticulous
+learner who prefers to learn every detail before moving on to the next, you
+might want to skip Chapter 2 and go straight to Chapter 3, returning to Chapter
+2 when you’d like to work on a project applying the details you’ve learned.
Chapter 5 discusses structs and methods, and Chapter 6 covers enums, `match`
expressions, and the `if let` control flow construct. You’ll use structs and
diff --git a/src/doc/book/src/ch01-01-installation.md b/src/doc/book/src/ch01-01-installation.md
index 47664eb4f..fa9617ad9 100644
--- a/src/doc/book/src/ch01-01-installation.md
+++ b/src/doc/book/src/ch01-01-installation.md
@@ -10,18 +10,18 @@ an internet connection for the download.
The following steps install the latest stable version of the Rust compiler.
Rust’s stability guarantees ensure that all the examples in the book that
compile will continue to compile with newer Rust versions. The output might
-differ slightly between versions, because Rust often improves error messages
-and warnings. In other words, any newer, stable version of Rust you install
-using these steps should work as expected with the content of this book.
+differ slightly between versions because Rust often improves error messages and
+warnings. In other words, any newer, stable version of Rust you install using
+these steps should work as expected with the content of this book.
> ### Command Line Notation
>
> In this chapter and throughout the book, we’ll show some commands used in the
> terminal. Lines that you should enter in a terminal all start with `$`. You
-> don’t need to type in the `$` character; it’s the command line prompt shown
-> to indicate the start of each command. Lines that don’t start with `$`
-> typically show the output of the previous command. Additionally,
-> PowerShell-specific examples will use `>` rather than `$`.
+> don’t need to type the `$` character; it’s the command line prompt shown to
+> indicate the start of each command. Lines that don’t start with `$` typically
+> show the output of the previous command. Additionally, PowerShell-specific
+> examples will use `>` rather than `$`.
### Installing `rustup` on Linux or macOS
@@ -60,13 +60,14 @@ the `build-essential` package.
On Windows, go to [https://www.rust-lang.org/tools/install][install] and follow
the instructions for installing Rust. At some point in the installation, you’ll
receive a message explaining that you’ll also need the MSVC build tools for
-Visual Studio 2013 or later. To acquire the build tools, you’ll need to install
-[Visual Studio 2022][visualstudio]. When asked which workloads to install,
-include:
+Visual Studio 2013 or later.
-- “Desktop Development with C++”
-- The Windows 10 or 11 SDK
-- The English language pack component, along with any other language pack of
+To acquire the build tools, you’ll need to install [Visual Studio
+2022][visualstudio]. When asked which workloads to install, include:
+
+* “Desktop Development with C++”
+* The Windows 10 or 11 SDK
+* The English language pack component, along with any other language pack of
your choosing
The rest of this book uses commands that work in both *cmd.exe* and PowerShell.
@@ -82,15 +83,15 @@ $ rustc --version
```
You should see the version number, commit hash, and commit date for the latest
-stable version that has been released in the following format:
+stable version that has been released, in the following format:
```text
rustc x.y.z (abcabcabc yyyy-mm-dd)
```
If you see this information, you have installed Rust successfully! If you don’t
-see this information, check that Rust is in your `%PATH%`
-system variable as follows.
+see this information, check that Rust is in your `%PATH%` system variable as
+follows.
In Windows CMD, use:
@@ -100,27 +101,24 @@ In Windows CMD, use:
In PowerShell, use:
-```console
+```powershell
> echo $env:Path
```
In Linux and macOS, use:
```console
-echo $PATH
+$ echo $PATH
```
If that’s all correct and Rust still isn’t working, there are a number of
-places you can get help. The easiest is the #beginners channel on [the official
-Rust Discord][discord]. There, you can chat with other Rustaceans (a silly
-nickname we call ourselves) who can help you out. Other great resources include
-[the Users forum][users] and [Stack Overflow][stackoverflow].
+places you can get help. Find out how to get in touch with other Rustaceans (a
+silly nickname we call ourselves) on [the community page][community].
### Updating and Uninstalling
-Once Rust is installed via `rustup`, when a new version of Rust is released,
-updating to the latest version is easy. From your shell, run the following
-update script:
+Once Rust is installed via `rustup`, updating to a newly released version is
+easy. From your shell, run the following update script:
```console
$ rustup update
@@ -135,9 +133,9 @@ $ rustup self uninstall
### Local Documentation
-The installation of Rust also includes a local copy of the documentation, so
-you can read it offline. Run `rustup doc` to open the local documentation in
-your browser.
+The installation of Rust also includes a local copy of the documentation so
+that you can read it offline. Run `rustup doc` to open the local documentation
+in your browser.
Any time a type or function is provided by the standard library and you’re not
sure what it does or how to use it, use the application programming interface
@@ -146,6 +144,4 @@ sure what it does or how to use it, use the application programming interface
[otherinstall]: https://forge.rust-lang.org/infra/other-installation-methods.html
[install]: https://www.rust-lang.org/tools/install
[visualstudio]: https://visualstudio.microsoft.com/downloads/
-[discord]: https://discord.gg/rust-lang
-[users]: https://users.rust-lang.org/
-[stackoverflow]: https://stackoverflow.com/questions/tagged/rust
+[community]: https://www.rust-lang.org/community
diff --git a/src/doc/book/src/ch01-02-hello-world.md b/src/doc/book/src/ch01-02-hello-world.md
index ce9b8f55b..8d8d754d7 100644
--- a/src/doc/book/src/ch01-02-hello-world.md
+++ b/src/doc/book/src/ch01-02-hello-world.md
@@ -1,8 +1,8 @@
## Hello, World!
-Now that you’ve installed Rust, let’s write your first Rust program. It’s
-traditional when learning a new language to write a little program that prints
-the text `Hello, world!` to the screen, so we’ll do the same here!
+Now that you’ve installed Rust, it’s time to write your first Rust program.
+It’s traditional when learning a new language to write a little program that
+prints the text `Hello, world!` to the screen, so we’ll do the same here!
> Note: This book assumes basic familiarity with the command line. Rust makes
> no specific demands about your editing or tooling or where your code lives, so
@@ -10,7 +10,7 @@ the text `Hello, world!` to the screen, so we’ll do the same here!
> the command line, feel free to use your favorite IDE. Many IDEs now have some
> degree of Rust support; check the IDE’s documentation for details. The Rust
> team has been focusing on enabling great IDE support via `rust-analyzer`. See
-> [Appendix D][devtools]<!-- ignore --> for more details!
+> [Appendix D][devtools]<!-- ignore --> for more details.
### Creating a Project Directory
@@ -109,7 +109,7 @@ line as the function declaration, adding one space in between.
> use an automatic formatter tool called `rustfmt` to format your code in a
> particular style (more on `rustfmt` in
> [Appendix D][devtools]<!-- ignore -->). The Rust team has included this tool
-> with the standard Rust distribution, like `rustc`, so it should already be
+> with the standard Rust distribution, as `rustc` is, so it should already be
> installed on your computer!
The body of the `main` function holds the following code:
@@ -126,7 +126,7 @@ First, Rust style is to indent with four spaces, not a tab.
Second, `println!` calls a Rust macro. If it had called a function instead, it
would be entered as `println` (without the `!`). We’ll discuss Rust macros in
more detail in Chapter 19. For now, you just need to know that using a `!`
-means that you’re calling a macro instead of a normal function, and that macros
+means that you’re calling a macro instead of a normal function and that macros
don’t always follow the same rules as functions.
Third, you see the `"Hello, world!"` string. We pass this string as an argument
@@ -153,16 +153,16 @@ If you have a C or C++ background, you’ll notice that this is similar to `gcc`
or `clang`. After compiling successfully, Rust outputs a binary executable.
On Linux, macOS, and PowerShell on Windows, you can see the executable by
-entering the `ls` command in your shell. On Linux and macOS, you’ll see two
-files. With PowerShell on Windows, you’ll see the same three files that you
-would see using CMD.
+entering the `ls` command in your shell:
```console
$ ls
main main.rs
```
-With CMD on Windows, you would enter the following:
+On Linux and macOS, you’ll see two files. With PowerShell on Windows, you’ll
+see the same three files that you would see using CMD. With CMD on Windows, you
+would enter the following:
```cmd
> dir /B %= the /B option says to only show the file names =%
diff --git a/src/doc/book/src/ch01-03-hello-cargo.md b/src/doc/book/src/ch01-03-hello-cargo.md
index 9979e76dd..42cd0889c 100644
--- a/src/doc/book/src/ch01-03-hello-cargo.md
+++ b/src/doc/book/src/ch01-03-hello-cargo.md
@@ -17,7 +17,7 @@ assumes that you’re using Cargo too. Cargo comes installed with Rust if you
used the official installers discussed in the
[“Installation”][installation]<!-- ignore --> section. If you installed Rust
through some other means, check whether Cargo is installed by entering the
-following into your terminal:
+following in your terminal:
```console
$ cargo --version
@@ -30,9 +30,9 @@ determine how to install Cargo separately.
### Creating a Project with Cargo
Let’s create a new project using Cargo and look at how it differs from our
-original “Hello, world!” project. Navigate back to your *projects* directory (or
-wherever you decided to store your code). Then, on any operating system, run
-the following:
+original “Hello, world!” project. Navigate back to your *projects* directory
+(or wherever you decided to store your code). Then, on any operating system,
+run the following:
```console
$ cargo new hello_cargo
@@ -74,8 +74,8 @@ edition = "2021"
<span class="caption">Listing 1-2: Contents of *Cargo.toml* generated by `cargo
new`</span>
-This file is in the [*TOML*](https://toml.io)<!-- ignore --> (*Tom’s Obvious,
-Minimal Language*) format, which is Cargo’s configuration format.
+This file is in the [*TOML*][toml]<!-- ignore --> (*Tom’s Obvious, Minimal
+Language*) format, which is Cargo’s configuration format.
The first line, `[package]`, is a section heading that indicates that the
following statements are configuring a package. As we add more information to
@@ -102,7 +102,7 @@ fn main() {
Cargo has generated a “Hello, world!” program for you, just like the one we
wrote in Listing 1-1! So far, the differences between our project and the
-project Cargo generated are that Cargo placed the code in the *src* directory,
+project Cargo generated are that Cargo placed the code in the *src* directory
and we have a *Cargo.toml* configuration file in the top directory.
Cargo expects your source files to live inside the *src* directory. The
@@ -147,7 +147,7 @@ manages its contents for you.
We just built a project with `cargo build` and ran it with
`./target/debug/hello_cargo`, but we can also use `cargo run` to compile the
-code and then run the resulting executable all in one command:
+code and then run the resultant executable all in one command:
```console
$ cargo run
@@ -184,7 +184,7 @@ $ cargo check
```
Why would you not want an executable? Often, `cargo check` is much faster than
-`cargo build`, because it skips the step of producing an executable. If you’re
+`cargo build` because it skips the step of producing an executable. If you’re
continually checking your work while writing the code, using `cargo check` will
speed up the process of letting you know if your project is still compiling! As
such, many Rustaceans run `cargo check` periodically as they write their
@@ -236,9 +236,7 @@ $ cd someproject
$ cargo build
```
-For more information about Cargo, check out [its documentation].
-
-[its documentation]: https://doc.rust-lang.org/cargo/
+For more information about Cargo, check out [its documentation][cargo].
## Summary
@@ -257,4 +255,6 @@ If you would rather start by learning how common programming concepts work in
Rust, see Chapter 3 and then return to Chapter 2.
[installation]: ch01-01-installation.html#installation
+[toml]: https://toml.io
[appendix-e]: appendix-05-editions.html
+[cargo]: https://doc.rust-lang.org/cargo/
diff --git a/src/doc/book/src/ch02-00-guessing-game-tutorial.md b/src/doc/book/src/ch02-00-guessing-game-tutorial.md
index bffbc0501..4dac23764 100644
--- a/src/doc/book/src/ch02-00-guessing-game-tutorial.md
+++ b/src/doc/book/src/ch02-00-guessing-game-tutorial.md
@@ -3,8 +3,8 @@
Let’s jump into Rust by working through a hands-on project together! This
chapter introduces you to a few common Rust concepts by showing you how to use
them in a real program. You’ll learn about `let`, `match`, methods, associated
-functions, using external crates, and more! In the following chapters, we’ll
-explore these ideas in more detail. In this chapter, you’ll practice the
+functions, external crates, and more! In the following chapters, we’ll explore
+these ideas in more detail. In this chapter, you’ll just practice the
fundamentals.
We’ll implement a classic beginner programming problem: a guessing game. Here’s
@@ -34,7 +34,8 @@ cd listings/ch02-guessing-game-tutorial
rm -rf no-listing-01-cargo-new
cargo new no-listing-01-cargo-new --name guessing_game
cd no-listing-01-cargo-new
-cargo run
+cargo run > output.txt 2>&1
+cd ../../..
-->
<span class="filename">Filename: Cargo.toml</span>
@@ -83,16 +84,16 @@ prints it</span>
This code contains a lot of information, so let’s go over it line by line. To
obtain user input and then print the result as output, we need to bring the
-`io` input/output library into scope. The `io` library comes from the
-standard library, known as `std`:
+`io` input/output library into scope. The `io` library comes from the standard
+library, known as `std`:
```rust,ignore
{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs:io}}
```
-By default, Rust has a set of items defined in the standard library that it brings
-into the scope of every program. This set is called the *prelude*, and you can
-see everything in it [in the standard library documentation][prelude].
+By default, Rust has a set of items defined in the standard library that it
+brings into the scope of every program. This set is called the *prelude*, and
+you can see everything in it [in the standard library documentation][prelude].
If a type you want to use isn’t in the prelude, you have to bring that type
into scope explicitly with a `use` statement. Using the `std::io` library
@@ -106,8 +107,8 @@ program:
{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs:main}}
```
-The `fn` syntax declares a new function, the parentheses, `()`, indicate there
-are no parameters, and the curly bracket, `{`, starts the body of the function.
+The `fn` syntax declares a new function; the parentheses, `()`, indicate there
+are no parameters; and the curly bracket, `{`, starts the body of the function.
As you also learned in Chapter 1, `println!` is a macro that prints a string to
the screen:
@@ -136,7 +137,7 @@ let apples = 5;
This line creates a new variable named `apples` and binds it to the value 5. In
Rust, variables are immutable by default, meaning once we give the variable a
-value, the value won't change. We’ll be discussing this concept in detail in
+value, the value won’t change. We’ll be discussing this concept in detail in
the [“Variables and Mutability”][variables-and-mutability]<!-- ignore -->
section in Chapter 3. To make a variable mutable, we add `mut` before the
variable name:
@@ -152,7 +153,7 @@ let mut bananas = 5; // mutable
Returning to the guessing game program, you now know that `let mut guess` will
introduce a mutable variable named `guess`. The equal sign (`=`) tells Rust we
-want to bind something to the variable now. On the right of the equals sign is
+want to bind something to the variable now. On the right of the equal sign is
the value that `guess` is bound to, which is the result of calling
`String::new`, a function that returns a new instance of a `String`.
[`String`][string]<!-- ignore --> is a string type provided by the standard
@@ -161,7 +162,7 @@ library that is a growable, UTF-8 encoded bit of text.
The `::` syntax in the `::new` line indicates that `new` is an associated
function of the `String` type. An *associated function* is a function that’s
implemented on a type, in this case `String`. This `new` function creates a
-new, empty string. You’ll find a `new` function on many types, because it’s a
+new, empty string. You’ll find a `new` function on many types because it’s a
common name for a function that makes a new value of some kind.
In full, the `let mut guess = String::new();` line has created a mutable
@@ -178,7 +179,7 @@ input:
{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs:read}}
```
-If we hadn’t imported the `io` library with `use std::io` at the beginning of
+If we hadn’t imported the `io` library with `use std::io;` at the beginning of
the program, we could still use the function by writing this function call as
`std::io::stdin`. The `stdin` function returns an instance of
[`std::io::Stdin`][iostdin]<!-- ignore -->, which is a type that represents a
@@ -198,12 +199,15 @@ let multiple parts of your code access one piece of data without needing to
copy that data into memory multiple times. References are a complex feature,
and one of Rust’s major advantages is how safe and easy it is to use
references. You don’t need to know a lot of those details to finish this
-program. For now, all you need to know is that like variables, references are
+program. For now, all you need to know is that, like variables, references are
immutable by default. Hence, you need to write `&mut guess` rather than
`&guess` to make it mutable. (Chapter 4 will explain references more
thoroughly.)
-### Handling Potential Failure with the `Result` Type
+<!-- Old heading. Do not remove or links may break. -->
+<a id="handling-potential-failure-with-the-result-type"></a>
+
+### Handling Potential Failure with `Result`
We’re still working on this line of code. We’re now discussing a third line of
text, but note that it’s still part of a single logical line of code. The next
@@ -230,10 +234,10 @@ ignore --> is an [*enumeration*][enums]<!-- ignore -->, often called an *enum*,
which is a type that can be in one of multiple possible states. We call each
possible state a *variant*.
-Chapter 6 will cover enums in more detail. The purpose of these `Result` types
-is to encode error-handling information.
+[Chapter 6][enums]<!-- ignore --> will cover enums in more detail. The purpose
+of these `Result` types is to encode error-handling information.
-`Result`'s variants are `Ok` and `Err`. The `Ok` variant indicates the
+`Result`’s variants are `Ok` and `Err`. The `Ok` variant indicates the
operation was successful, and inside `Ok` is the successfully generated value.
The `Err` variant means the operation failed, and `Err` contains information
about how or why the operation failed.
@@ -257,9 +261,9 @@ If you don’t call `expect`, the program will compile, but you’ll get a warni
Rust warns that you haven’t used the `Result` value returned from `read_line`,
indicating that the program hasn’t handled a possible error.
-The right way to suppress the warning is to actually write error handling, but
-in our case we just want to crash this program when a problem occurs, so we can
-use `expect`. You’ll learn about recovering from errors in [Chapter
+The right way to suppress the warning is to actually write error-handling code,
+but in our case we just want to crash this program when a problem occurs, so we
+can use `expect`. You’ll learn about recovering from errors in [Chapter
9][recover]<!-- ignore -->.
### Printing Values with `println!` Placeholders
@@ -273,19 +277,21 @@ the code so far:
This line prints the string that now contains the user’s input. The `{}` set of
curly brackets is a placeholder: think of `{}` as little crab pincers that hold
-a value in place. You can print more than one value using curly brackets: the
-first set of curly brackets holds the first value listed after the format
-string, the second set holds the second value, and so on. Printing multiple
-values in one call to `println!` would look like this:
+a value in place. When printing the value of a variable, the variable name can
+go inside the curly brackets. When printing the result of evaluating an
+expression, place empty curly brackets in the format string, then follow the
+format string with a comma-separated list of expressions to print in each empty
+curly bracket placeholder in the same order. Printing a variable and the result
+of an expression in one call to `println!` would look like this:
```rust
let x = 5;
let y = 10;
-println!("x = {} and y = {}", x, y);
+println!("x = {x} and y + 2 = {}", y + 2);
```
-This code would print `x = 5 and y = 10`.
+This code would print `x = 5 and y = 12`.
### Testing the First Part
@@ -324,15 +330,15 @@ said functionality.
Remember that a crate is a collection of Rust source code files. The project
we’ve been building is a *binary crate*, which is an executable. The `rand`
-crate is a *library crate*, which contains code intended to be used in other
-programs and can't be executed on its own.
+crate is a *library crate*, which contains code that is intended to be used in
+other programs and can’t be executed on its own.
Cargo’s coordination of external crates is where Cargo really shines. Before we
can write code that uses `rand`, we need to modify the *Cargo.toml* file to
include the `rand` crate as a dependency. Open that file now and add the
-following line to the bottom beneath the `[dependencies]` section header that
+following line to the bottom, beneath the `[dependencies]` section header that
Cargo created for you. Be sure to specify `rand` exactly as we have here, with
-this version number, or the code examples in this tutorial may not work.
+this version number, or the code examples in this tutorial may not work:
<!-- When updating the version of `rand` used, also update the version of
`rand` used in these files so they all match:
@@ -343,50 +349,50 @@ this version number, or the code examples in this tutorial may not work.
<span class="filename">Filename: Cargo.toml</span>
```toml
-{{#include ../listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.toml:9:}}
+{{#include ../listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.toml:8:}}
```
In the *Cargo.toml* file, everything that follows a header is part of that
section that continues until another section starts. In `[dependencies]` you
tell Cargo which external crates your project depends on and which versions of
those crates you require. In this case, we specify the `rand` crate with the
-semantic version specifier `0.8.3`. Cargo understands [Semantic
+semantic version specifier `0.8.5`. Cargo understands [Semantic
Versioning][semver]<!-- ignore --> (sometimes called *SemVer*), which is a
-standard for writing version numbers. The number `0.8.3` is actually shorthand
-for `^0.8.3`, which means any version that is at least `0.8.3` but below
-`0.9.0`.
+standard for writing version numbers. The specifier `0.8.5` is actually
+shorthand for `^0.8.5`, which means any version that is at least 0.8.5 but
+below 0.9.0.
Cargo considers these versions to have public APIs compatible with version
-`0.8.3`, and this specification ensures you’ll get the latest patch release
-that will still compile with the code in this chapter. Any version `0.9.0` or
-greater is not guaranteed to have the same API as what the following examples
-use.
+0.8.5, and this specification ensures you’ll get the latest patch release that
+will still compile with the code in this chapter. Any version 0.9.0 or greater
+is not guaranteed to have the same API as what the following examples use.
Now, without changing any of the code, let’s build the project, as shown in
Listing 2-2.
<!-- manual-regeneration
cd listings/ch02-guessing-game-tutorial/listing-02-02/
+rm Cargo.lock
cargo clean
cargo build -->
```console
$ cargo build
Updating crates.io index
- Downloaded rand v0.8.3
- Downloaded libc v0.2.86
- Downloaded getrandom v0.2.2
+ Downloaded rand v0.8.5
+ Downloaded libc v0.2.127
+ Downloaded getrandom v0.2.7
Downloaded cfg-if v1.0.0
- Downloaded ppv-lite86 v0.2.10
- Downloaded rand_chacha v0.3.0
- Downloaded rand_core v0.6.2
- Compiling rand_core v0.6.2
- Compiling libc v0.2.86
- Compiling getrandom v0.2.2
+ Downloaded ppv-lite86 v0.2.16
+ Downloaded rand_chacha v0.3.1
+ Downloaded rand_core v0.6.3
+ Compiling libc v0.2.127
+ Compiling getrandom v0.2.7
Compiling cfg-if v1.0.0
- Compiling ppv-lite86 v0.2.10
- Compiling rand_chacha v0.3.0
- Compiling rand v0.8.3
+ Compiling ppv-lite86 v0.2.16
+ Compiling rand_core v0.6.3
+ Compiling rand_chacha v0.3.1
+ Compiling rand v0.8.5
Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
Finished dev [unoptimized + debuginfo] target(s) in 2.53s
```
@@ -395,8 +401,8 @@ $ cargo build
adding the rand crate as a dependency</span>
You may see different version numbers (but they will all be compatible with the
-code, thanks to SemVer!), different lines (depending on the operating system),
-and the lines may be in a different order.
+code, thanks to SemVer!) and different lines (depending on the operating
+system), and the lines may be in a different order.
When we include an external dependency, Cargo fetches the latest versions of
everything that dependency needs from the *registry*, which is a copy of data
@@ -416,8 +422,8 @@ about them in your *Cargo.toml* file. Cargo also knows that you haven’t change
anything about your code, so it doesn’t recompile that either. With nothing to
do, it simply exits.
-If you open up the *src/main.rs* file, make a trivial change, and then save it
-and build again, you’ll only see two lines of output:
+If you open the *src/main.rs* file, make a trivial change, and then save it and
+build again, you’ll only see two lines of output:
<!-- manual-regeneration
cd listings/ch02-guessing-game-tutorial/listing-02-02/
@@ -430,7 +436,7 @@ $ cargo build
Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs
```
-These lines show Cargo only updates the build with your tiny change to the
+These lines show that Cargo only updates the build with your tiny change to the
*src/main.rs* file. Your dependencies haven’t changed, so Cargo knows it can
reuse what it has already downloaded and compiled for those.
@@ -439,21 +445,21 @@ reuse what it has already downloaded and compiled for those.
Cargo has a mechanism that ensures you can rebuild the same artifact every time
you or anyone else builds your code: Cargo will use only the versions of the
dependencies you specified until you indicate otherwise. For example, say that
-next week version 0.8.4 of the `rand` crate comes out, and that version
+next week version 0.8.6 of the `rand` crate comes out, and that version
contains an important bug fix, but it also contains a regression that will
break your code. To handle this, Rust creates the *Cargo.lock* file the first
time you run `cargo build`, so we now have this in the *guessing_game*
directory.
-When you build a project for the first time, Cargo figures out all the
-versions of the dependencies that fit the criteria and then writes them to
-the *Cargo.lock* file. When you build your project in the future, Cargo will
-see that the *Cargo.lock* file exists and use the versions specified there
+When you build a project for the first time, Cargo figures out all the versions
+of the dependencies that fit the criteria and then writes them to the
+*Cargo.lock* file. When you build your project in the future, Cargo will see
+that the *Cargo.lock* file exists and will use the versions specified there
rather than doing all the work of figuring out versions again. This lets you
have a reproducible build automatically. In other words, your project will
-remain at `0.8.3` until you explicitly upgrade, thanks to the *Cargo.lock*
-file. Because the *Cargo.lock* file is important for reproducible builds, it's
-often checked into source control with the rest of the code in your project.
+remain at 0.8.5 until you explicitly upgrade, thanks to the *Cargo.lock* file.
+Because the *Cargo.lock* file is important for reproducible builds, it’s often
+checked into source control with the rest of the code in your project.
#### Updating a Crate to Get a New Version
@@ -461,9 +467,9 @@ When you *do* want to update a crate, Cargo provides the command `update`,
which will ignore the *Cargo.lock* file and figure out all the latest versions
that fit your specifications in *Cargo.toml*. Cargo will then write those
versions to the *Cargo.lock* file. Otherwise, by default, Cargo will only look
-for versions greater than `0.8.3` and less than `0.9.0`. If the `rand` crate
-has released the two new versions `0.8.4` and `0.9.0` you would see the
-following if you ran `cargo update`:
+for versions greater than 0.8.5 and less than 0.9.0. If the `rand` crate has
+released the two new versions 0.8.6 and 0.9.0, you would see the following if
+you ran `cargo update`:
<!-- manual-regeneration
cd listings/ch02-guessing-game-tutorial/listing-02-02/
@@ -474,14 +480,13 @@ as a guide to creating the hypothetical output shown here -->
```console
$ cargo update
Updating crates.io index
- Updating rand v0.8.3 -> v0.8.4
+ Updating rand v0.8.5 -> v0.8.6
```
-Cargo ignores the `0.9.0` release. At this point, you would also notice a
-change in your *Cargo.lock* file noting that the version of the `rand` crate
-you are now using is `0.8.4`. To use `rand` version `0.9.0` or any version in
-the `0.9.x` series, you’d have to update the *Cargo.toml* file to look like
-this instead:
+Cargo ignores the 0.9.0 release. At this point, you would also notice a change
+in your *Cargo.lock* file noting that the version of the `rand` crate you are
+now using is 0.8.6. To use `rand` version 0.9.0 or any version in the 0.9.*x*
+series, you’d have to update the *Cargo.toml* file to look like this instead:
```toml
[dependencies]
@@ -493,7 +498,7 @@ available and reevaluate your `rand` requirements according to the new version
you have specified.
There’s a lot more to say about [Cargo][doccargo]<!-- ignore --> and [its
-ecosystem][doccratesio]<!-- ignore --> which we’ll discuss in Chapter 14, but
+ecosystem][doccratesio]<!-- ignore -->, which we’ll discuss in Chapter 14, but
for now, that’s all you need to know. Cargo makes it very easy to reuse
libraries, so Rustaceans are able to write smaller projects that are assembled
from a number of packages.
@@ -512,16 +517,16 @@ update *src/main.rs*, as shown in Listing 2-3.
<span class="caption">Listing 2-3: Adding code to generate a random
number</span>
-First, we add the line `use rand::Rng`. The `Rng` trait defines methods that
+First we add the line `use rand::Rng;`. The `Rng` trait defines methods that
random number generators implement, and this trait must be in scope for us to
use those methods. Chapter 10 will cover traits in detail.
Next, we’re adding two lines in the middle. In the first line, we call the
`rand::thread_rng` function that gives us the particular random number
-generator that we’re going to use: one that is local to the current thread of
-execution and seeded by the operating system. Then we call the `gen_range`
+generator we’re going to use: one that is local to the current thread of
+execution and is seeded by the operating system. Then we call the `gen_range`
method on the random number generator. This method is defined by the `Rng`
-trait that we brought into scope with the `use rand::Rng` statement. The
+trait that we brought into scope with the `use rand::Rng;` statement. The
`gen_range` method takes a range expression as an argument and generates a
random number in the range. The kind of range expression we’re using here takes
the form `start..=end` and is inclusive on the lower and upper bounds, so we
@@ -530,7 +535,7 @@ need to specify `1..=100` to request a number between 1 and 100.
> Note: You won’t just know which traits to use and which methods and functions
> to call from a crate, so each crate has documentation with instructions for
> using it. Another neat feature of Cargo is that running the `cargo doc
-> --open` command will build documentation provided by all of your dependencies
+> --open` command will build documentation provided by all your dependencies
> locally and open it in your browser. If you’re interested in other
> functionality in the `rand` crate, for example, run `cargo doc --open` and
> click `rand` in the sidebar on the left.
@@ -577,8 +582,8 @@ You should get different random numbers, and they should all be numbers between
## Comparing the Guess to the Secret Number
Now that we have user input and a random number, we can compare them. That step
-is shown in Listing 2-4. Note that this code won’t compile quite yet, as we
-will explain.
+is shown in Listing 2-4. Note that this code won’t compile just yet, as we will
+explain.
<span class="filename">Filename: src/main.rs</span>
@@ -597,7 +602,7 @@ the three outcomes that are possible when you compare two values.
Then we add five new lines at the bottom that use the `Ordering` type. The
`cmp` method compares two values and can be called on anything that can be
compared. It takes a reference to whatever you want to compare with: here it’s
-comparing the `guess` to the `secret_number`. Then it returns a variant of the
+comparing `guess` to `secret_number`. Then it returns a variant of the
`Ordering` enum we brought into scope with the `use` statement. We use a
[`match`][match]<!-- ignore --> expression to decide what to do next based on
which variant of `Ordering` was returned from the call to `cmp` with the values
@@ -607,14 +612,16 @@ A `match` expression is made up of *arms*. An arm consists of a *pattern* to
match against, and the code that should be run if the value given to `match`
fits that arm’s pattern. Rust takes the value given to `match` and looks
through each arm’s pattern in turn. Patterns and the `match` construct are
-powerful Rust features that let you express a variety of situations your code
-might encounter and make sure that you handle them all. These features will be
+powerful Rust features: they let you express a variety of situations your code
+might encounter and they make sure you handle them all. These features will be
covered in detail in Chapter 6 and Chapter 18, respectively.
Let’s walk through an example with the `match` expression we use here. Say that
the user has guessed 50 and the randomly generated secret number this time is
-38. When the code compares 50 to 38, the `cmp` method will return
-`Ordering::Greater`, because 50 is greater than 38. The `match` expression gets
+38.
+
+When the code compares 50 to 38, the `cmp` method will return
+`Ordering::Greater` because 50 is greater than 38. The `match` expression gets
the `Ordering::Greater` value and starts checking each arm’s pattern. It looks
at the first arm’s pattern, `Ordering::Less`, and sees that the value
`Ordering::Greater` does not match `Ordering::Less`, so it ignores the code in
@@ -626,6 +633,11 @@ arm in this scenario.
However, the code in Listing 2-4 won’t compile yet. Let’s try it:
+<!--
+The error numbers in this output should be that of the code **WITHOUT** the
+anchor or snip comments
+-->
+
```console
{{#include ../listings/ch02-guessing-game-tutorial/listing-02-04/output.txt}}
```
@@ -642,8 +654,8 @@ elsewhere that would cause Rust to infer a different numerical type. The reason
for the error is that Rust cannot compare a string and a number type.
Ultimately, we want to convert the `String` the program reads as input into a
-real number type so we can compare it numerically to the secret number. We do so
-by adding this line to the `main` function body:
+real number type so we can compare it numerically to the secret number. We do
+so by adding this line to the `main` function body:
<span class="filename">Filename: src/main.rs</span>
@@ -658,12 +670,12 @@ let guess: u32 = guess.trim().parse().expect("Please type a number!");
```
We create a variable named `guess`. But wait, doesn’t the program already have
-a variable named `guess`? It does, but helpfully Rust allows us to *shadow* the
-previous value of `guess` with a new one. Shadowing lets us reuse the `guess`
+a variable named `guess`? It does, but helpfully Rust allows us to shadow the
+previous value of `guess` with a new one. *Shadowing* lets us reuse the `guess`
variable name rather than forcing us to create two unique variables, such as
-`guess_str` and `guess` for example. We’ll cover this in more detail in Chapter
-3, but for now know that this feature is often used when you want to convert a
-value from one type to another type.
+`guess_str` and `guess`, for example. We’ll cover this in more detail in
+[Chapter 3][shadowing]<!-- ignore -->, but for now, know that this feature is
+often used when you want to convert a value from one type to another type.
We bind this new variable to the expression `guess.trim().parse()`. The `guess`
in the expression refers to the original `guess` variable that contained the
@@ -674,9 +686,9 @@ string to the `u32`, which can only contain numerical data. The user must press
guess, which adds a newline character to the string. For example, if the user
types <span class="keystroke">5</span> and presses <span
class="keystroke">enter</span>, `guess` looks like this: `5\n`. The `\n`
-represents “newline”. (On Windows, pressing <span
+represents “newline.” (On Windows, pressing <span
class="keystroke">enter</span> results in a carriage return and a newline,
-`\r\n`). The `trim` method eliminates `\n` or `\r\n`, resulting in just `5`.
+`\r\n`.) The `trim` method eliminates `\n` or `\r\n`, resulting in just `5`.
The [`parse` method on strings][parse]<!-- ignore --> converts a string to
another type. Here, we use it to convert from a string to a number. We need to
@@ -684,25 +696,27 @@ tell Rust the exact number type we want by using `let guess: u32`. The colon
(`:`) after `guess` tells Rust we’ll annotate the variable’s type. Rust has a
few built-in number types; the `u32` seen here is an unsigned, 32-bit integer.
It’s a good default choice for a small positive number. You’ll learn about
-other number types in Chapter 3. Additionally, the `u32` annotation in this
-example program and the comparison with `secret_number` means that Rust will
-infer that `secret_number` should be a `u32` as well. So now the comparison
-will be between two values of the same type!
+other number types in [Chapter 3][integers]<!-- ignore -->.
+
+Additionally, the `u32` annotation in this example program and the comparison
+with `secret_number` means Rust will infer that `secret_number` should be a
+`u32` as well. So now the comparison will be between two values of the same
+type!
The `parse` method will only work on characters that can logically be converted
into numbers and so can easily cause errors. If, for example, the string
contained `A👍%`, there would be no way to convert that to a number. Because it
might fail, the `parse` method returns a `Result` type, much as the `read_line`
-method does (discussed earlier in [“Handling Potential Failure with the
-`Result` Type”](#handling-potential-failure-with-the-result-type)<!-- ignore
--->). We’ll treat this `Result` the same way by using the `expect` method
-again. If `parse` returns an `Err` `Result` variant because it couldn’t create
-a number from the string, the `expect` call will crash the game and print the
-message we give it. If `parse` can successfully convert the string to a number,
-it will return the `Ok` variant of `Result`, and `expect` will return the
-number that we want from the `Ok` value.
+method does (discussed earlier in [“Handling Potential Failure with
+`Result`”](#handling-potential-failure-with-result)<!-- ignore-->). We’ll treat
+this `Result` the same way by using the `expect` method again. If `parse`
+returns an `Err` `Result` variant because it couldn’t create a number from the
+string, the `expect` call will crash the game and print the message we give it.
+If `parse` can successfully convert the string to a number, it will return the
+`Ok` variant of `Result`, and `expect` will return the number that we want from
+the `Ok` value.
-Let’s run the program now!
+Let’s run the program now:
<!-- manual-regeneration
cd listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/
@@ -788,8 +802,8 @@ thread 'main' panicked at 'Please type a number!: ParseIntError { kind: InvalidD
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
-Typing `quit` will quit the game, but as you’ll notice so will entering any
-other non-number input. This is suboptimal to say the least; we want the game
+Typing `quit` will quit the game, but as you’ll notice, so will entering any
+other non-number input. This is suboptimal, to say the least; we want the game
to also stop when the correct number is guessed.
### Quitting After a Correct Guess
@@ -829,7 +843,7 @@ a `match` expression here, as we did with the `Ordering` result of the `cmp`
method.
If `parse` is able to successfully turn the string into a number, it will
-return an `Ok` value that contains the resulting number. That `Ok` value will
+return an `Ok` value that contains the resultant number. That `Ok` value will
match the first arm’s pattern, and the `match` expression will just return the
`num` value that `parse` produced and put inside the `Ok` value. That number
will end up right where we want it in the new `guess` variable we’re creating.
@@ -891,10 +905,10 @@ secret number. Listing 2-6 shows the final code.
<span class="caption">Listing 2-6: Complete guessing game code</span>
-## Summary
-
At this point, you’ve successfully built the guessing game. Congratulations!
+## Summary
+
This project was a hands-on way to introduce you to many new Rust concepts:
`let`, `match`, functions, the use of external crates, and more. In the next
few chapters, you’ll learn about these concepts in more detail. Chapter 3
@@ -919,4 +933,6 @@ discusses structs and method syntax, and Chapter 6 explains how enums work.
[doccargo]: http://doc.crates.io
[doccratesio]: http://doc.crates.io/crates-io.html
[match]: ch06-02-match.html
+[shadowing]: ch03-01-variables-and-mutability.html#shadowing
[parse]: ../std/primitive.str.html#method.parse
+[integers]: ch03-02-data-types.html#integer-types
diff --git a/src/doc/book/src/ch03-00-common-programming-concepts.md b/src/doc/book/src/ch03-00-common-programming-concepts.md
index 8495543f3..2e37fad02 100644
--- a/src/doc/book/src/ch03-00-common-programming-concepts.md
+++ b/src/doc/book/src/ch03-00-common-programming-concepts.md
@@ -12,9 +12,9 @@ them early will give you a strong core to start from.
> #### Keywords
>
-> The Rust language has a set of *keywords* that are reserved for use by
-> the language only, much as in other languages. Keep in mind that you cannot
-> use these words as names of variables or functions. Most of the keywords have
+> The Rust language has a set of *keywords* that are reserved for use by the
+> language only, much as in other languages. Keep in mind that you cannot use
+> these words as names of variables or functions. Most of the keywords have
> special meanings, and you’ll be using them to do various tasks in your Rust
> programs; a few have no current functionality associated with them but have
> been reserved for functionality that might be added to Rust in the future. You
diff --git a/src/doc/book/src/ch03-01-variables-and-mutability.md b/src/doc/book/src/ch03-01-variables-and-mutability.md
index ac583f1b2..883a53050 100644
--- a/src/doc/book/src/ch03-01-variables-and-mutability.md
+++ b/src/doc/book/src/ch03-01-variables-and-mutability.md
@@ -1,7 +1,7 @@
## Variables and Mutability
As mentioned in the [“Storing Values with
-Variables”][storing-values-with-variables]<!-- ignore --> section, by default
+Variables”][storing-values-with-variables]<!-- ignore --> section, by default,
variables are immutable. This is one of many nudges Rust gives you to write
your code in a way that takes advantage of the safety and easy concurrency that
Rust offers. However, you still have the option to make your variables mutable.
@@ -9,12 +9,11 @@ Let’s explore how and why Rust encourages you to favor immutability and why
sometimes you might want to opt out.
When a variable is immutable, once a value is bound to a name, you can’t change
-that value. To illustrate this, let’s generate a new project called *variables*
-in your *projects* directory by using `cargo new variables`.
+that value. To illustrate this, generate a new project called *variables* in
+your *projects* directory by using `cargo new variables`.
Then, in your new *variables* directory, open *src/main.rs* and replace its
-code with the following code. This code won’t compile just yet, we’ll first
-examine the immutability error.
+code with the following code, which won’t compile just yet:
<span class="filename">Filename: src/main.rs</span>
@@ -22,8 +21,8 @@ examine the immutability error.
{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/src/main.rs}}
```
-Save and run the program using `cargo run`. You should receive an error
-message, as shown in this output:
+Save and run the program using `cargo run`. You should receive an error message
+regarding an immutability error, as shown in this output:
```console
{{#include ../listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/output.txt}}
@@ -34,9 +33,8 @@ Compiler errors can be frustrating, but really they only mean your program
isn’t safely doing what you want it to do yet; they do *not* mean that you’re
not a good programmer! Experienced Rustaceans still get compiler errors.
-The error message indicates that the cause of the error is that you `` cannot
-assign twice to immutable variable `x` ``, because you tried to assign a second
-value to the immutable `x` variable.
+You received the error message `` cannot assign twice to immutable variable `x`
+`` because you tried to assign a second value to the immutable `x` variable.
It’s important that we get compile-time errors when we attempt to change a
value that’s designated as immutable because this very situation can lead to
@@ -45,15 +43,16 @@ never change and another part of our code changes that value, it’s possible
that the first part of the code won’t do what it was designed to do. The cause
of this kind of bug can be difficult to track down after the fact, especially
when the second piece of code changes the value only *sometimes*. The Rust
-compiler guarantees that when you state a value won’t change, it really won’t
-change, so you don’t have to keep track of it yourself. Your code is thus
+compiler guarantees that when you state that a value won’t change, it really
+won’t change, so you don’t have to keep track of it yourself. Your code is thus
easier to reason through.
-But mutability can be very useful, and can make code more convenient to write.
-Although variables are immutable by default, you can make them mutable by adding
-`mut` in front of the variable name as you did in Chapter 2. Adding `mut` also
-conveys intent to future readers of the code by indicating that other parts of
-the code will be changing this variable’s value.
+But mutability can be very useful, and can make code more convenient to write.
+Although variables are immutable by default, you can make them mutable by
+adding `mut` in front of the variable name as you did in [Chapter
+2][storing-values-with-variables]<!-- ignore -->. Adding `mut` also conveys
+intent to future readers of the code by indicating that other parts of the code
+will be changing this variable’s value.
For example, let’s change *src/main.rs* to the following:
@@ -69,8 +68,8 @@ When we run the program now, we get this:
{{#include ../listings/ch03-common-programming-concepts/no-listing-02-adding-mut/output.txt}}
```
-We’re allowed to change the value bound to `x` from `5` to `6` when `mut`
-is used. Ultimately, deciding whether to use mutability or not is up to you and
+We’re allowed to change the value bound to `x` from `5` to `6` when `mut` is
+used. Ultimately, deciding whether to use mutability or not is up to you and
depends on what you think is clearest in that particular situation.
### Constants
@@ -82,9 +81,9 @@ and variables.
First, you aren’t allowed to use `mut` with constants. Constants aren’t just
immutable by default—they’re always immutable. You declare constants using the
`const` keyword instead of the `let` keyword, and the type of the value *must*
-be annotated. We’re about to cover types and type annotations in the next
-section, [“Data Types,”][data-types]<!-- ignore --> so don’t worry about the
-details right now. Just know that you must always annotate the type.
+be annotated. We’ll cover types and type annotations in the next section,
+[“Data Types,”][data-types]<!-- ignore -->, so don’t worry about the details
+right now. Just know that you must always annotate the type.
Constants can be declared in any scope, including the global scope, which makes
them useful for values that many parts of code need to know about.
@@ -109,11 +108,11 @@ to the value 10,800. See the [Rust Reference’s section on constant
evaluation][const-eval] for more information on what operations can be used
when declaring constants.
-Constants are valid for the entire time a program runs, within the scope they
-were declared in. This property makes constants useful for values in your
-application domain that multiple parts of the program might need to know about,
-such as the maximum number of points any player of a game is allowed to earn or
-the speed of light.
+Constants are valid for the entire time a program runs, within the scope in
+which they were declared. This property makes constants useful for values in
+your application domain that multiple parts of the program might need to know
+about, such as the maximum number of points any player of a game is allowed to
+earn, or the speed of light.
Naming hardcoded values used throughout your program as constants is useful in
conveying the meaning of that value to future maintainers of the code. It also
@@ -150,7 +149,7 @@ When we run this program, it will output the following:
{{#include ../listings/ch03-common-programming-concepts/no-listing-03-shadowing/output.txt}}
```
-Shadowing is different from marking a variable as `mut`, because we’ll get a
+Shadowing is different from marking a variable as `mut` because we’ll get a
compile-time error if we accidentally try to reassign to this variable without
using the `let` keyword. By using `let`, we can perform a few transformations
on a value but have the variable be immutable after those transformations have
diff --git a/src/doc/book/src/ch03-02-data-types.md b/src/doc/book/src/ch03-02-data-types.md
index 47c00adc8..bedf1450c 100644
--- a/src/doc/book/src/ch03-02-data-types.md
+++ b/src/doc/book/src/ch03-02-data-types.md
@@ -16,9 +16,9 @@ Chapter 2, we must add a type annotation, like this:
let guess: u32 = "42".parse().expect("Not a number!");
```
-If we don’t add the `: u32` type annotation above, Rust will display the
-following error, which means the compiler needs more information from us to
-know which type we want to use:
+If we don’t add the `: u32` type annotation shown in the preceding code, Rust
+will display the following error, which means the compiler needs more
+information from us to know which type we want to use:
```console
{{#include ../listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt}}
@@ -37,7 +37,7 @@ these from other programming languages. Let’s jump into how they work in Rust.
An *integer* is a number without a fractional component. We used one integer
type in Chapter 2, the `u32` type. This type declaration indicates that the
value it’s associated with should be an unsigned integer (signed integer types
-start with `i`, instead of `u`) that takes up 32 bits of space. Table 3-1 shows
+start with `i` instead of `u`) that takes up 32 bits of space. Table 3-1 shows
the built-in integer types in Rust. We can use any of these variants to declare
the type of an integer value.
@@ -59,9 +59,8 @@ negative—in other words, whether the number needs to have a sign with it
represented without a sign (unsigned). It’s like writing numbers on paper: when
the sign matters, a number is shown with a plus sign or a minus sign; however,
when it’s safe to assume the number is positive, it’s shown with no sign.
-Signed numbers are stored using [two’s
-complement](https://en.wikipedia.org/wiki/Two%27s_complement)<!-- ignore -->
-representation.
+Signed numbers are stored using [two’s complement][twos-complement]<!-- ignore
+--> representation.
Each signed variant can store numbers from -(2<sup>n - 1</sup>) to 2<sup>n -
1</sup> - 1 inclusive, where *n* is the number of bits that variant uses. So an
@@ -98,12 +97,12 @@ some sort of collection.
> ##### Integer Overflow
>
> Let’s say you have a variable of type `u8` that can hold values between 0 and
-> 255. If you try to change the variable to a value outside of that range, such
-> as 256, *integer overflow* will occur, which can result in one of two
-> behaviors. When you’re compiling in debug mode, Rust includes checks for
-> integer overflow that cause your program to *panic* at runtime if this
-> behavior occurs. Rust uses the term panicking when a program exits with an
-> error; we’ll discuss panics in more depth in the [“Unrecoverable Errors with
+> 255. If you try to change the variable to a value outside that range, such as
+> 256, *integer overflow* will occur, which can result in one of two behaviors.
+> When you’re compiling in debug mode, Rust includes checks for integer overflow
+> that cause your program to *panic* at runtime if this behavior occurs. Rust
+> uses the term *panicking* when a program exits with an error; we’ll discuss
+> panics in more depth in the [“Unrecoverable Errors with
> `panic!`”][unrecoverable-errors-with-panic]<!-- ignore --> section in Chapter
> 9.
>
@@ -119,19 +118,19 @@ some sort of collection.
> To explicitly handle the possibility of overflow, you can use these families
> of methods provided by the standard library for primitive numeric types:
>
-> - Wrap in all modes with the `wrapping_*` methods, such as `wrapping_add`
-> - Return the `None` value if there is overflow with the `checked_*` methods
-> - Return the value and a boolean indicating whether there was overflow with
-> the `overflowing_*` methods
-> - Saturate at the value’s minimum or maximum values with `saturating_*`
-> methods
+> * Wrap in all modes with the `wrapping_*` methods, such as `wrapping_add`.
+> * Return the `None` value if there is overflow with the `checked_*` methods.
+> * Return the value and a boolean indicating whether there was overflow with
+> the `overflowing_*` methods.
+> * Saturate at the value’s minimum or maximum values with the `saturating_*`
+> methods.
#### Floating-Point Types
Rust also has two primitive types for *floating-point numbers*, which are
numbers with decimal points. Rust’s floating-point types are `f32` and `f64`,
which are 32 bits and 64 bits in size, respectively. The default type is `f64`
-because on modern CPUs it’s roughly the same speed as `f32` but is capable of
+because on modern CPUs, it’s roughly the same speed as `f32` but is capable of
more precision. All floating-point types are signed.
Here’s an example that shows floating-point numbers in action:
@@ -147,9 +146,9 @@ Floating-point numbers are represented according to the IEEE-754 standard. The
#### Numeric Operations
-Rust supports the basic mathematical operations you’d expect for all of the
-number types: addition, subtraction, multiplication, division, and remainder.
-Integer division rounds down to the nearest integer. The following code shows
+Rust supports the basic mathematical operations you’d expect for all the number
+types: addition, subtraction, multiplication, division, and remainder. Integer
+division truncates toward zero to the nearest integer. The following code shows
how you’d use each numeric operation in a `let` statement:
<span class="filename">Filename: src/main.rs</span>
@@ -159,8 +158,9 @@ how you’d use each numeric operation in a `let` statement:
```
Each expression in these statements uses a mathematical operator and evaluates
-to a single value, which is then bound to a variable. [Appendix B][appendix_b]<!-- ignore --> contains a
-list of all operators that Rust provides.
+to a single value, which is then bound to a variable. [Appendix
+B][appendix_b]<!-- ignore --> contains a list of all operators that Rust
+provides.
#### The Boolean Type
@@ -180,7 +180,7 @@ Flow”][control-flow]<!-- ignore --> section.
#### The Character Type
-Rust’s `char` type is the language’s most primitive alphabetic type. Here’s
+Rust’s `char` type is the language’s most primitive alphabetic type. Here are
some examples of declaring `char` values:
<span class="filename">Filename: src/main.rs</span>
@@ -207,9 +207,9 @@ primitive compound types: tuples and arrays.
#### The Tuple Type
-A tuple is a general way of grouping together a number of values with a variety
-of types into one compound type. Tuples have a fixed length: once declared,
-they cannot grow or shrink in size.
+A *tuple* is a general way of grouping together a number of values with a
+variety of types into one compound type. Tuples have a fixed length: once
+declared, they cannot grow or shrink in size.
We create a tuple by writing a comma-separated list of values inside
parentheses. Each position in the tuple has a type, and the types of the
@@ -222,7 +222,7 @@ type annotations in this example:
{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-10-tuples/src/main.rs}}
```
-The variable `tup` binds to the entire tuple, because a tuple is considered a
+The variable `tup` binds to the entire tuple because a tuple is considered a
single compound element. To get the individual values out of a tuple, we can
use pattern matching to destructure a tuple value, like this:
@@ -234,7 +234,7 @@ use pattern matching to destructure a tuple value, like this:
This program first creates a tuple and binds it to the variable `tup`. It then
uses a pattern with `let` to take `tup` and turn it into three separate
-variables, `x`, `y`, and `z`. This is called *destructuring*, because it breaks
+variables, `x`, `y`, and `z`. This is called *destructuring* because it breaks
the single tuple into three parts. Finally, the program prints the value of
`y`, which is `6.4`.
@@ -275,9 +275,9 @@ Arrays are useful when you want your data allocated on the stack rather than
the heap (we will discuss the stack and the heap more in [Chapter
4][stack-and-heap]<!-- ignore -->) or when you want to ensure you always have a
fixed number of elements. An array isn’t as flexible as the vector type,
-though. A vector is a similar collection type provided by the standard library
-that *is* allowed to grow or shrink in size. If you’re unsure whether to use an
-array or a vector, chances are you should use a vector. [Chapter
+though. A *vector* is a similar collection type provided by the standard
+library that *is* allowed to grow or shrink in size. If you’re unsure whether
+to use an array or a vector, chances are you should use a vector. [Chapter
8][vectors]<!-- ignore --> discusses vectors in more detail.
However, arrays are more useful when you know the number of elements will not
@@ -324,9 +324,9 @@ like this:
{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-14-array-indexing/src/main.rs}}
```
-In this example, the variable named `first` will get the value `1`, because
-that is the value at index `[0]` in the array. The variable named `second` will
-get the value `2` from index `[1]` in the array.
+In this example, the variable named `first` will get the value `1` because that
+is the value at index `[0]` in the array. The variable named `second` will get
+the value `2` from index `[1]` in the array.
##### Invalid Array Element Access
@@ -341,9 +341,9 @@ Chapter 2, to get an array index from the user:
```
This code compiles successfully. If you run this code using `cargo run` and
-enter 0, 1, 2, 3, or 4, the program will print out the corresponding value at
-that index in the array. If you instead enter a number past the end of the
-array, such as 10, you’ll see output like this:
+enter `0`, `1`, `2`, `3`, or `4`, the program will print out the corresponding
+value at that index in the array. If you instead enter a number past the end of
+the array, such as `10`, you’ll see output like this:
<!-- manual-regeneration
cd listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access
@@ -374,10 +374,10 @@ write readable, safe code that neither panics nor allows invalid memory access.
[comparing-the-guess-to-the-secret-number]:
ch02-00-guessing-game-tutorial.html#comparing-the-guess-to-the-secret-number
+[twos-complement]: https://en.wikipedia.org/wiki/Two%27s_complement
[control-flow]: ch03-05-control-flow.html#control-flow
[strings]: ch08-02-strings.html#storing-utf-8-encoded-text-with-strings
[stack-and-heap]: ch04-01-what-is-ownership.html#the-stack-and-the-heap
[vectors]: ch08-01-vectors.html
[unrecoverable-errors-with-panic]: ch09-01-unrecoverable-errors-with-panic.html
-[wrapping]: ../std/num/struct.Wrapping.html
[appendix_b]: appendix-02-operators.md
diff --git a/src/doc/book/src/ch03-03-how-functions-work.md b/src/doc/book/src/ch03-03-how-functions-work.md
index c698853ce..2b59f0cd4 100644
--- a/src/doc/book/src/ch03-03-how-functions-work.md
+++ b/src/doc/book/src/ch03-03-how-functions-work.md
@@ -35,8 +35,8 @@ should see the following output:
```
The lines execute in the order in which they appear in the `main` function.
-First, the “Hello, world!” message prints, and then `another_function` is
-called and its message is printed.
+First the “Hello, world!” message prints, and then `another_function` is called
+and its message is printed.
### Parameters
@@ -108,8 +108,9 @@ understand. Other languages don’t have the same distinctions, so let’s look
what statements and expressions are and how their differences affect the bodies
of functions.
-*Statements* are instructions that perform some action and do not return a
-value. *Expressions* evaluate to a resulting value. Let’s look at some examples.
+* **Statements** are instructions that perform some action and do not return
+ a value.
+* **Expressions** evaluate to a resultant value. Let’s look at some examples.
We’ve actually already used statements and expressions. Creating a variable and
assigning a value to it with the `let` keyword is a statement. In Listing 3-1,
@@ -172,10 +173,11 @@ This expression:
is a block that, in this case, evaluates to `4`. That value gets bound to `y`
as part of the `let` statement. Note that the `x + 1` line doesn’t have a
-semicolon at the end, unlike most of the lines you’ve seen so far. Expressions
-do not include ending semicolons. If you add a semicolon to the end of an
-expression, you turn it into a statement, and it will then not return a value.
-Keep this in mind as you explore function return values and expressions next.
+semicolon at the end, which is unlike most of the lines you’ve seen so far.
+Expressions do not include ending semicolons. If you add a semicolon to the end
+of an expression, you turn it into a statement, and it will then not return a
+value. Keep this in mind as you explore function return values and expressions
+next.
### Functions with Return Values
@@ -226,7 +228,7 @@ Let’s look at another example:
Running this code will print `The value of x is: 6`. But if we place a
semicolon at the end of the line containing `x + 1`, changing it from an
-expression to a statement, we’ll get an error.
+expression to a statement, we’ll get an error:
<span class="filename">Filename: src/main.rs</span>
@@ -240,7 +242,7 @@ Compiling this code produces an error, as follows:
{{#include ../listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/output.txt}}
```
-The main error message, “mismatched types,” reveals the core issue with this
+The main error message, `mismatched types`, reveals the core issue with this
code. The definition of the function `plus_one` says that it will return an
`i32`, but statements don’t evaluate to a value, which is expressed by `()`,
the unit type. Therefore, nothing is returned, which contradicts the function
diff --git a/src/doc/book/src/ch03-04-comments.md b/src/doc/book/src/ch03-04-comments.md
index 6af0ce175..bfb0cfe17 100644
--- a/src/doc/book/src/ch03-04-comments.md
+++ b/src/doc/book/src/ch03-04-comments.md
@@ -39,4 +39,7 @@ separate line above the code it’s annotating:
```
Rust also has another kind of comment, documentation comments, which we’ll
-discuss in the “Publishing a Crate to Crates.io” section of Chapter 14.
+discuss in the [“Publishing a Crate to Crates.io”][publishing]<!-- ignore -->
+section of Chapter 14.
+
+[publishing]: ch14-02-publishing-to-crates-io.html
diff --git a/src/doc/book/src/ch03-05-control-flow.md b/src/doc/book/src/ch03-05-control-flow.md
index 100bfb3e3..60d6b95a9 100644
--- a/src/doc/book/src/ch03-05-control-flow.md
+++ b/src/doc/book/src/ch03-05-control-flow.md
@@ -1,9 +1,9 @@
## Control Flow
-The ability to run some code depending on if a condition is true, or run some
-code repeatedly while a condition is true, are basic building blocks in most
-programming languages. The most common constructs that let you control the flow
-of execution of Rust code are `if` expressions and loops.
+The ability to run some code depending on whether a condition is `true` and to
+run some code repeatedly while a condition is `true` are basic building blocks
+in most programming languages. The most common constructs that let you control
+the flow of execution of Rust code are `if` expressions and loops.
### `if` Expressions
@@ -22,17 +22,17 @@ the `if` expression. In the *src/main.rs* file, input the following:
All `if` expressions start with the keyword `if`, followed by a condition. In
this case, the condition checks whether or not the variable `number` has a
-value less than 5. We place the block of code to execute if the condition is true
-immediately after the condition inside curly brackets. Blocks of code
+value less than 5. We place the block of code to execute if the condition is
+`true` immediately after the condition inside curly brackets. Blocks of code
associated with the conditions in `if` expressions are sometimes called *arms*,
just like the arms in `match` expressions that we discussed in the [“Comparing
the Guess to the Secret Number”][comparing-the-guess-to-the-secret-number]<!--
ignore --> section of Chapter 2.
-Optionally, we can also include an `else` expression, which we chose
-to do here, to give the program an alternative block of code to execute should
-the condition evaluate to false. If you don’t provide an `else` expression and
-the condition is false, the program will just skip the `if` block and move on
+Optionally, we can also include an `else` expression, which we chose to do
+here, to give the program an alternative block of code to execute should the
+condition evaluate to `false`. If you don’t provide an `else` expression and
+the condition is `false`, the program will just skip the `if` block and move on
to the next bit of code.
Try running this code; you should see the following output:
@@ -105,11 +105,11 @@ see the following output:
```
When this program executes, it checks each `if` expression in turn and executes
-the first body for which the condition holds true. Note that even though 6 is
-divisible by 2, we don’t see the output `number is divisible by 2`, nor do we
-see the `number is not divisible by 4, 3, or 2` text from the `else` block.
-That’s because Rust only executes the block for the first true condition, and
-once it finds one, it doesn’t even check the rest.
+the first body for which the condition evaluates to `true`. Note that even
+though 6 is divisible by 2, we don’t see the output `number is divisible by 2`,
+nor do we see the `number is not divisible by 4, 3, or 2` text from the `else`
+block. That’s because Rust only executes the block for the first `true`
+condition, and once it finds one, it doesn’t even check the rest.
Using too many `else if` expressions can clutter your code, so if you have more
than one, you might want to refactor your code. Chapter 6 describes a powerful
@@ -171,8 +171,8 @@ if it had to keep track of multiple hypothetical types for any variable.
It’s often useful to execute a block of code more than once. For this task,
Rust provides several *loops*, which will run through the code inside the loop
-body to the end and then start immediately back at the beginning. To
-experiment with loops, let’s make a new project called *loops*.
+body to the end and then start immediately back at the beginning. To experiment
+with loops, let’s make a new project called *loops*.
Rust has three kinds of loops: `loop`, `while`, and `for`. Let’s try each one.
@@ -191,9 +191,9 @@ like this:
```
When we run this program, we’ll see `again!` printed over and over continuously
-until we stop the program manually. Most terminals support the keyboard shortcut
-<span class="keystroke">ctrl-c</span> to interrupt a program that is stuck in
-a continual loop. Give it a try:
+until we stop the program manually. Most terminals support the keyboard
+shortcut <span class="keystroke">ctrl-c</span> to interrupt a program that is
+stuck in a continual loop. Give it a try:
<!-- manual-regeneration
cd listings/ch03-common-programming-concepts/no-listing-32-loop
@@ -213,10 +213,10 @@ again!
^Cagain!
```
-The symbol `^C` represents where you pressed <span class="keystroke">ctrl-c
-</span>. You may or may not see the word `again!` printed after the `^C`,
-depending on where the code was in the loop when it received the interrupt
-signal.
+The symbol `^C` represents where you pressed <span
+class="keystroke">ctrl-c</span>. You may or may not see the word `again!`
+printed after the `^C`, depending on where the code was in the loop when it
+received the interrupt signal.
Fortunately, Rust also provides a way to break out of a loop using code. You
can place the `break` keyword within the loop to tell the program when to stop
@@ -245,18 +245,18 @@ use it, as shown here:
Before the loop, we declare a variable named `counter` and initialize it to
`0`. Then we declare a variable named `result` to hold the value returned from
the loop. On every iteration of the loop, we add `1` to the `counter` variable,
-and then check whether the counter is equal to `10`. When it is, we use the
+and then check whether the `counter` is equal to `10`. When it is, we use the
`break` keyword with the value `counter * 2`. After the loop, we use a
semicolon to end the statement that assigns the value to `result`. Finally, we
-print the value in `result`, which in this case is 20.
+print the value in `result`, which in this case is `20`.
#### Loop Labels to Disambiguate Between Multiple Loops
If you have loops within loops, `break` and `continue` apply to the innermost
-loop at that point. You can optionally specify a *loop label* on a loop that we
-can then use with `break` or `continue` to specify that those keywords apply to
-the labeled loop instead of the innermost loop. Loop labels must begin with a
-single quote. Here’s an example with two nested loops:
+loop at that point. You can optionally specify a *loop label* on a loop that
+you can then use with `break` or `continue` to specify that those keywords
+apply to the labeled loop instead of the innermost loop. Loop labels must begin
+with a single quote. Here’s an example with two nested loops:
```rust
{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/src/main.rs}}
@@ -274,7 +274,7 @@ doesn’t specify a label will exit the inner loop only. The `break
#### Conditional Loops with `while`
A program will often need to evaluate a condition within a loop. While the
-condition is true, the loop runs. When the condition ceases to be true, the
+condition is `true`, the loop runs. When the condition ceases to be `true`, the
program calls `break`, stopping the loop. It’s possible to implement behavior
like this using a combination of `loop`, `if`, `else`, and `break`; you could
try that now in a program, if you’d like. However, this pattern is so common
@@ -292,8 +292,8 @@ time, and then, after the loop, print a message and exit.
condition holds true</span>
This construct eliminates a lot of nesting that would be necessary if you used
-`loop`, `if`, `else`, and `break`, and it’s clearer. While a condition holds
-true, the code runs; otherwise, it exits the loop.
+`loop`, `if`, `else`, and `break`, and it’s clearer. While a condition
+evaluates to `true`, the code runs; otherwise, it exits the loop.
#### Looping Through a Collection with `for`
@@ -312,8 +312,8 @@ using a `while` loop</span>
Here, the code counts up through the elements in the array. It starts at index
`0`, and then loops until it reaches the final index in the array (that is,
-when `index < 5` is no longer true). Running this code will print every element
-in the array:
+when `index < 5` is no longer `true`). Running this code will print every
+element in the array:
```console
{{#include ../listings/ch03-common-programming-concepts/listing-03-04/output.txt}}
@@ -324,8 +324,8 @@ will reach a value of `5` at some point, the loop stops executing before trying
to fetch a sixth value from the array.
However, this approach is error prone; we could cause the program to panic if
-the index value or test condition are incorrect. For example, if you changed
-the definition of the `a` array to have four elements but forgot to update the
+the index value or test condition is incorrect. For example, if you changed the
+definition of the `a` array to have four elements but forgot to update the
condition to `while index < 4`, the code would panic. It’s also slow, because
the compiler adds runtime code to perform the conditional check of whether the
index is within the bounds of the array on every iteration through the loop.
@@ -372,13 +372,13 @@ This code is a bit nicer, isn’t it?
## Summary
-You made it! That was a sizable chapter: you learned about variables, scalar
-and compound data types, functions, comments, `if` expressions, and loops!
-To practice with the concepts discussed in this chapter, try building
-programs to do the following:
+You made it! This was a sizable chapter: you learned about variables, scalar
+and compound data types, functions, comments, `if` expressions, and loops! To
+practice with the concepts discussed in this chapter, try building programs to
+do the following:
* Convert temperatures between Fahrenheit and Celsius.
-* Generate the nth Fibonacci number.
+* Generate the *n*th Fibonacci number.
* Print the lyrics to the Christmas carol “The Twelve Days of Christmas,”
taking advantage of the repetition in the song.
diff --git a/src/doc/book/src/ch04-01-what-is-ownership.md b/src/doc/book/src/ch04-01-what-is-ownership.md
index 94842e1b0..5249c2dd7 100644
--- a/src/doc/book/src/ch04-01-what-is-ownership.md
+++ b/src/doc/book/src/ch04-01-what-is-ownership.md
@@ -1,8 +1,8 @@
## What Is Ownership?
-*Ownership* is a set of rules that governs how a Rust program manages memory.
+*Ownership* is a set of rules that govern how a Rust program manages memory.
All programs have to manage the way they use a computer’s memory while running.
-Some languages have garbage collection that regularly looks for no-longer used
+Some languages have garbage collection that regularly looks for no-longer-used
memory as the program runs; in other languages, the programmer must explicitly
allocate and free the memory. Rust uses a third approach: memory is managed
through a system of ownership with a set of rules that the compiler checks. If
@@ -49,14 +49,14 @@ strings.
> known, fixed size, you can store the pointer on the stack, but when you want
> the actual data, you must follow the pointer. Think of being seated at a
> restaurant. When you enter, you state the number of people in your group, and
-> the staff finds an empty table that fits everyone and leads you there. If
+> the host finds an empty table that fits everyone and leads you there. If
> someone in your group comes late, they can ask where you’ve been seated to
> find you.
>
> Pushing to the stack is faster than allocating on the heap because the
> allocator never has to search for a place to store new data; that location is
> always at the top of the stack. Comparatively, allocating space on the heap
-> requires more work, because the allocator must first find a big enough space
+> requires more work because the allocator must first find a big enough space
> to hold the data and then perform bookkeeping to prepare for the next
> allocation.
>
@@ -122,8 +122,8 @@ valid</span>
In other words, there are two important points in time here:
-* When `s` comes *into scope*, it is valid.
-* It remains valid until it goes *out of scope*.
+* When `s` comes *into* scope, it is valid.
+* It remains valid until it goes *out of* scope.
At this point, the relationship between scopes and when variables are valid is
similar to that in other programming languages. Now we’ll build on top of this
@@ -133,7 +133,7 @@ understanding by introducing the `String` type.
To illustrate the rules of ownership, we need a data type that is more complex
than those we covered in the [“Data Types”][data-types]<!-- ignore --> section
-of Chapter 3. The types covered previously are all a known size, can be stored
+of Chapter 3. The types covered previously are of a known size, can be stored
on the stack and popped off the stack when their scope is over, and can be
quickly and trivially copied to make a new, independent instance if another
part of code needs to use the same value in a different scope. But we want to
@@ -162,7 +162,7 @@ let s = String::from("hello");
The double colon `::` operator allows us to namespace this particular `from`
function under the `String` type rather than using some sort of name like
`string_from`. We’ll discuss this syntax more in the [“Method
-Syntax”][method-syntax]<!-- ignore --> section of Chapter 5 and when we talk
+Syntax”][method-syntax]<!-- ignore --> section of Chapter 5, and when we talk
about namespacing with modules in [“Paths for Referring to an Item in the
Module Tree”][paths-module-tree]<!-- ignore --> in Chapter 7.
@@ -173,7 +173,7 @@ This kind of string *can* be mutated:
```
So, what’s the difference here? Why can `String` be mutated but literals
-cannot? The difference is how these two types deal with memory.
+cannot? The difference is in how these two types deal with memory.
### Memory and Allocation
@@ -189,8 +189,8 @@ we need to allocate an amount of memory on the heap, unknown at compile time,
to hold the contents. This means:
* The memory must be requested from the memory allocator at runtime.
-* We need a way of returning this memory to the allocator when we’re
- done with our `String`.
+* We need a way of returning this memory to the allocator when we’re done with
+ our `String`.
That first part is done by us: when we call `String::from`, its implementation
requests the memory it needs. This is pretty much universal in programming
@@ -199,7 +199,7 @@ languages.
However, the second part is different. In languages with a *garbage collector
(GC)*, the GC keeps track of and cleans up memory that isn’t being used
anymore, and we don’t need to think about it. In most languages without a GC,
-it’s our responsibility to identify when memory is no longer being used and
+it’s our responsibility to identify when memory is no longer being used and to
call code to explicitly free it, just as we did to request it. Doing this
correctly has historically been a difficult programming problem. If we forget,
we’ll waste memory. If we do it too early, we’ll have an invalid variable. If
@@ -231,7 +231,10 @@ simple right now, but the behavior of code can be unexpected in more
complicated situations when we want to have multiple variables use the data
we’ve allocated on the heap. Let’s explore some of those situations now.
-#### Ways Variables and Data Interact: Move
+<!-- Old heading. Do not remove or links may break. -->
+<a id="ways-variables-and-data-interact-move"></a>
+
+#### Variables and Data Interacting with Move
Multiple variables can interact with the same data in different ways in Rust.
Let’s look at an example using an integer in Listing 4-2.
@@ -265,23 +268,29 @@ the memory that holds the contents of the string, a length, and a capacity.
This group of data is stored on the stack. On the right is the memory on the
heap that holds the contents.
-<img alt="String in memory" src="img/trpl04-01.svg" class="center" style="width: 50%;" />
+<img alt="Two tables: the first table contains the representation of s1 on the
+stack, consisting of its length (5), capacity (5), and a pointer to the first
+value in the second table. The second table contains the representation of the
+string data on the heap, byte by byte." src="img/trpl04-01.svg" class="center"
+style="width: 50%;" />
<span class="caption">Figure 4-1: Representation in memory of a `String`
holding the value `"hello"` bound to `s1`</span>
-The length is how much memory, in bytes, the contents of the `String` is
+The length is how much memory, in bytes, the contents of the `String` are
currently using. The capacity is the total amount of memory, in bytes, that the
-`String` has received from the allocator. The difference between length
-and capacity matters, but not in this context, so for now, it’s fine to ignore
-the capacity.
+`String` has received from the allocator. The difference between length and
+capacity matters, but not in this context, so for now, it’s fine to ignore the
+capacity.
When we assign `s1` to `s2`, the `String` data is copied, meaning we copy the
pointer, the length, and the capacity that are on the stack. We do not copy the
data on the heap that the pointer refers to. In other words, the data
representation in memory looks like Figure 4-2.
-<img alt="s1 and s2 pointing to the same value" src="img/trpl04-02.svg" class="center" style="width: 50%;" />
+<img alt="Three tables: tables s1 and s2 representing those strings on the
+stack, respectively, and both pointing to the same string data on the heap."
+src="img/trpl04-02.svg" class="center" style="width: 50%;" />
<span class="caption">Figure 4-2: Representation in memory of the variable `s2`
that has a copy of the pointer, length, and capacity of `s1`</span>
@@ -291,7 +300,9 @@ look like if Rust instead copied the heap data as well. If Rust did this, the
operation `s2 = s1` could be very expensive in terms of runtime performance if
the data on the heap were large.
-<img alt="s1 and s2 to two places" src="img/trpl04-03.svg" class="center" style="width: 50%;" />
+<img alt="Four tables: two tables representing the stack data for s1 and s2,
+and each points to its own copy of string data on the heap."
+src="img/trpl04-03.svg" class="center" style="width: 50%;" />
<span class="caption">Figure 4-3: Another possibility for what `s2 = s1` might
do if Rust copied the heap data as well</span>
@@ -304,7 +315,7 @@ same memory. This is known as a *double free* error and is one of the memory
safety bugs we mentioned previously. Freeing memory twice can lead to memory
corruption, which can potentially lead to security vulnerabilities.
-To ensure memory safety, after the line `let s2 = s1`, Rust considers `s1` as
+To ensure memory safety, after the line `let s2 = s1;`, Rust considers `s1` as
no longer valid. Therefore, Rust doesn’t need to free anything when `s1` goes
out of scope. Check out what happens when you try to use `s1` after `s2` is
created; it won’t work:
@@ -323,23 +334,30 @@ invalidated reference:
If you’ve heard the terms *shallow copy* and *deep copy* while working with
other languages, the concept of copying the pointer, length, and capacity
without copying the data probably sounds like making a shallow copy. But
-because Rust also invalidates the first variable, instead of calling it a
-shallow copy, it’s known as a *move*. In this example, we would say that
-`s1` was *moved* into `s2`. So what actually happens is shown in Figure 4-4.
+because Rust also invalidates the first variable, instead of being called a
+shallow copy, it’s known as a *move*. In this example, we would say that `s1`
+was *moved* into `s2`. So, what actually happens is shown in Figure 4-4.
-<img alt="s1 moved to s2" src="img/trpl04-04.svg" class="center" style="width: 50%;" />
+<img alt="Three tables: tables s1 and s2 representing those strings on the
+stack, respectively, and both pointing to the same string data on the heap.
+Table s1 is grayed out be-cause s1 is no longer valid; only s2 can be used to
+access the heap data." src="img/trpl04-04.svg" class="center" style="width:
+50%;" />
<span class="caption">Figure 4-4: Representation in memory after `s1` has been
invalidated</span>
-That solves our problem! With only `s2` valid, when it goes out of scope, it
+That solves our problem! With only `s2` valid, when it goes out of scope it
alone will free the memory, and we’re done.
In addition, there’s a design choice that’s implied by this: Rust will never
automatically create “deep” copies of your data. Therefore, any *automatic*
copying can be assumed to be inexpensive in terms of runtime performance.
-#### Ways Variables and Data Interact: Clone
+<!-- Old heading. Do not remove or links may break. -->
+<a id="ways-variables-and-data-interact-clone"></a>
+
+#### Variables and Data Interacting with Clone
If we *do* want to deeply copy the heap data of the `String`, not just the
stack data, we can use a common method called `clone`. We’ll discuss method
@@ -361,8 +379,8 @@ different is going on.
#### Stack-Only Data: Copy
-There’s another wrinkle we haven’t talked about yet. This code using integers –
-part of which was shown in Listing 4-2 – works and is valid:
+There’s another wrinkle we haven’t talked about yet. This code using
+integers—part of which was shown in Listing 4-2—works and is valid:
```rust
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-06-copy/src/main.rs:here}}
@@ -376,7 +394,7 @@ time are stored entirely on the stack, so copies of the actual values are quick
to make. That means there’s no reason we would want to prevent `x` from being
valid after we create the variable `y`. In other words, there’s no difference
between deep and shallow copying here, so calling `clone` wouldn’t do anything
-different from the usual shallow copying and we can leave it out.
+different from the usual shallow copying, and we can leave it out.
Rust has a special annotation called the `Copy` trait that we can place on
types that are stored on the stack, as integers are (we’ll talk more about
@@ -391,7 +409,7 @@ we’ll get a compile-time error. To learn about how to add the `Copy` annotatio
to your type to implement the trait, see [“Derivable
Traits”][derivable-traits]<!-- ignore --> in Appendix C.
-So what types implement the `Copy` trait? You can check the documentation for
+So, what types implement the `Copy` trait? You can check the documentation for
the given type to be sure, but as a general rule, any group of simple scalar
values can implement `Copy`, and nothing that requires allocation or is some
form of resource can implement `Copy`. Here are some of the types that
@@ -399,7 +417,7 @@ implement `Copy`:
* All the integer types, such as `u32`.
* The Boolean type, `bool`, with values `true` and `false`.
-* All the floating point types, such as `f64`.
+* All the floating-point types, such as `f64`.
* The character type, `char`.
* Tuples, if they only contain types that also implement `Copy`. For example,
`(i32, i32)` implements `Copy`, but `(i32, String)` does not.
@@ -427,9 +445,9 @@ the ownership rules prevent you from doing so.
### Return Values and Scope
-Returning values can also transfer ownership. Listing 4-4 shows an example
-of a function that returns some value, with similar annotations as those in
-Listing 4-3.
+Returning values can also transfer ownership. Listing 4-4 shows an example of a
+function that returns some value, with similar annotations as those in Listing
+4-3.
<span class="filename">Filename: src/main.rs</span>
diff --git a/src/doc/book/src/ch04-02-references-and-borrowing.md b/src/doc/book/src/ch04-02-references-and-borrowing.md
index 060c344bb..ea2d8d202 100644
--- a/src/doc/book/src/ch04-02-references-and-borrowing.md
+++ b/src/doc/book/src/ch04-02-references-and-borrowing.md
@@ -9,9 +9,8 @@ the data stored at that address; that data is owned by some other variable.
Unlike a pointer, a reference is guaranteed to point to a valid value of a
particular type for the life of that reference.
-Here is how you would define and use a `calculate_length` function that
-has a reference to an object as a parameter instead of taking ownership of the
-value:
+Here is how you would define and use a `calculate_length` function that has a
+reference to an object as a parameter instead of taking ownership of the value:
<span class="filename">Filename: src/main.rs</span>
@@ -25,7 +24,9 @@ function return value is gone. Second, note that we pass `&s1` into
`String`. These ampersands represent *references*, and they allow you to refer
to some value without taking ownership of it. Figure 4-5 depicts this concept.
-<img alt="&amp;String s pointing at String s1" src="img/trpl04-05.svg" class="center" />
+<img alt="Three tables: the table for s contains only a pointer to the table
+for s1. The table for s1 contains the stack data for s1 and points to the
+string data on the heap." src="img/trpl04-05.svg" class="center" />
<span class="caption">Figure 4-5: A diagram of `&String s` pointing at `String
s1`</span>
@@ -54,7 +55,7 @@ the parameter `s` is a reference. Let’s add some explanatory annotations:
The scope in which the variable `s` is valid is the same as any function
parameter’s scope, but the value pointed to by the reference is not dropped
-when `s` stops being used because `s` doesn’t have ownership. When functions
+when `s` stops being used, because `s` doesn’t have ownership. When functions
have references as parameters instead of the actual values, we won’t need to
return the values in order to give back ownership, because we never had
ownership.
@@ -63,7 +64,7 @@ We call the action of creating a reference *borrowing*. As in real life, if a
person owns something, you can borrow it from them. When you’re done, you have
to give it back. You don’t own it.
-So what happens if we try to modify something we’re borrowing? Try the code in
+So, what happens if we try to modify something we’re borrowing? Try the code in
Listing 4-6. Spoiler alert: it doesn’t work!
<span class="filename">Filename: src/main.rs</span>
@@ -94,7 +95,7 @@ with just a few small tweaks that use, instead, a *mutable reference*:
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/src/main.rs}}
```
-First, we change `s` to be `mut`. Then we create a mutable reference with `&mut
+First we change `s` to be `mut`. Then we create a mutable reference with `&mut
s` where we call the `change` function, and update the function signature to
accept a mutable reference with `some_string: &mut String`. This makes it very
clear that the `change` function will mutate the value it borrows.
@@ -123,7 +124,7 @@ in `r2` that borrows the same data as `r1`.
The restriction preventing multiple mutable references to the same data at the
same time allows for mutation but in a very controlled fashion. It’s something
-that new Rustaceans struggle with, because most languages let you mutate
+that new Rustaceans struggle with because most languages let you mutate
whenever you’d like. The benefit of having this restriction is that Rust can
prevent data races at compile time. A *data race* is similar to a race
condition and happens when these three behaviors occur:
@@ -133,8 +134,8 @@ condition and happens when these three behaviors occur:
* There’s no mechanism being used to synchronize access to the data.
Data races cause undefined behavior and can be difficult to diagnose and fix
-when you’re trying to track them down at runtime; Rust prevents this problem
-by refusing to compile code with data races!
+when you’re trying to track them down at runtime; Rust prevents this problem by
+refusing to compile code with data races!
As always, we can use curly brackets to create a new scope, allowing for
multiple mutable references, just not *simultaneous* ones:
@@ -175,10 +176,9 @@ occurs before the mutable reference is introduced:
The scopes of the immutable references `r1` and `r2` end after the `println!`
where they are last used, which is before the mutable reference `r3` is
-created. These scopes don’t overlap, so this code is allowed. The ability of
-the compiler to tell that a reference is no longer being used at a point before
-the end of the scope is called *Non-Lexical Lifetimes* (NLL for short), and you
-can read more about it in [The Edition Guide][nll].
+created. These scopes don’t overlap, so this code is allowed: the compiler can
+tell that the reference is no longer being used at a point before the end of
+the scope.
Even though borrowing errors may be frustrating at times, remember that it’s
the Rust compiler pointing out a potential bug early (at compile time rather
@@ -188,9 +188,9 @@ have to track down why your data isn’t what you thought it was.
### Dangling References
In languages with pointers, it’s easy to erroneously create a *dangling
-pointer*--a pointer that references a location in memory that may have been
-given to someone else--by freeing some memory while preserving a pointer to
-that memory. In Rust, by contrast, the compiler guarantees that references will
+pointer*—a pointer that references a location in memory that may have been
+given to someone else—by freeing some memory while preserving a pointer to that
+memory. In Rust, by contrast, the compiler guarantees that references will
never be dangling references: if you have a reference to some data, the
compiler will ensure that the data will not go out of scope before the
reference to the data does.
@@ -251,5 +251,3 @@ Let’s recap what we’ve discussed about references:
* References must always be valid.
Next, we’ll look at a different kind of reference: slices.
-
-[nll]: https://doc.rust-lang.org/edition-guide/rust-2018/ownership-and-lifetimes/non-lexical-lifetimes.html
diff --git a/src/doc/book/src/ch04-03-slices.md b/src/doc/book/src/ch04-03-slices.md
index afb6f76b1..6ffb1dc11 100644
--- a/src/doc/book/src/ch04-03-slices.md
+++ b/src/doc/book/src/ch04-03-slices.md
@@ -32,7 +32,7 @@ byte index value into the `String` parameter</span>
Because we need to go through the `String` element by element and check whether
a value is a space, we’ll convert our `String` to an array of bytes using the
-`as_bytes` method:
+`as_bytes` method.
```rust,ignore
{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-07/src/main.rs:as_bytes}}
@@ -60,7 +60,7 @@ Because we get a reference to the element from `.iter().enumerate()`, we use
Inside the `for` loop, we search for the byte that represents the space by
using the byte literal syntax. If we find a space, we return the position.
-Otherwise, we return the length of the string by using `s.len()`:
+Otherwise, we return the length of the string by using `s.len()`.
```rust,ignore
{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-07/src/main.rs:inside_for}}
@@ -98,8 +98,8 @@ fn second_word(s: &String) -> (usize, usize) {
Now we’re tracking a starting *and* an ending index, and we have even more
values that were calculated from data in a particular state but aren’t tied to
-that state at all. We have three unrelated variables floating around that
-need to be kept in sync.
+that state at all. We have three unrelated variables floating around that need
+to be kept in sync.
Luckily, Rust has a solution to this problem: string slices.
@@ -117,18 +117,22 @@ using a range within brackets by specifying `[starting_index..ending_index]`,
where `starting_index` is the first position in the slice and `ending_index` is
one more than the last position in the slice. Internally, the slice data
structure stores the starting position and the length of the slice, which
-corresponds to `ending_index` minus `starting_index`. So in the case of `let
+corresponds to `ending_index` minus `starting_index`. So, in the case of `let
world = &s[6..11];`, `world` would be a slice that contains a pointer to the
-byte at index 6 of `s` with a length value of 5.
+byte at index 6 of `s` with a length value of `5`.
Figure 4-6 shows this in a diagram.
-<img alt="world containing a pointer to the byte at index 6 of String s and a length 5" src="img/trpl04-06.svg" class="center" style="width: 50%;" />
+<img alt="Three tables: a table representing the stack data of s, which points
+to the byte at index 0 in a table of the string data &quot;hello world&quot; on
+the heap. The third table rep-resents the stack data of the slice world, which
+has a length value of 5 and points to byte 6 of the heap data table."
+src="img/trpl04-06.svg" class="center" style="width: 50%;" />
<span class="caption">Figure 4-6: String slice referring to part of a
`String`</span>
-With Rust’s `..` range syntax, if you want to start at index zero, you can drop
+With Rust’s `..` range syntax, if you want to start at index 0, you can drop
the value before the two periods. In other words, these are equal:
```rust
@@ -178,10 +182,10 @@ slice. The type that signifies “string slice” is written as `&str`:
{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-18-first-word-slice/src/main.rs:here}}
```
-We get the index for the end of the word in the same way as we did in Listing
-4-7, by looking for the first occurrence of a space. When we find a space, we
-return a string slice using the start of the string and the index of the space
-as the starting and ending indices.
+We get the index for the end of the word the same way we did in Listing 4-7, by
+looking for the first occurrence of a space. When we find a space, we return a
+string slice using the start of the string and the index of the space as the
+starting and ending indices.
Now when we call `first_word`, we get back a single value that is tied to the
underlying data. The value is made up of a reference to the starting point of
@@ -193,7 +197,7 @@ Returning a slice would also work for a `second_word` function:
fn second_word(s: &String) -> &str {
```
-We now have a straightforward API that’s much harder to mess up, because the
+We now have a straightforward API that’s much harder to mess up because the
compiler will ensure the references into the `String` remain valid. Remember
the bug in the program in Listing 4-8, when we got the index to the end of the
first word but then cleared the string so our index was invalid? That code was
@@ -224,7 +228,10 @@ reference in `clear` and the immutable reference in `word` from existing at the
same time, and compilation fails. Not only has Rust made our API easier to use,
but it has also eliminated an entire class of errors at compile time!
-#### String Literals Are Slices
+<!-- Old heading. Do not remove or links may break. -->
+<a id="string-literals-are-slices"></a>
+
+#### String Literals as Slices
Recall that we talked about string literals being stored inside the binary. Now
that we know about slices, we can properly understand string literals:
@@ -260,10 +267,11 @@ a string slice for the type of the `s` parameter</span>
If we have a string slice, we can pass that directly. If we have a `String`, we
can pass a slice of the `String` or a reference to the `String`. This
flexibility takes advantage of *deref coercions*, a feature we will cover in
-the [“Implicit Deref Coercions with Functions and
-Methods”][deref-coercions]<!--ignore--> section of Chapter 15. Defining a
-function to take a string slice instead of a reference to a `String` makes our
-API more general and useful without losing any functionality:
+[“Implicit Deref Coercions with Functions and
+Methods”][deref-coercions]<!--ignore--> section of Chapter 15.
+
+Defining a function to take a string slice instead of a reference to a `String`
+makes our API more general and useful without losing any functionality:
<span class="filename">Filename: src/main.rs</span>
@@ -274,14 +282,14 @@ API more general and useful without losing any functionality:
### Other Slices
String slices, as you might imagine, are specific to strings. But there’s a
-more general slice type, too. Consider this array:
+more general slice type too. Consider this array:
```rust
let a = [1, 2, 3, 4, 5];
```
-Just as we might want to refer to a part of a string, we might want to refer
-to part of an array. We’d do so like this:
+Just as we might want to refer to part of a string, we might want to refer to
+part of an array. We’d do so like this:
```rust
let a = [1, 2, 3, 4, 5];
diff --git a/src/doc/book/src/ch05-02-example-structs.md b/src/doc/book/src/ch05-02-example-structs.md
index a83fa0564..5d33d9cb1 100644
--- a/src/doc/book/src/ch05-02-example-structs.md
+++ b/src/doc/book/src/ch05-02-example-structs.md
@@ -198,7 +198,7 @@ that expression, and returns ownership of the value.
> Note: Calling the `dbg!` macro prints to the standard error console stream
> (`stderr`), as opposed to `println!` which prints to the standard output
> console stream (`stdout`). We’ll talk more about `stderr` and `stdout` in the
-> “[“Writing Error Messages to Standard Error Instead of Standard
+> [“Writing Error Messages to Standard Error Instead of Standard
> Output” section in Chapter 12][err]<!-- ignore -->.
Here’s an example where we’re interested in the value that gets assigned to the
diff --git a/src/doc/book/src/ch08-02-strings.md b/src/doc/book/src/ch08-02-strings.md
index bf79c3925..9663d36ab 100644
--- a/src/doc/book/src/ch08-02-strings.md
+++ b/src/doc/book/src/ch08-02-strings.md
@@ -355,7 +355,7 @@ of type `char`, and you can iterate over the result to access each element:
```rust
for c in "Зд".chars() {
- println!("{}", c);
+ println!("{c}");
}
```
@@ -371,7 +371,7 @@ appropriate for your domain:
```rust
for b in "Зд".bytes() {
- println!("{}", b);
+ println!("{b}");
}
```
diff --git a/src/doc/book/src/ch09-01-unrecoverable-errors-with-panic.md b/src/doc/book/src/ch09-01-unrecoverable-errors-with-panic.md
index f5b9fefb8..5675fe3e7 100644
--- a/src/doc/book/src/ch09-01-unrecoverable-errors-with-panic.md
+++ b/src/doc/book/src/ch09-01-unrecoverable-errors-with-panic.md
@@ -120,21 +120,21 @@ $ RUST_BACKTRACE=1 cargo run
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', src/main.rs:4:5
stack backtrace:
0: rust_begin_unwind
- at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/panicking.rs:483
+ at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/std/src/panicking.rs:584:5
1: core::panicking::panic_fmt
- at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/panicking.rs:85
+ at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/panicking.rs:142:14
2: core::panicking::panic_bounds_check
- at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/panicking.rs:62
+ at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/panicking.rs:84:5
3: <usize as core::slice::index::SliceIndex<[T]>>::index
- at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/slice/index.rs:255
+ at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/slice/index.rs:242:10
4: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
- at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/slice/index.rs:15
- 5: <alloc::vec::Vec<T> as core::ops::index::Index<I>>::index
- at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/alloc/src/vec.rs:1982
+ at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/slice/index.rs:18:9
+ 5: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index
+ at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/alloc/src/vec/mod.rs:2591:9
6: panic::main
- at ./src/main.rs:4
+ at ./src/main.rs:4:5
7: core::ops::function::FnOnce::call_once
- at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/ops/function.rs:227
+ at /rustc/e092d0b6b43f2de967af0887873151bb1c0b18d3/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```
diff --git a/src/doc/book/src/ch09-02-recoverable-errors-with-result.md b/src/doc/book/src/ch09-02-recoverable-errors-with-result.md
index 347ef9aa7..2ee006f09 100644
--- a/src/doc/book/src/ch09-02-recoverable-errors-with-result.md
+++ b/src/doc/book/src/ch09-02-recoverable-errors-with-result.md
@@ -6,9 +6,9 @@ interpret and respond to. For example, if you try to open a file and that
operation fails because the file doesn’t exist, you might want to create the
file instead of terminating the process.
-Recall from [“Handling Potential Failure with the `Result`
-Type”][handle_failure]<!-- ignore --> in Chapter 2 that the `Result` enum is
-defined as having two variants, `Ok` and `Err`, as follows:
+Recall from [“Handling Potential Failure with `Result`”][handle_failure]<!--
+ignore --> in Chapter 2 that the `Result` enum is defined as having two
+variants, `Ok` and `Err`, as follows:
```rust
enum Result<T, E> {
@@ -532,6 +532,6 @@ Now that we’ve discussed the details of calling `panic!` or returning `Result`
let’s return to the topic of how to decide which is appropriate to use in which
cases.
-[handle_failure]: ch02-00-guessing-game-tutorial.html#handling-potential-failure-with-the-result-type
+[handle_failure]: ch02-00-guessing-game-tutorial.html#handling-potential-failure-with-result
[trait-objects]: ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types
[termination]: ../std/process/trait.Termination.html
diff --git a/src/doc/book/src/ch13-02-iterators.md b/src/doc/book/src/ch13-02-iterators.md
index 2efa552a8..030ebf48e 100644
--- a/src/doc/book/src/ch13-02-iterators.md
+++ b/src/doc/book/src/ch13-02-iterators.md
@@ -133,7 +133,7 @@ ownership of the iterator we call it on.
consume the iterator. Instead, they produce different iterators by changing
some aspect of the original iterator.
-Listing 13-17 shows an example of calling the iterator adaptor method `map`,
+Listing 13-14 shows an example of calling the iterator adaptor method `map`,
which takes a closure to call on each item as the items are iterated through.
The `map` method returns a new iterator that produces the modified items. The
closure here creates a new iterator in which each item from the vector will be
diff --git a/src/doc/book/src/ch14-02-publishing-to-crates-io.md b/src/doc/book/src/ch14-02-publishing-to-crates-io.md
index 64885d052..c5b1ac7fc 100644
--- a/src/doc/book/src/ch14-02-publishing-to-crates-io.md
+++ b/src/doc/book/src/ch14-02-publishing-to-crates-io.md
@@ -442,10 +442,15 @@ yank. For example, if we've published a crate named `guessing_game` version
1.0.1 and we want to yank it, in the project directory for `guessing_game` we'd
run:
+<!-- manual-regeneration:
+cargo yank carol-test --version 2.1.0
+cargo yank carol-test --version 2.1.0 --undo
+-->
+
```console
$ cargo yank --vers 1.0.1
Updating crates.io index
- Yank guessing_game:1.0.1
+ Yank guessing_game@1.0.1
```
By adding `--undo` to the command, you can also undo a yank and allow projects
@@ -454,7 +459,7 @@ to start depending on a version again:
```console
$ cargo yank --vers 1.0.1 --undo
Updating crates.io index
- Unyank guessing_game_:1.0.1
+ Unyank guessing_game@1.0.1
```
A yank *does not* delete any code. It cannot, for example, delete accidentally
diff --git a/src/doc/book/src/ch14-03-cargo-workspaces.md b/src/doc/book/src/ch14-03-cargo-workspaces.md
index 942d61b46..7c67331b7 100644
--- a/src/doc/book/src/ch14-03-cargo-workspaces.md
+++ b/src/doc/book/src/ch14-03-cargo-workspaces.md
@@ -224,9 +224,9 @@ copy output below; the output updating script doesn't handle subdirectories in p
```console
$ cargo build
Updating crates.io index
- Downloaded rand v0.8.3
+ Downloaded rand v0.8.5
--snip--
- Compiling rand v0.8.3
+ Compiling rand v0.8.5
Compiling add_one v0.1.0 (file:///projects/add/add_one)
warning: unused import: `rand`
--> add_one/src/lib.rs:1:5
@@ -236,8 +236,7 @@ warning: unused import: `rand`
|
= note: `#[warn(unused_imports)]` on by default
-warning: 1 warning emitted
-
+warning: `add_one` (lib) generated 1 warning
Compiling adder v0.1.0 (file:///projects/add/adder)
Finished dev [unoptimized + debuginfo] target(s) in 10.18s
```
@@ -300,14 +299,14 @@ $ cargo test
Compiling add_one v0.1.0 (file:///projects/add/add_one)
Compiling adder v0.1.0 (file:///projects/add/adder)
Finished test [unoptimized + debuginfo] target(s) in 0.27s
- Running target/debug/deps/add_one-f0253159197f7841
+ Running unittests src/lib.rs (target/debug/deps/add_one-f0253159197f7841)
running 1 test
test tests::it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
- Running target/debug/deps/adder-49979ff40686fa8e
+ Running unittests src/main.rs (target/debug/deps/adder-49979ff40686fa8e)
running 0 tests
@@ -338,7 +337,7 @@ copy output below; the output updating script doesn't handle subdirectories in p
```console
$ cargo test -p add_one
Finished test [unoptimized + debuginfo] target(s) in 0.00s
- Running target/debug/deps/add_one-b3235fea9a156f74
+ Running unittests src/lib.rs (target/debug/deps/add_one-b3235fea9a156f74)
running 1 test
test tests::it_works ... ok
diff --git a/src/doc/book/src/ch14-04-installing-binaries.md b/src/doc/book/src/ch14-04-installing-binaries.md
index 425cf9c37..fd821f3a0 100644
--- a/src/doc/book/src/ch14-04-installing-binaries.md
+++ b/src/doc/book/src/ch14-04-installing-binaries.md
@@ -31,14 +31,14 @@ cargo install something you don't have, copy relevant output below
```console
$ cargo install ripgrep
Updating crates.io index
- Downloaded ripgrep v11.0.2
+ Downloaded ripgrep v13.0.0
Downloaded 1 crate (243.3 KB) in 0.88s
- Installing ripgrep v11.0.2
+ Installing ripgrep v13.0.0
--snip--
- Compiling ripgrep v11.0.2
+ Compiling ripgrep v13.0.0
Finished release [optimized + debuginfo] target(s) in 3m 10s
Installing ~/.cargo/bin/rg
- Installed package `ripgrep v11.0.2` (executable `rg`)
+ Installed package `ripgrep v13.0.0` (executable `rg`)
```
The second-to-last line of the output shows the location and the name of the
diff --git a/src/doc/book/src/ch15-00-smart-pointers.md b/src/doc/book/src/ch15-00-smart-pointers.md
index 7552dd5d1..9ecdcc835 100644
--- a/src/doc/book/src/ch15-00-smart-pointers.md
+++ b/src/doc/book/src/ch15-00-smart-pointers.md
@@ -12,7 +12,7 @@ pointer but also have additional metadata and capabilities. The concept of
smart pointers isn’t unique to Rust: smart pointers originated in C++ and exist
in other languages as well. Rust has a variety of smart pointers defined in the
standard library that provide functionality beyond that provided by references.
-To explore the general concept, we'll look at a couple of different examples of
+To explore the general concept, we’ll look at a couple of different examples of
smart pointers, including a *reference counting* smart pointer type. This
pointer enables you to allow data to have multiple owners by keeping track of
the number of owners and, when no owners remain, cleaning up the data.
@@ -21,7 +21,7 @@ Rust, with its concept of ownership and borrowing, has an additional difference
between references and smart pointers: while references only borrow data, in
many cases, smart pointers *own* the data they point to.
-Though we didn't call them as such at the time, we’ve already encountered a few
+Though we didn’t call them as such at the time, we’ve already encountered a few
smart pointers in this book, including `String` and `Vec<T>` in Chapter 8. Both
these types count as smart pointers because they own some memory and allow you
to manipulate it. They also have metadata and extra capabilities or guarantees.
@@ -32,7 +32,7 @@ Smart pointers are usually implemented using structs. Unlike an ordinary
struct, smart pointers implement the `Deref` and `Drop` traits. The `Deref`
trait allows an instance of the smart pointer struct to behave like a reference
so you can write your code to work with either references or smart pointers.
-The `Drop` trait allows you to customize the code that's run when an instance
+The `Drop` trait allows you to customize the code that’s run when an instance
of the smart pointer goes out of scope. In this chapter, we’ll discuss both
traits and demonstrate why they’re important to smart pointers.
diff --git a/src/doc/book/src/ch15-01-box.md b/src/doc/book/src/ch15-01-box.md
index 030a7842d..838062552 100644
--- a/src/doc/book/src/ch15-01-box.md
+++ b/src/doc/book/src/ch15-01-box.md
@@ -82,7 +82,7 @@ function”) in Lisp that constructs a new pair from its two arguments. By
calling `cons` on a pair consisting of a value and another pair, we can
construct cons lists made up of recursive pairs.
-For example, here's a pseudocode representation of a cons list containing the
+For example, here’s a pseudocode representation of a cons list containing the
list 1, 2, 3 with each pair in parentheses:
```text
@@ -150,7 +150,7 @@ a recursive enum</span>
The error shows this type “has infinite size.” The reason is that we’ve defined
`List` with a variant that is recursive: it holds another value of itself
directly. As a result, Rust can’t figure out how much space it needs to store a
-`List` value. Let’s break down why we get this error. First, we'll look at how
+`List` value. Let’s break down why we get this error. First, we’ll look at how
Rust decides how much space it needs to store a value of a non-recursive type.
#### Computing the Size of a Non-Recursive Type
@@ -196,7 +196,7 @@ after doing automatic regeneration, look at listings/ch15-smart-pointers/listing
help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `List` representable
|
2 | Cons(i32, Box<List>),
- | ^^^^ ^
+ | ++++ +
```
In this suggestion, “indirection” means that instead of storing a value
diff --git a/src/doc/book/src/ch15-02-deref.md b/src/doc/book/src/ch15-02-deref.md
index ba0b8990f..23c9fe8bf 100644
--- a/src/doc/book/src/ch15-02-deref.md
+++ b/src/doc/book/src/ch15-02-deref.md
@@ -73,11 +73,12 @@ Listing 15-6:
`Box<i32>`</span>
The main difference between Listing 15-7 and Listing 15-6 is that here we set
-`y` to be an instance of a box pointing to a copied value of `x` rather than a
-reference pointing to the value of `x`. In the last assertion, we can use the
-dereference operator to follow the box’s pointer in the same way that we did
-when `y` was a reference. Next, we’ll explore what is special about `Box<T>`
-that enables us to use the dereference operator by defining our own box type.
+`y` to be an instance of a `Box<T>` pointing to a copied value of `x` rather
+than a reference pointing to the value of `x`. In the last assertion, we can
+use the dereference operator to follow the pointer of the `Box<T>` in the same
+way that we did when `y` was a reference. Next, we’ll explore what is special
+about `Box<T>` that enables us to use the dereference operator by defining our
+own type.
### Defining Our Own Smart Pointer
diff --git a/src/doc/book/src/ch15-03-drop.md b/src/doc/book/src/ch15-03-drop.md
index 1ab2b86f0..05ab86873 100644
--- a/src/doc/book/src/ch15-03-drop.md
+++ b/src/doc/book/src/ch15-03-drop.md
@@ -58,7 +58,7 @@ When we run this program, we’ll see the following output:
Rust automatically called `drop` for us when our instances went out of scope,
calling the code we specified. Variables are dropped in the reverse order of
-their creation, so `d` was dropped before `c`. This example's purpose is to
+their creation, so `d` was dropped before `c`. This example’s purpose is to
give you a visual guide to how the `drop` method works; usually you would
specify the cleanup code that your type needs to run rather than a print
message.
diff --git a/src/doc/book/src/ch15-05-interior-mutability.md b/src/doc/book/src/ch15-05-interior-mutability.md
index 74bb02f05..7b5e825d7 100644
--- a/src/doc/book/src/ch15-05-interior-mutability.md
+++ b/src/doc/book/src/ch15-05-interior-mutability.md
@@ -103,11 +103,11 @@ an immutable value and see why that is useful.
#### A Use Case for Interior Mutability: Mock Objects
Sometimes during testing a programmer will use a type in place of another type,
-in order to observe particular behavior and assert it's implemented correctly.
+in order to observe particular behavior and assert it’s implemented correctly.
This placeholder type is called a *test double*. Think of it in the sense of a
-"stunt double" in filmmaking, where a person steps in and substitutes for an
+“stunt double” in filmmaking, where a person steps in and substitutes for an
actor to do a particular tricky scene. Test doubles stand in for other types
-when we're running tests. *Mock objects* are specific types of test doubles
+when we’re running tests. *Mock objects* are specific types of test doubles
that record what happens during a test so you can assert that the correct
actions took place.
@@ -273,7 +273,7 @@ BorrowMutError`. This is how `RefCell<T>` handles violations of the borrowing
rules at runtime.
Choosing to catch borrowing errors at runtime rather than compile time, as
-we've done here, means you'd potentially be finding mistakes in your code later
+we’ve done here, means you’d potentially be finding mistakes in your code later
in the development process: possibly not until your code was deployed to
production. Also, your code would incur a small runtime performance penalty as
a result of keeping track of the borrows at runtime rather than compile time.
diff --git a/src/doc/book/src/ch15-06-reference-cycles.md b/src/doc/book/src/ch15-06-reference-cycles.md
index 4b55d88a6..bef289202 100644
--- a/src/doc/book/src/ch15-06-reference-cycles.md
+++ b/src/doc/book/src/ch15-06-reference-cycles.md
@@ -117,7 +117,7 @@ up if its `strong_count` is 0. You can also create a *weak reference* to the
value within an `Rc<T>` instance by calling `Rc::downgrade` and passing a
reference to the `Rc<T>`. Strong references are how you can share ownership of
an `Rc<T>` instance. Weak references don’t express an ownership relationship,
-and their count doesn't affect when an `Rc<T>` instance is cleaned up. They
+and their count doesn’t affect when an `Rc<T>` instance is cleaned up. They
won’t cause a reference cycle because any cycle involving some weak references
will be broken once the strong reference count of values involved is 0.
diff --git a/src/doc/book/src/ch16-01-threads.md b/src/doc/book/src/ch16-01-threads.md
index 52947a99b..cfdd0c706 100644
--- a/src/doc/book/src/ch16-01-threads.md
+++ b/src/doc/book/src/ch16-01-threads.md
@@ -173,7 +173,7 @@ threads run at the same time.
We'll often use the `move` keyword with closures passed to `thread::spawn`
because the closure will then take ownership of the values it uses from the
environment, thus transferring ownership of those values from one thread to
-another. In the [“Capturing the Environment with Closures”][capture]<!-- ignore
+another. In the [“Capturing References or Moving Ownership”][capture]<!-- ignore
--> section of Chapter 13, we discussed `move` in the context of closures. Now,
we’ll concentrate more on the interaction between `move` and `thread::spawn`.
@@ -278,4 +278,4 @@ ownership rules.
With a basic understanding of threads and the thread API, let’s look at what we
can *do* with threads.
-[capture]: ch13-01-closures.html#capturing-the-environment-with-closures
+[capture]: ch13-01-closures.html#capturing-references-or-moving-ownership
diff --git a/src/doc/book/src/ch16-03-shared-state.md b/src/doc/book/src/ch16-03-shared-state.md
index 41dccfa13..918d162cf 100644
--- a/src/doc/book/src/ch16-03-shared-state.md
+++ b/src/doc/book/src/ch16-03-shared-state.md
@@ -219,9 +219,9 @@ thread update the final result with its part.
Note that if you are doing simple numerical operations, there are types simpler
than `Mutex<T>` types provided by the [`std::sync::atomic` module of the
-standard library][atomic]. These types provide safe, concurrent, atomic access
-to primitive types. We chose to use `Mutex<T>` with a primitive type for this
-example so we could concentrate on how `Mutex<T>` works.
+standard library][atomic]<!-- ignore -->. These types provide safe, concurrent,
+atomic access to primitive types. We chose to use `Mutex<T>` with a primitive
+type for this example so we could concentrate on how `Mutex<T>` works.
### Similarities Between `RefCell<T>`/`Rc<T>` and `Mutex<T>`/`Arc<T>`