summaryrefslogtreecommitdiffstats
path: root/src/doc/book/nostarch/chapter02.md
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/doc/book/nostarch/chapter02.md
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/doc/book/nostarch/chapter02.md')
-rw-r--r--src/doc/book/nostarch/chapter02.md1111
1 files changed, 1111 insertions, 0 deletions
diff --git a/src/doc/book/nostarch/chapter02.md b/src/doc/book/nostarch/chapter02.md
new file mode 100644
index 000000000..b7986c0de
--- /dev/null
+++ b/src/doc/book/nostarch/chapter02.md
@@ -0,0 +1,1111 @@
+<!-- DO NOT EDIT THIS FILE.
+
+This file is periodically generated from the content in the `/src/`
+directory, so all fixes need to be made in `/src/`.
+-->
+
+[TOC]
+
+# Programming a Guessing Game
+
+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
+fundamentals.
+
+We’ll implement a classic beginner programming problem: a guessing game. Here’s
+how it works: the program will generate a random integer between 1 and 100. It
+will then prompt the player to enter a guess. After a guess is entered, the
+program will indicate whether the guess is too low or too high. If the guess is
+correct, the game will print a congratulatory message and exit.
+
+## Setting Up a New Project
+
+To set up a new project, go to the *projects* directory that you created in
+Chapter 1 and make a new project using Cargo, like so:
+
+```
+$ cargo new guessing_game
+$ cd guessing_game
+```
+
+The first command, `cargo new`, takes the name of the project (`guessing_game`)
+as the first argument. The second command changes to the new project’s
+directory.
+
+Look at the generated *Cargo.toml* file:
+
+Filename: Cargo.toml
+
+```
+[package]
+name = "guessing_game"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+```
+
+<!--- We should move to the 2021 edition. /JT --->
+<!-- Totally right, done! /Carol -->
+
+As you saw in Chapter 1, `cargo new` generates a “Hello, world!” program for
+you. Check out the *src/main.rs* file:
+
+Filename: src/main.rs
+
+```
+fn main() {
+ println!("Hello, world!");
+}
+```
+
+Now let’s compile this “Hello, world!” program and run it in the same step
+using the `cargo run` command:
+
+```
+$ cargo run
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Finished dev [unoptimized + debuginfo] target(s) in 1.50s
+ Running `target/debug/guessing_game`
+Hello, world!
+```
+
+The `run` command comes in handy when you need to rapidly iterate on a project,
+as we’ll do in this game, quickly testing each iteration before moving on to
+the next one.
+
+Reopen the *src/main.rs* file. You’ll be writing all the code in this file.
+
+## Processing a Guess
+
+The first part of the guessing game program will ask for user input, process
+that input, and check that the input is in the expected form. To start, we’ll
+allow the player to input a guess. Enter the code in Listing 2-1 into
+*src/main.rs*.
+
+Filename: src/main.rs
+
+```
+use std::io;
+
+fn main() {
+ println!("Guess the number!");
+
+ println!("Please input your guess.");
+
+ let mut guess = String::new();
+
+ io::stdin()
+ .read_line(&mut guess)
+ .expect("Failed to read line");
+
+ println!("You guessed: {guess}");
+}
+```
+
+<!--- Style question, should we switch to the more recent style of:
+```
+ println!("You guessed: {guess}");
+```
+/JT --->
+<!-- Good call, I'll switch these throughout as I edit after TR. /Carol -->
+
+Listing 2-1: Code that gets a guess from the user and prints it
+
+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`:
+
+```
+use std::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 at *https://doc.rust-lang.org/std/prelude/index.html*.
+
+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
+provides you with a number of useful features, including the ability to accept
+user input.
+
+As you saw in Chapter 1, the `main` function is the entry point into the
+program:
+
+```
+fn 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.
+
+As you also learned in Chapter 1, `println!` is a macro that prints a string to
+the screen:
+
+<!--- Not sure if we want to go into it just yet, but `println!` formats a string
+and then prints the resulting string to stdout (which is often, but not always
+the screen). /JT --->
+<!-- Yeah, I want to gloss over that for now. Leaving this as-is. /Carol -->
+
+```
+ println!("Guess the number!");
+
+ println!("Please input your guess.");
+```
+
+This code is printing a prompt stating what the game is and requesting input
+from the user.
+
+### Storing Values with Variables
+
+Next, we’ll create a *variable* to store the user input, like this:
+
+```
+ let mut guess = String::new();
+```
+
+Now the program is getting interesting! There’s a lot going on in this little
+line. We use the `let` statement to create the variable. Here’s another example:
+
+```
+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
+the “Variables and Mutability” section in Chapter 3. To make a variable
+mutable, we add `mut` before the variable name:
+
+<!--- Do we want to give a quick word about what "mutable" means? Folks who grab
+this book but aren't familiar with some of the technical programming language terms
+might need something like "variable are immutable by default, meaning once we give
+the variable its value, it won't change". /JT --->
+<!-- Sounds good, made that change /Carol -->
+
+```
+let apples = 5; // immutable
+let mut bananas = 5; // mutable
+```
+
+> Note: The `//` syntax starts a comment that continues until the end of the
+> line. Rust ignores everything in comments. We’ll discuss comments in more
+> detail in Chapter 3.
+
+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
+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`
+is a string type provided by the standard 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
+common name for a function that makes a new value of some kind.
+
+<!--- For some readers, we might want to say "If you've used languages with
+static methods, associated function work very similarly" or something along
+those lines. /JT --->
+<!-- I don't think that's helpful enough for all readers to include here, given
+that we're trying to make the book mostly background-agnostic. /Carol -->
+
+In full, the `let mut guess = String::new();` line has created a mutable
+variable that is currently bound to a new, empty instance of a `String`. Whew!
+
+### Receiving User Input
+
+Recall that we included the input/output functionality from the standard
+library with `use std::io;` on the first line of the program. Now we’ll call
+the `stdin` function from the `io` module, which will allow us to handle user
+input:
+
+```
+ io::stdin()
+ .read_line(&mut guess)
+```
+
+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`,
+which is a type that represents a handle to the standard input for your
+terminal.
+
+Next, the line `.read_line(&mut guess)` calls the `read_line` method on the
+standard input handle to get input from the user. We’re also passing `&mut
+guess` as the argument to `read_line` to tell it what string to store the user
+input in. The full job of `read_line` is to take whatever the user types into
+standard input and append that into a string (without overwriting its
+contents), so we therefore pass that string as an argument. The string argument
+needs to be mutable so the method can change the string’s content.
+
+The `&` indicates that this argument is a *reference*, which gives you a way to
+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
+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
+
+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
+part is this method:
+
+<!--- in the program this is the second line of code -- do you mean the third
+section of this line? -->
+<!-- This is still discussing the code in Listing 2-1, and is going to talk
+about the third line, if you're counting the lines of the page, of this logical
+line of code, where logical lines of code are ended with semicolons. Do you
+have suggestions on how to make that clearer? /Carol -->
+<!--- Ashley, does this all track now? /LC --->
+
+```
+ .expect("Failed to read line");
+```
+
+We could have written this code as:
+
+```
+io::stdin().read_line(&mut guess).expect("Failed to read line");
+```
+
+However, one long line is difficult to read, so it’s best to divide it. It’s
+often wise to introduce a newline and other whitespace to help break up long
+lines when you call a method with the `.method_name()` syntax. Now let’s
+discuss what this line does.
+
+As mentioned earlier, `read_line` puts whatever the user enters into the string
+we pass to it, but it also returns a `Result` value. `Result` is an
+*enumeration*, often called an *enum*, which is a type that can be in one of
+multiple possible states. We call each possible state a *variant*.
+
+<!--- Typo above: possibilities /JT --->
+<!--- Personally, I think the above paragraph might be introducing a little too
+much all at once. You might be able to shorten it to: "`Result` is an *enumeration*,
+often called an *enum*, which is a type that can be in one of multiple possible
+states. We call each possible state a *variant*. /JT --->
+<!-- I like it, made that change /Carol -->
+
+Chapter 6 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
+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.
+
+Values of the `Result` type, like values of any type, have methods defined on
+them. An instance of `Result` has an `expect` method that you can call. If this
+instance of `Result` is an `Err` value, `expect` will cause the program to
+crash and display the message that you passed as an argument to `expect`. If
+the `read_line` method returns an `Err`, it would likely be the result of an
+error coming from the underlying operating system. If this instance of `Result`
+is an `Ok` value, `expect` will take the return value that `Ok` is holding and
+return just that value to you so you can use it. In this case, that value is
+the number of bytes in the user’s input.
+
+If you don’t call `expect`, the program will compile, but you’ll get a warning:
+
+```
+$ cargo build
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+warning: unused `Result` that must be used
+ --> src/main.rs:10:5
+ |
+10 | io::stdin().read_line(&mut guess);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(unused_must_use)]` on by default
+ = note: this `Result` may be an `Err` variant, which should be handled
+
+warning: `guessing_game` (bin "guessing_game") generated 1 warning
+ Finished dev [unoptimized + debuginfo] target(s) in 0.59s
+```
+
+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 9.
+
+### Printing Values with `println!` Placeholders
+
+Aside from the closing curly bracket, there’s only one more line to discuss in
+the code so far:
+
+```
+ println!("You guessed: {guess}");
+```
+
+<!--- Ditto with using the `{guess}` style in this line. /JT --->
+
+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:
+
+```
+let x = 5;
+let y = 10;
+
+println!("x = {x} and y = {y}");
+```
+<!--- And `println!("x = {x} and y = {y}");` in this example. /JT --->
+<!-- Done! /Carol -->
+
+This code would print `x = 5 and y = 10`.
+
+### Testing the First Part
+
+Let’s test the first part of the guessing game. Run it using `cargo run`:
+
+```
+$ cargo run
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Finished dev [unoptimized + debuginfo] target(s) in 6.44s
+ Running `target/debug/guessing_game`
+Guess the number!
+Please input your guess.
+6
+You guessed: 6
+```
+
+At this point, the first part of the game is done: we’re getting input from the
+keyboard and then printing it.
+
+## Generating a Secret Number
+
+Next, we need to generate a secret number that the user will try to guess. The
+secret number should be different every time so the game is fun to play more
+than once. We’ll use a random number between 1 and 100 so the game isn’t too
+difficult. Rust doesn’t yet include random number functionality in its standard
+library. However, the Rust team does provide a `rand` crate at
+*https://crates.io/crates/rand* with said functionality.
+
+### Using a Crate to Get More 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.
+
+<!--- Nit: ", and" followed by incomplete sentence. /JT --->
+<!-- Fixed /Carol -->
+
+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
+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.
+
+Filename: Cargo.toml
+
+```
+rand = "0.8.3"
+```
+<!--- 0.8.5 is the current latest. /JT --->
+<!-- I will update this version to whatever is latest once we're in Word; there
+could be another version between now and then. If it's another 0.8.x version,
+it doesn't really matter in any case. /Carol -->
+
+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 Versioning
+(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`.
+
+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.
+
+Now, without changing any of the code, let’s build the project, as shown in
+Listing 2-2.
+
+```
+$ cargo build
+ Updating crates.io index
+ Downloaded rand v0.8.3
+ Downloaded libc v0.2.86
+ Downloaded getrandom v0.2.2
+ 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
+ Compiling cfg-if v1.0.0
+ Compiling ppv-lite86 v0.2.10
+ Compiling rand_chacha v0.3.0
+ Compiling rand v0.8.3
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Finished dev [unoptimized + debuginfo] target(s) in 2.53s
+```
+<!--- If we feel like refreshing this, here's what I saw today:
+
+ Compiling cfg-if v1.0.0
+ Compiling ppv-lite86 v0.2.16
+ Compiling libc v0.2.120
+ Compiling getrandom v0.2.5
+ Compiling rand_core v0.6.3
+ Compiling rand_chacha v0.3.1
+ Compiling rand v0.8.5
+ Compiling guessing_game v0.1.0 (/Users/jt/Source/book/guessing_game)
+ Finished dev [unoptimized + debuginfo] target(s) in 1.50s
+
+/JT --->
+<!-- I will refresh this when we're in Word /Carol -->
+
+Listing 2-2: The output from running `cargo build` after adding the rand crate
+as a dependency
+
+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.
+
+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
+from Crates.io at *https://crates.io/*. Crates.io is where people in the Rust
+ecosystem post their open source Rust projects for others to use.
+
+After updating the registry, Cargo checks the `[dependencies]` section and
+downloads any crates listed that aren’t already downloaded. In this case,
+although we only listed `rand` as a dependency, Cargo also grabbed other crates
+that `rand` depends on to work. After downloading the crates, Rust compiles
+them and then compiles the project with the dependencies available.
+
+If you immediately run `cargo build` again without making any changes, you
+won’t get any output aside from the `Finished` line. Cargo knows it has already
+downloaded and compiled the dependencies, and you haven’t changed anything
+about them in your *Cargo.toml* file. Cargo also knows that you haven’t changed
+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:
+
+```
+$ cargo build
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs
+```
+
+These lines show 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.
+
+#### Ensuring Reproducible Builds with the *Cargo.lock* File
+
+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
+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.
+
+<!--- If we bump version numbers, we should bump above and below also. /JT --->
+<!-- Yup, will do in Word! /Carol -->
+
+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
+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.
+
+<!--- We could mention that because Cargo.lock is important for reproducible
+builds, they're often checked into source control alongside the Cargo.toml and
+the rest of the code of your project. /JT --->
+<!-- Liz, is this sentence ok even though we don't really talk about source
+control or what it is anywhere else in the book? I don't really want to get
+into it, but at this point I think it's a fair assumption that developers know
+what "source control" is. If you disagree, this sentence can come back out.
+/Carol -->
+
+#### Updating a Crate to Get a New Version
+
+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`:
+
+```
+$ cargo update
+ Updating crates.io index
+ Updating rand v0.8.3 -> v0.8.4
+```
+
+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:
+
+<!--- Typo first line: release. /JT --->
+<!-- Fixed /Carol -->
+
+```
+[dependencies]
+rand = "0.9.0"
+```
+
+The next time you run `cargo build`, Cargo will update the registry of crates
+available and reevaluate your `rand` requirements according to the new version
+you have specified.
+
+There’s a lot more to say about Cargo and its ecosystem 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.
+
+### Generating a Random Number
+
+Let’s start using `rand` to generate a number to guess. The next step is to
+update *src/main.rs*, as shown in Listing 2-3.
+
+Filename: src/main.rs
+
+```
+use std::io;
+[1]use rand::Rng;
+
+fn main() {
+ println!("Guess the number!");
+
+ [2] let secret_number = rand::thread_rng().gen_range(1..=100);
+
+ [3] println!("The secret number is: {secret_number}");
+
+ println!("Please input your guess.");
+
+ let mut guess = String::new();
+
+ io::stdin()
+ .read_line(&mut guess)
+ .expect("Failed to read line");
+
+ println!("You guessed: {guess}");
+}
+```
+
+<!--- Same style suggestion re: `{secret_number}`. /JT --->
+<!--- Thought: for first-time readability, we could use `1..=100` in the above
+and let people know later this is equivalent to `1..101` later. We say a number
+between 1 and 100, so we could show the syntax equivalent of that description.
+/JT --->
+<!-- I'm into both these suggestions! /Carol -->
+
+Listing 2-3: Adding code to generate a random number
+
+<!--- I can't remember how we handled wingdings in markdown before... I don't
+have those files on this machine. I've just used [x] for now, does that work?
+Then we'll replace them when we convert to Word /LC --->
+<!-- I don't think we added the wingdings at all until we moved to Word. For
+code listings that are the same as the last printing version, I'd definitely
+like to keep the wingdings the way they were. Using the brackets with numbers
+as you have here works fine! /Carol -->
+
+First, we add the line `use rand::Rng` [1]. 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 [2], 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`
+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
+`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
+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 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.
+
+The second new line [3] prints the secret number. This is useful while
+we’re developing the program to be able to test it, but we’ll delete it from
+the final version. It’s not much of a game if the program prints the answer as
+soon as it starts!
+
+Try running the program a few times:
+
+```
+$ cargo run
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Finished dev [unoptimized + debuginfo] target(s) in 2.53s
+ Running `target/debug/guessing_game`
+Guess the number!
+The secret number is: 7
+Please input your guess.
+4
+You guessed: 4
+
+$ cargo run
+ Finished dev [unoptimized + debuginfo] target(s) in 0.02s
+ Running `target/debug/guessing_game`
+Guess the number!
+The secret number is: 83
+Please input your guess.
+5
+You guessed: 5
+```
+
+You should get different random numbers, and they should all be numbers between
+1 and 100. Great job!
+
+## 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.
+
+Filename: src/main.rs
+
+```
+use rand::Rng;
+[1]use std::cmp::Ordering;
+use std::io;
+
+fn main() {
+ // --snip--
+
+ println!("You guessed: {guess}");
+
+ match[2] guess.cmp(&secret_number)[3] {
+ Ordering::Less => println!("Too small!"),
+ Ordering::Greater => println!("Too big!"),
+ Ordering::Equal => println!("You win!"),
+ }
+}
+```
+
+Listing 2-4: Handling the possible return values of comparing two numbers
+
+First we add another `use` statement [1], bringing a type called
+`std::cmp::Ordering` into scope from the standard library. The `Ordering` type
+is another enum and has the variants `Less`, `Greater`, and `Equal`. These are
+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 [3] 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
+`Ordering` enum we brought into scope with the `use` statement. We use a
+`match` expression [2] to decide what to do next based on which variant of
+`Ordering` was returned from the call to `cmp` with the values in `guess` and
+`secret_number`.
+
+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
+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
+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
+that arm and moves to the next arm. The next arm’s pattern is
+`Ordering::Greater`, which *does* match `Ordering::Greater`! The associated
+code in that arm will execute and print `Too big!` to the screen. The `match`
+expression ends after the first successful match, so it won’t look at the last
+arm in this scenario.
+
+<!--- Since `match` always ends after the first successful match, we might want
+to just say that directly: "The `match` expression ends after the first successful
+match, so it won't look at the last arm in this scenario". /JT --->
+<!-- Sounds good, done! /Carol -->
+
+However, the code in Listing 2-4 won’t compile yet. Let’s try it:
+
+```
+$ cargo build
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+error[E0308]: mismatched types
+ --> src/main.rs:22:21
+ |
+22 | match guess.cmp(&secret_number) {
+ | ^^^^^^^^^^^^^^ expected struct `String`, found integer
+ |
+ = note: expected reference `&String`
+ found reference `&{integer}`
+```
+
+The core of the error states that there are *mismatched types*. Rust has a
+strong, static type system. However, it also has type inference. When we wrote
+`let mut guess = String::new()`, Rust was able to infer that `guess` should be
+a `String` and didn’t make us write the type. The `secret_number`, on the other
+hand, is a number type. A few of Rust’s number types can have a value between 1
+and 100: `i32`, a 32-bit number; `u32`, an unsigned 32-bit number; `i64`, a
+64-bit number; as well as others. Unless otherwise specified, Rust defaults to
+an `i32`, which is the type of `secret_number` unless you add type information
+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.
+
+<!--- Typo: Unless otherwise specified. /JT --->
+<!-- Fixed /Carol -->
+
+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:
+
+Filename: src/main.rs
+
+```
+ // --snip--
+
+ let mut guess = String::new();
+
+ io::stdin()
+ .read_line(&mut guess)
+ .expect("Failed to read line");
+
+ let guess: u32 = guess.trim().parse().expect("Please type a number!");
+
+ println!("You guessed: {guess}");
+
+ match guess.cmp(&secret_number) {
+ Ordering::Less => println!("Too small!"),
+ Ordering::Greater => println!("Too big!"),
+ Ordering::Equal => println!("You win!"),
+ }
+```
+
+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`
+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.
+
+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
+input as a string. The `trim` method on a `String` instance will eliminate any
+whitespace at the beginning and end, which we must do to be able to compare the
+string to the `u32`, which can only contain numerical data. The user must press
+<span class="keystroke">enter</span> to satisfy `read_line` and input their
+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
+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`.
+
+The `parse` method on strings converts a string to another type. Here, we use
+it to convert from a string to a number. We need to 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!
+
+<!--- More correct to say "The `parse` method converts a string to another type.
+Here, we use it to convert from a string to a number." You can use `parse` to
+convert to non-numeric types also. /JT --->
+<!-- Great catch, fixed! /Carol -->
+
+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”). 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!
+
+```
+$ cargo run
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Finished dev [unoptimized + debuginfo] target(s) in 0.43s
+ Running `target/debug/guessing_game`
+Guess the number!
+The secret number is: 58
+Please input your guess.
+ 76
+You guessed: 76
+Too big!
+```
+
+Nice! Even though spaces were added before the guess, the program still figured
+out that the user guessed 76. Run the program a few times to verify the
+different behavior with different kinds of input: guess the number correctly,
+guess a number that is too high, and guess a number that is too low.
+
+We have most of the game working now, but the user can make only one guess.
+Let’s change that by adding a loop!
+
+## Allowing Multiple Guesses with Looping
+
+The `loop` keyword creates an infinite loop. We’ll add a loop to give users
+more chances at guessing the number:
+
+Filename: src/main.rs
+
+```
+ // --snip--
+
+ println!("The secret number is: {secret_number}");
+
+ loop {
+ println!("Please input your guess.");
+
+ // --snip--
+
+ match guess.cmp(&secret_number) {
+ Ordering::Less => println!("Too small!"),
+ Ordering::Greater => println!("Too big!"),
+ Ordering::Equal => println!("You win!"),
+ }
+ }
+}
+```
+
+As you can see, we’ve moved everything from the guess input prompt onward into
+a loop. Be sure to indent the lines inside the loop another four spaces each
+and run the program again. The program will now ask for another guess forever,
+which actually introduces a new problem. It doesn’t seem like the user can quit!
+
+The user could always interrupt the program by using the keyboard shortcut
+<span class="keystroke">ctrl-c</span>. But there’s another way to escape this
+insatiable monster, as mentioned in the `parse` discussion in “Comparing the
+Guess to the Secret Number”: if the user enters a non-number answer, the
+program will crash. We can take advantage of that to allow the user to quit, as
+shown here:
+
+```
+$ cargo run
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Finished dev [unoptimized + debuginfo] target(s) in 1.50s
+ Running `target/debug/guessing_game`
+Guess the number!
+The secret number is: 59
+Please input your guess.
+45
+You guessed: 45
+Too small!
+Please input your guess.
+60
+You guessed: 60
+Too big!
+Please input your guess.
+59
+You guessed: 59
+You win!
+Please input your guess.
+quit
+thread 'main' panicked at 'Please type a number!: ParseIntError { kind: InvalidDigit }', src/main.rs:28:47
+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
+to also stop when the correct number is guessed.
+
+### Quitting After a Correct Guess
+
+Let’s program the game to quit when the user wins by adding a `break` statement:
+
+Filename: src/main.rs
+
+```
+ // --snip--
+
+ match guess.cmp(&secret_number) {
+ Ordering::Less => println!("Too small!"),
+ Ordering::Greater => println!("Too big!"),
+ Ordering::Equal => {
+ println!("You win!");
+ break;
+ }
+ }
+ }
+}
+```
+
+Adding the `break` line after `You win!` makes the program exit the loop when
+the user guesses the secret number correctly. Exiting the loop also means
+exiting the program, because the loop is the last part of `main`.
+
+### Handling Invalid Input
+
+To further refine the game’s behavior, rather than crashing the program when
+the user inputs a non-number, let’s make the game ignore a non-number so the
+user can continue guessing. We can do that by altering the line where `guess`
+is converted from a `String` to a `u32`, as shown in Listing 2-5.
+
+Filename: src/main.rs
+
+```
+ // --snip--
+
+ io::stdin()
+ .read_line(&mut guess)
+ .expect("Failed to read line");
+
+ let guess: u32 = match guess.trim().parse() {
+ Ok(num) => num,
+ Err(_) => continue,
+ };
+
+ println!("You guessed: {guess}");
+
+ // --snip--
+```
+
+Listing 2-5: Ignoring a non-number guess and asking for another guess instead
+of crashing the program
+
+We switch from an `expect` call to a `match` expression to move from crashing
+on an error to handling the error. Remember that `parse` returns a `Result`
+type and `Result` is an enum that has the variants `Ok` and `Err`. We’re using
+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
+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.
+
+If `parse` is *not* able to turn the string into a number, it will return an
+`Err` value that contains more information about the error. The `Err` value
+does not match the `Ok(num)` pattern in the first `match` arm, but it does
+match the `Err(_)` pattern in the second arm. The underscore, `_`, is a
+catchall value; in this example, we’re saying we want to match all `Err`
+values, no matter what information they have inside them. So the program will
+execute the second arm’s code, `continue`, which tells the program to go to the
+next iteration of the `loop` and ask for another guess. So, effectively, the
+program ignores all errors that `parse` might encounter!
+
+Now everything in the program should work as expected. Let’s try it:
+
+```
+$ cargo run
+ Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
+ Finished dev [unoptimized + debuginfo] target(s) in 4.45s
+ Running `target/debug/guessing_game`
+Guess the number!
+The secret number is: 61
+Please input your guess.
+10
+You guessed: 10
+Too small!
+Please input your guess.
+99
+You guessed: 99
+Too big!
+Please input your guess.
+foo
+Please input your guess.
+61
+You guessed: 61
+You win!
+```
+
+Awesome! With one tiny final tweak, we will finish the guessing game. Recall
+that the program is still printing the secret number. That worked well for
+testing, but it ruins the game. Let’s delete the `println!` that outputs the
+secret number. Listing 2-6 shows the final code.
+
+Filename: src/main.rs
+
+```
+use rand::Rng;
+use std::cmp::Ordering;
+use std::io;
+
+fn main() {
+ println!("Guess the number!");
+
+ let secret_number = rand::thread_rng().gen_range(1..=100);
+
+ loop {
+ println!("Please input your guess.");
+
+ let mut guess = String::new();
+
+ io::stdin()
+ .read_line(&mut guess)
+ .expect("Failed to read line");
+
+ let guess: u32 = match guess.trim().parse() {
+ Ok(num) => num,
+ Err(_) => continue,
+ };
+
+ println!("You guessed: {guess}");
+
+ match guess.cmp(&secret_number) {
+ Ordering::Less => println!("Too small!"),
+ Ordering::Greater => println!("Too big!"),
+ Ordering::Equal => {
+ println!("You win!");
+ break;
+ }
+ }
+ }
+}
+```
+
+Listing 2-6: Complete guessing game code
+
+## Summary
+
+At this point, you’ve successfully built the guessing game. Congratulations!
+
+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
+covers concepts that most programming languages have, such as variables, data
+types, and functions, and shows how to use them in Rust. Chapter 4 explores
+ownership, a feature that makes Rust different from other languages. Chapter 5
+discusses structs and method syntax, and Chapter 6 explains how enums work.