]> git.lizzy.rs Git - rust.git/blob - src/doc/trpl/guessing-game.md
TRPL: Add `rust` Marker to Some Code Block
[rust.git] / src / doc / trpl / guessing-game.md
1 % Guessing Game
2
3 For our first project, we’ll implement a classic beginner programming problem:
4 the guessing game. Here’s how it works: Our program will generate a random
5 integer between one and a hundred. It will then prompt us to enter a guess.
6 Upon entering our guess, it will tell us if we’re too low or too high. Once we
7 guess correctly, it will congratulate us. Sounds good?
8
9 # Set up
10
11 Let’s set up a new project. Go to your projects directory. Remember how we had
12 to create our directory structure and a `Cargo.toml` for `hello_world`? Cargo
13 has a command that does that for us. Let’s give it a shot:
14
15 ```bash
16 $ cd ~/projects
17 $ cargo new guessing_game --bin
18 $ cd guessing_game
19 ```
20
21 We pass the name of our project to `cargo new`, and then the `--bin` flag,
22 since we’re making a binary, rather than a library.
23
24 Check out the generated `Cargo.toml`:
25
26 ```toml
27 [package]
28
29 name = "guessing_game"
30 version = "0.1.0"
31 authors = ["Your Name <you@example.com>"]
32 ```
33
34 Cargo gets this information from your environment. If it’s not correct, go ahead
35 and fix that.
36
37 Finally, Cargo generated a ‘Hello, world!’ for us. Check out `src/main.rs`:
38
39 ```rust
40 fn main() {
41     println!("Hello, world!")
42 }
43 ```
44
45 Let’s try compiling what Cargo gave us:
46
47 ```{bash}
48 $ cargo build
49    Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
50 ```
51
52 Excellent! Open up your `src/main.rs` again. We’ll be writing all of
53 our code in this file.
54
55 Before we move on, let me show you one more Cargo command: `run`. `cargo run`
56 is kind of like `cargo build`, but it also then runs the produced executable.
57 Try it out:
58
59 ```bash
60 $ cargo run
61    Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
62      Running `target/debug/guessing_game`
63 Hello, world!
64 ```
65
66 Great! The `run` command comes in handy when you need to rapidly iterate on a
67 project. Our game is just such a project, we need to quickly test each
68 iteration before moving on to the next one.
69
70 # Processing a Guess
71
72 Let’s get to it! The first thing we need to do for our guessing game is
73 allow our player to input a guess. Put this in your `src/main.rs`:
74
75 ```rust,no_run
76 use std::io;
77
78 fn main() {
79     println!("Guess the number!");
80
81     println!("Please input your guess.");
82
83     let mut guess = String::new();
84
85     io::stdin().read_line(&mut guess)
86         .ok()
87         .expect("Failed to read line");
88
89     println!("You guessed: {}", guess);
90 }
91 ```
92
93 There’s a lot here! Let’s go over it, bit by bit.
94
95 ```rust,ignore
96 use std::io;
97 ```
98
99 We’ll need to take user input, and then print the result as output. As such, we
100 need the `io` library from the standard library. Rust only imports a few things
101 into every program, [the ‘prelude’][prelude]. If it’s not in the prelude,
102 you’ll have to `use` it directly.
103
104 [prelude]: ../std/prelude/index.html
105
106 ```rust,ignore
107 fn main() {
108 ```
109
110 As you’ve seen before, the `main()` function is the entry point into your
111 program. The `fn` syntax declares a new function, the `()`s indicate that
112 there are no arguments, and `{` starts the body of the function. Because
113 we didn’t include a return type, it’s assumed to be `()`, an empty
114 [tuple][tuples].
115
116 [tuples]: primitive-types.html#tuples
117
118 ```rust,ignore
119     println!("Guess the number!");
120
121     println!("Please input your guess.");
122 ```
123
124 We previously learned that `println!()` is a [macro][macros] that
125 prints a [string][strings] to the screen.
126
127 [macros]: macros.html
128 [strings]: strings.html
129
130 ```rust,ignore
131     let mut guess = String::new();
132 ```
133
134 Now we’re getting interesting! There’s a lot going on in this little line.
135 The first thing to notice is that this is a [let statement][let], which is
136 used to create ‘variable bindings’. They take this form:
137
138 ```rust,ignore
139 let foo = bar;
140 ```
141
142 [let]: variable-bindings.html
143
144 This will create a new binding named `foo`, and bind it to the value `bar`. In
145 many languages, this is called a ‘variable’, but Rust’s variable bindings have
146 a few tricks up their sleeves.
147
148 For example, they’re [immutable][immutable] by default. That’s why our example
149 uses `mut`: it makes a binding mutable, rather than immutable. `let` doesn’t
150 take a name on the left hand side, it actually accepts a
151 ‘[pattern][patterns]’. We’ll use patterns more later. It’s easy enough
152 to use for now:
153
154 ```rust
155 let foo = 5; // immutable.
156 let mut bar = 5; // mutable
157 ```
158
159 [immutable]: mutability.html
160 [patterns]: patterns.html
161
162 Oh, and `//` will start a comment, until the end of the line. Rust ignores
163 everything in [comments][comments].
164
165 [comments]: comments.html
166
167 So now we know that `let mut guess` will introduce a mutable binding named
168 `guess`, but we have to look at the other side of the `=` for what it’s
169 bound to: `String::new()`.
170
171 `String` is a string type, provided by the standard library. A
172 [`String`][string] is a growable, UTF-8 encoded bit of text.
173
174 [string]: ../std/string/struct.String.html
175
176 The `::new()` syntax uses `::` because this is an ‘associated function’ of
177 a particular type. That is to say, it’s associated with `String` itself,
178 rather than a particular instance of a `String`. Some languages call this a
179 ‘static method’.
180
181 This function is named `new()`, because it creates a new, empty `String`.
182 You’ll find a `new()` function on many types, as it’s a common name for making
183 a new value of some kind.
184
185 Let’s move forward:
186
187 ```rust,ignore
188     io::stdin().read_line(&mut guess)
189         .ok()
190         .expect("Failed to read line");
191 ```
192
193 That’s a lot more! Let’s go bit-by-bit. The first line has two parts. Here’s
194 the first:
195
196 ```rust,ignore
197 io::stdin()
198 ```
199
200 Remember how we `use`d `std::io` on the first line of the program? We’re now
201 calling an associated function on it. If we didn’t `use std::io`, we could
202 have written this line as `std::io::stdin()`.
203
204 This particular function returns a handle to the standard input for your
205 terminal. More specifically, a [std::io::Stdin][iostdin].
206
207 [iostdin]: ../std/io/struct.Stdin.html
208
209 The next part will use this handle to get input from the user:
210
211 ```rust,ignore
212 .read_line(&mut guess)
213 ```
214
215 Here, we call the [`read_line()`][read_line] method on our handle.
216 [Methods][method] are like associated functions, but are only available on a
217 particular instance of a type, rather than the type itself. We’re also passing
218 one argument to `read_line()`: `&mut guess`.
219
220 [read_line]: ../std/io/struct.Stdin.html#method.read_line
221 [method]: method-syntax.html
222
223 Remember how we bound `guess` above? We said it was mutable. However,
224 `read_line` doesn’t take a `String` as an argument: it takes a `&mut String`.
225 Rust has a feature called ‘[references][references]’, which allows you to have
226 multiple references to one piece of data, which can reduce copying. References
227 are a complex feature, as one of Rust’s major selling points is how safe and
228 easy it is to use references. We don’t need to know a lot of those details to
229 finish our program right now, though. For now, all we need to know is that
230 like `let` bindings, references are immutable by default. Hence, we need to
231 write `&mut guess`, rather than `&guess`.
232
233 Why does `read_line()` take a mutable reference to a string? Its job is
234 to take what the user types into standard input, and place that into a
235 string. So it takes that string as an argument, and in order to add
236 the input, it needs to be mutable.
237
238 [references]: references-and-borrowing.html
239
240 But we’re not quite done with this line of code, though. While it’s
241 a single line of text, it’s only the first part of the single logical line of
242 code:
243
244 ```rust,ignore
245         .ok()
246         .expect("Failed to read line");
247 ```
248
249 When you call a method with the `.foo()` syntax, you may introduce a newline
250 and other whitespace. This helps you split up long lines. We _could_ have
251 done:
252
253 ```rust,ignore
254     io::stdin().read_line(&mut guess).ok().expect("failed to read line");
255 ```
256
257 But that gets hard to read. So we’ve split it up, three lines for three
258 method calls. We already talked about `read_line()`, but what about `ok()`
259 and `expect()`? Well, we already mentioned that `read_line()` puts what
260 the user types into the `&mut String` we pass it. But it also returns
261 a value: in this case, an [`io::Result`][ioresult]. Rust has a number of
262 types named `Result` in its standard library: a generic [`Result`][result],
263 and then specific versions for sub-libraries, like `io::Result`.
264
265 [ioresult]: ../std/io/type.Result.html
266 [result]: ../std/result/enum.Result.html
267
268 The purpose of these `Result` types is to encode error handling information.
269 Values of the `Result` type, like any type, have methods defined on them. In
270 this case, `io::Result` has an `ok()` method, which says ‘we want to assume
271 this value is a successful one. If not, just throw away the error
272 information’. Why throw it away? Well, for a basic program, we just want to
273 print a generic error, as basically any issue means we can’t continue. The
274 [`ok()` method][ok] returns a value which has another method defined on it:
275 `expect()`. The [`expect()` method][expect] takes a value it’s called on, and
276 if it isn’t a successful one, [`panic!`][panic]s with a message you
277 passed it. A `panic!` like this will cause our program to crash, displaying
278 the message.
279
280 [ok]: ../std/result/enum.Result.html#method.ok
281 [expect]: ../std/option/enum.Option.html#method.expect
282 [panic]: error-handling.html
283
284 If we leave off calling these two methods, our program will compile, but
285 we’ll get a warning:
286
287 ```bash
288 $ cargo build
289    Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
290 src/main.rs:10:5: 10:39 warning: unused result which must be used,
291 #[warn(unused_must_use)] on by default
292 src/main.rs:10     io::stdin().read_line(&mut guess);
293                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
294 ```
295
296 Rust warns us that we haven’t used the `Result` value. This warning comes from
297 a special annotation that `io::Result` has. Rust is trying to tell you that
298 you haven’t handled a possible error. The right way to suppress the error is
299 to actually write error handling. Luckily, if we just want to crash if there’s
300 a problem, we can use these two little methods. If we can recover from the
301 error somehow, we’d do something else, but we’ll save that for a future
302 project.
303
304 There’s just one line of this first example left:
305
306 ```rust,ignore
307     println!("You guessed: {}", guess);
308 }
309 ```
310
311 This prints out the string we saved our input in. The `{}`s are a placeholder,
312 and so we pass it `guess` as an argument. If we had multiple `{}`s, we would
313 pass multiple arguments:
314
315 ```rust
316 let x = 5;
317 let y = 10;
318
319 println!("x and y: {} and {}", x, y);
320 ```
321
322 Easy.
323
324 Anyway, that’s the tour. We can run what we have with `cargo run`:
325
326 ```bash
327 $ cargo run
328    Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
329      Running `target/debug/guessing_game`
330 Guess the number!
331 Please input your guess.
332 6
333 You guessed: 6
334 ```
335
336 All right! Our first part is done: we can get input from the keyboard,
337 and then print it back out.
338
339 # Generating a secret number
340
341 Next, we need to generate a secret number. Rust does not yet include random
342 number functionality in its standard library. The Rust team does, however,
343 provide a [`rand` crate][randcrate]. A ‘crate’ is a package of Rust code.
344 We’ve been building a ‘binary crate’, which is an executable. `rand` is a
345 ‘library crate’, which contains code that’s intended to be used with other
346 programs.
347
348 [randcrate]: https://crates.io/crates/rand
349
350 Using external crates is where Cargo really shines. Before we can write
351 the code using `rand`, we need to modify our `Cargo.toml`. Open it up, and
352 add these few lines at the bottom:
353
354 ```toml
355 [dependencies]
356
357 rand="0.3.0"
358 ```
359
360 The `[dependencies]` section of `Cargo.toml` is like the `[package]` section:
361 everything that follows it is part of it, until the next section starts.
362 Cargo uses the dependencies section to know what dependencies on external
363 crates you have, and what versions you require. In this case, we’ve used version `0.3.0`.
364 Cargo understands [Semantic Versioning][semver], which is a standard for writing version
365 numbers. If we wanted to use the latest version we could use `*` or we could use a range 
366 of versions. [Cargo’s documentation][cargodoc] contains more details.
367
368 [semver]: http://semver.org
369 [cargodoc]: http://doc.crates.io/crates-io.html
370
371 Now, without changing any of our code, let’s build our project:
372
373 ```bash
374 $ cargo build
375     Updating registry `https://github.com/rust-lang/crates.io-index`
376  Downloading rand v0.3.8
377  Downloading libc v0.1.6
378    Compiling libc v0.1.6
379    Compiling rand v0.3.8
380    Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
381 ```
382
383 (You may see different versions, of course.)
384
385 Lots of new output! Now that we have an external dependency, Cargo fetches the
386 latest versions of everything from the registry, which is a copy of data from
387 [Crates.io][cratesio]. Crates.io is where people in the Rust ecosystem
388 post their open source Rust projects for others to use.
389
390 [cratesio]: https://crates.io
391
392 After updating the registry, Cargo checks our `[dependencies]` and downloads
393 any we don’t have yet. In this case, while we only said we wanted to depend on
394 `rand`, we’ve also grabbed a copy of `libc`. This is because `rand` depends on
395 `libc` to work. After downloading them, it compiles them, and then compiles
396 our project.
397
398 If we run `cargo build` again, we’ll get different output:
399
400 ```bash
401 $ cargo build
402 ```
403
404 That’s right, no output! Cargo knows that our project has been built, and that
405 all of its dependencies are built, and so there’s no reason to do all that
406 stuff. With nothing to do, it simply exits. If we open up `src/main.rs` again,
407 make a trivial change, and then save it again, we’ll just see one line:
408
409 ```bash
410 $ cargo build
411    Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
412 ```
413
414 So, we told Cargo we wanted any `0.3.x` version of `rand`, and so it fetched the latest
415 version at the time this was written, `v0.3.8`. But what happens when next
416 week, version `v0.3.9` comes out, with an important bugfix? While getting
417 bugfixes is important, what if `0.3.9` contains a regression that breaks our
418 code?
419
420 The answer to this problem is the `Cargo.lock` file you’ll now find in your
421 project directory. When you build your project for the first time, Cargo
422 figures out all of the versions that fit your criteria, and then writes them
423 to the `Cargo.lock` file. When you build your project in the future, Cargo
424 will see that the `Cargo.lock` file exists, and then use that specific version
425 rather than do all the work of figuring out versions again. This lets you
426 have a repeatable build automatically. In other words, we’ll stay at `0.3.8`
427 until we explicitly upgrade, and so will anyone who we share our code with,
428 thanks to the lock file.
429
430 What about when we _do_ want to use `v0.3.9`? Cargo has another command,
431 `update`, which says ‘ignore the lock, figure out all the latest versions that
432 fit what we’ve specified. If that works, write those versions out to the lock
433 file’. But, by default, Cargo will only look for versions larger than `0.3.0`
434 and smaller than `0.4.0`. If we want to move to `0.4.x`, we’d have to update
435 the `Cargo.toml` directly. When we do, the next time we `cargo build`, Cargo
436 will update the index and re-evaluate our `rand` requirements.
437
438 There’s a lot more to say about [Cargo][doccargo] and [its
439 ecosystem][doccratesio], but for now, that’s all we need to know. Cargo makes
440 it really easy to re-use libraries, and so Rustaceans tend to write smaller
441 projects which are assembled out of a number of sub-packages.
442
443 [doccargo]: http://doc.crates.io
444 [doccratesio]: http://doc.crates.io/crates-io.html
445
446 Let’s get on to actually _using_ `rand`. Here’s our next step:
447
448 ```rust,ignore
449 extern crate rand;
450
451 use std::io;
452 use rand::Rng;
453
454 fn main() {
455     println!("Guess the number!");
456
457     let secret_number = rand::thread_rng().gen_range(1, 101);
458
459     println!("The secret number is: {}", secret_number);
460
461     println!("Please input your guess.");
462
463     let mut guess = String::new();
464
465     io::stdin().read_line(&mut guess)
466         .ok()
467         .expect("failed to read line");
468
469     println!("You guessed: {}", guess);
470 }
471 ```
472
473 The first thing we’ve done is change the first line. It now says
474 `extern crate rand`. Because we declared `rand` in our `[dependencies]`, we
475 can use `extern crate` to let Rust know we’ll be making use of it. This also
476 does the equivalent of a `use rand;` as well, so we can make use of anything
477 in the `rand` crate by prefixing it with `rand::`.
478
479 Next, we added another `use` line: `use rand::Rng`. We’re going to use a
480 method in a moment, and it requires that `Rng` be in scope to work. The basic
481 idea is this: methods are defined on something called ‘traits’, and for the
482 method to work, it needs the trait to be in scope. For more about the
483 details, read the [traits][traits] section.
484
485 [traits]: traits.html
486
487 There are two other lines we added, in the middle:
488
489 ```rust,ignore
490     let secret_number = rand::thread_rng().gen_range(1, 101);
491
492     println!("The secret number is: {}", secret_number);
493 ```
494
495 We use the `rand::thread_rng()` function to get a copy of the random number
496 generator, which is local to the particular [thread][concurrency] of execution
497 we’re in. Because we `use rand::Rng`’d above, it has a `gen_range()` method
498 available. This method takes two arguments, and generates a number between
499 them. It’s inclusive on the lower bound, but exclusive on the upper bound,
500 so we need `1` and `101` to get a number between one and a hundred.
501
502 [concurrency]: concurrency.html
503
504 The second line just prints out the secret number. This is useful while
505 we’re developing our program, so we can easily test it out. But we’ll be
506 deleting it for the final version. It’s not much of a game if it prints out
507 the answer when you start it up!
508
509 Try running our new program a few times:
510
511 ```bash
512 $ cargo run
513    Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
514      Running `target/debug/guessing_game`
515 Guess the number!
516 The secret number is: 7
517 Please input your guess.
518 4
519 You guessed: 4
520 $ cargo run
521      Running `target/debug/guessing_game`
522 Guess the number!
523 The secret number is: 83
524 Please input your guess.
525 5
526 You guessed: 5
527 ```
528
529 Great! Next up: let’s compare our guess to the secret guess.
530
531 # Comparing guesses
532
533 Now that we’ve got user input, let’s compare our guess to the random guess.
534 Here’s our next step, though it doesn’t quite work yet:
535
536 ```rust,ignore
537 extern crate rand;
538
539 use std::io;
540 use std::cmp::Ordering;
541 use rand::Rng;
542
543 fn main() {
544     println!("Guess the number!");
545
546     let secret_number = rand::thread_rng().gen_range(1, 101);
547
548     println!("The secret number is: {}", secret_number);
549
550     println!("Please input your guess.");
551
552     let mut guess = String::new();
553
554     io::stdin().read_line(&mut guess)
555         .ok()
556         .expect("failed to read line");
557
558     println!("You guessed: {}", guess);
559
560     match guess.cmp(&secret_number) {
561         Ordering::Less    => println!("Too small!"),
562         Ordering::Greater => println!("Too big!"),
563         Ordering::Equal   => println!("You win!"),
564     }
565 }
566 ```
567
568 A few new bits here. The first is another `use`. We bring a type called
569 `std::cmp::Ordering` into scope. Then, five new lines at the bottom that use
570 it:
571
572 ```rust,ignore
573 match guess.cmp(&secret_number) {
574     Ordering::Less    => println!("Too small!"),
575     Ordering::Greater => println!("Too big!"),
576     Ordering::Equal   => println!("You win!"),
577 }
578 ```
579
580 The `cmp()` method can be called on anything that can be compared, and it
581 takes a reference to the thing you want to compare it to. It returns the
582 `Ordering` type we `use`d earlier. We use a [`match`][match] statement to
583 determine exactly what kind of `Ordering` it is. `Ordering` is an
584 [`enum`][enum], short for ‘enumeration’, which looks like this:
585
586 ```rust
587 enum Foo {
588     Bar,
589     Baz,
590 }
591 ```
592
593 [match]: match.html
594 [enum]: enums.html
595
596 With this definition, anything of type `Foo` can be either a
597 `Foo::Bar` or a `Foo::Baz`. We use the `::` to indicate the
598 namespace for a particular `enum` variant.
599
600 The [`Ordering`][ordering] enum has three possible variants: `Less`, `Equal`,
601 and `Greater`. The `match` statement takes a value of a type, and lets you
602 create an ‘arm’ for each possible value. Since we have three types of
603 `Ordering`, we have three arms:
604
605 ```rust,ignore
606 match guess.cmp(&secret_number) {
607     Ordering::Less    => println!("Too small!"),
608     Ordering::Greater => println!("Too big!"),
609     Ordering::Equal   => println!("You win!"),
610 }
611 ```
612
613 [ordering]: ../std/cmp/enum.Ordering.html
614
615 If it’s `Less`, we print `Too small!`, if it’s `Greater`, `Too big!`, and if
616 `Equal`, `You win!`. `match` is really useful, and is used often in Rust.
617
618 I did mention that this won’t quite work yet, though. Let’s try it:
619
620 ```bash
621 $ cargo build
622    Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
623 src/main.rs:28:21: 28:35 error: mismatched types:
624  expected `&collections::string::String`,
625     found `&_`
626 (expected struct `collections::string::String`,
627     found integral variable) [E0308]
628 src/main.rs:28     match guess.cmp(&secret_number) {
629                                    ^~~~~~~~~~~~~~
630 error: aborting due to previous error
631 Could not compile `guessing_game`.
632 ```
633
634 Whew! This is a big error. The core of it is that we have ‘mismatched types’.
635 Rust has a strong, static type system. However, it also has type inference.
636 When we wrote `let guess = String::new()`, Rust was able to infer that `guess`
637 should be a `String`, and so it doesn’t make us write out the type. And with
638 our `secret_number`, there are a number of types which can have a value
639 between one and a hundred: `i32`, a thirty-two-bit number, or `u32`, an
640 unsigned thirty-two-bit number, or `i64`, a sixty-four-bit number. Or others.
641 So far, that hasn’t mattered, and so Rust defaults to an `i32`. However, here,
642 Rust doesn’t know how to compare the `guess` and the `secret_number`. They
643 need to be the same type. Ultimately, we want to convert the `String` we
644 read as input into a real number type, for comparison. We can do that
645 with three more lines. Here’s our new program:
646
647 ```rust,ignore
648 extern crate rand;
649
650 use std::io;
651 use std::cmp::Ordering;
652 use rand::Rng;
653
654 fn main() {
655     println!("Guess the number!");
656
657     let secret_number = rand::thread_rng().gen_range(1, 101);
658
659     println!("The secret number is: {}", secret_number);
660
661     println!("Please input your guess.");
662
663     let mut guess = String::new();
664
665     io::stdin().read_line(&mut guess)
666         .ok()
667         .expect("failed to read line");
668
669     let guess: u32 = guess.trim().parse()
670         .ok()
671         .expect("Please type a number!");
672
673     println!("You guessed: {}", guess);
674
675     match guess.cmp(&secret_number) {
676         Ordering::Less    => println!("Too small!"),
677         Ordering::Greater => println!("Too big!"),
678         Ordering::Equal   => println!("You win!"),
679     }
680 }
681 ```
682
683 The new three lines:
684
685 ```rust,ignore
686     let guess: u32 = guess.trim().parse()
687         .ok()
688         .expect("Please type a number!");
689 ```
690
691 Wait a minute, I thought we already had a `guess`? We do, but Rust allows us
692 to ‘shadow’ the previous `guess` with a new one. This is often used in this
693 exact situation, where `guess` starts as a `String`, but we want to convert it
694 to an `u32`. Shadowing lets us re-use the `guess` name, rather than forcing us
695 to come up with two unique names like `guess_str` and `guess`, or something
696 else.
697
698 We bind `guess` to an expression that looks like something we wrote earlier:
699
700 ```rust,ignore
701 guess.trim().parse()
702 ```
703
704 Followed by an `ok().expect()` invocation. Here, `guess` refers to the old
705 `guess`, the one that was a `String` with our input in it. The `trim()`
706 method on `String`s will eliminate any white space at the beginning and end of
707 our string. This is important, as we had to press the ‘return’ key to satisfy
708 `read_line()`. This means that if we type `5` and hit return, `guess` looks
709 like this: `5\n`. The `\n` represents ‘newline’, the enter key. `trim()` gets
710 rid of this, leaving our string with just the `5`. The [`parse()` method on
711 strings][parse] parses a string into some kind of number. Since it can parse a
712 variety of numbers, we need to give Rust a hint as to the exact type of number
713 we want. Hence, `let guess: u32`. The colon (`:`) after `guess` tells Rust
714 we’re going to annotate its type. `u32` is an unsigned, thirty-two bit
715 integer. Rust has [a number of built-in number types][number], but we’ve
716 chosen `u32`. It’s a good default choice for a small positive number.
717
718 [parse]: ../std/primitive.str.html#method.parse
719 [number]: primitive-types.html#numeric-types
720
721 Just like `read_line()`, our call to `parse()` could cause an error. What if
722 our string contained `A👍%`? There’d be no way to convert that to a number. As
723 such, we’ll do the same thing we did with `read_line()`: use the `ok()` and
724 `expect()` methods to crash if there’s an error.
725
726 Let’s try our program out!
727
728 ```bash
729 $ cargo run
730    Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
731      Running `target/guessing_game`
732 Guess the number!
733 The secret number is: 58
734 Please input your guess.
735   76
736 You guessed: 76
737 Too big!
738 ```
739
740 Nice! You can see I even added spaces before my guess, and it still figured
741 out that I guessed 76. Run the program a few times, and verify that guessing
742 the number works, as well as guessing a number too small.
743
744 Now we’ve got most of the game working, but we can only make one guess. Let’s
745 change that by adding loops!
746
747 # Looping
748
749 The `loop` keyword gives us an infinite loop. Let’s add that in:
750
751 ```rust,ignore
752 extern crate rand;
753
754 use std::io;
755 use std::cmp::Ordering;
756 use rand::Rng;
757
758 fn main() {
759     println!("Guess the number!");
760
761     let secret_number = rand::thread_rng().gen_range(1, 101);
762
763     println!("The secret number is: {}", secret_number);
764
765     loop {
766         println!("Please input your guess.");
767
768         let mut guess = String::new();
769
770         io::stdin().read_line(&mut guess)
771             .ok()
772             .expect("failed to read line");
773
774         let guess: u32 = guess.trim().parse()
775             .ok()
776             .expect("Please type a number!");
777
778         println!("You guessed: {}", guess);
779
780         match guess.cmp(&secret_number) {
781             Ordering::Less    => println!("Too small!"),
782             Ordering::Greater => println!("Too big!"),
783             Ordering::Equal   => println!("You win!"),
784         }
785     }
786 }
787 ```
788
789 And try it out. But wait, didn’t we just add an infinite loop? Yup. Remember
790 our discussion about `parse()`? If we give a non-number answer, we’ll `return`
791 and quit. Observe:
792
793 ```bash
794 $ cargo run
795    Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
796      Running `target/guessing_game`
797 Guess the number!
798 The secret number is: 59
799 Please input your guess.
800 45
801 You guessed: 45
802 Too small!
803 Please input your guess.
804 60
805 You guessed: 60
806 Too big!
807 Please input your guess.
808 59
809 You guessed: 59
810 You win!
811 Please input your guess.
812 quit
813 thread '<main>' panicked at 'Please type a number!'
814 ```
815
816 Ha! `quit` actually quits. As does any other non-number input. Well, this is
817 suboptimal to say the least. First, let’s actually quit when you win the game:
818
819 ```rust,ignore
820 extern crate rand;
821
822 use std::io;
823 use std::cmp::Ordering;
824 use rand::Rng;
825
826 fn main() {
827     println!("Guess the number!");
828
829     let secret_number = rand::thread_rng().gen_range(1, 101);
830
831     println!("The secret number is: {}", secret_number);
832
833     loop {
834         println!("Please input your guess.");
835
836         let mut guess = String::new();
837
838         io::stdin().read_line(&mut guess)
839             .ok()
840             .expect("failed to read line");
841
842         let guess: u32 = guess.trim().parse()
843             .ok()
844             .expect("Please type a number!");
845
846         println!("You guessed: {}", guess);
847
848         match guess.cmp(&secret_number) {
849             Ordering::Less    => println!("Too small!"),
850             Ordering::Greater => println!("Too big!"),
851             Ordering::Equal   => {
852                 println!("You win!");
853                 break;
854             }
855         }
856     }
857 }
858 ```
859
860 By adding the `break` line after the `You win!`, we’ll exit the loop when we
861 win. Exiting the loop also means exiting the program, since it’s the last
862 thing in `main()`. We have just one more tweak to make: when someone inputs a
863 non-number, we don’t want to quit, we just want to ignore it. We can do that
864 like this:
865
866 ```rust,ignore
867 extern crate rand;
868
869 use std::io;
870 use std::cmp::Ordering;
871 use rand::Rng;
872
873 fn main() {
874     println!("Guess the number!");
875
876     let secret_number = rand::thread_rng().gen_range(1, 101);
877
878     println!("The secret number is: {}", secret_number);
879
880     loop {
881         println!("Please input your guess.");
882
883         let mut guess = String::new();
884
885         io::stdin().read_line(&mut guess)
886             .ok()
887             .expect("failed to read line");
888
889         let guess: u32 = match guess.trim().parse() {
890             Ok(num) => num,
891             Err(_) => continue,
892         };
893
894         println!("You guessed: {}", guess);
895
896         match guess.cmp(&secret_number) {
897             Ordering::Less    => println!("Too small!"),
898             Ordering::Greater => println!("Too big!"),
899             Ordering::Equal   => {
900                 println!("You win!");
901                 break;
902             }
903         }
904     }
905 }
906 ```
907
908 These are the lines that changed:
909
910 ```rust,ignore
911 let guess: u32 = match guess.trim().parse() {
912     Ok(num) => num,
913     Err(_) => continue,
914 };
915 ```
916
917 This is how you generally move from ‘crash on error’ to ‘actually handle the
918 error’, by switching from `ok().expect()` to a `match` statement. The `Result`
919 returned by `parse()` is an enum just like `Ordering`, but in this case, each
920 variant has some data associated with it: `Ok` is a success, and `Err` is a
921 failure. Each contains more information: the successful parsed integer, or an
922 error type. In this case, we `match` on `Ok(num)`, which sets the inner value
923 of the `Ok` to the name `num`, and then we just return it on the right-hand
924 side. In the `Err` case, we don’t care what kind of error it is, so we just
925 use `_` instead of a name. This ignores the error, and `continue` causes us
926 to go to the next iteration of the `loop`.
927
928 Now we should be good! Let’s try:
929
930 ```bash
931 $ cargo run
932    Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
933      Running `target/guessing_game`
934 Guess the number!
935 The secret number is: 61
936 Please input your guess.
937 10
938 You guessed: 10
939 Too small!
940 Please input your guess.
941 99
942 You guessed: 99
943 Too big!
944 Please input your guess.
945 foo
946 Please input your guess.
947 61
948 You guessed: 61
949 You win!
950 ```
951
952 Awesome! With one tiny last tweak, we have finished the guessing game. Can you
953 think of what it is? That’s right, we don’t want to print out the secret
954 number. It was good for testing, but it kind of ruins the game. Here’s our
955 final source:
956
957 ```rust,ignore
958 extern crate rand;
959
960 use std::io;
961 use std::cmp::Ordering;
962 use rand::Rng;
963
964 fn main() {
965     println!("Guess the number!");
966
967     let secret_number = rand::thread_rng().gen_range(1, 101);
968
969     loop {
970         println!("Please input your guess.");
971
972         let mut guess = String::new();
973
974         io::stdin().read_line(&mut guess)
975             .ok()
976             .expect("failed to read line");
977
978         let guess: u32 = match guess.trim().parse() {
979             Ok(num) => num,
980             Err(_) => continue,
981         };
982
983         println!("You guessed: {}", guess);
984
985         match guess.cmp(&secret_number) {
986             Ordering::Less    => println!("Too small!"),
987             Ordering::Greater => println!("Too big!"),
988             Ordering::Equal   => {
989                 println!("You win!");
990                 break;
991             }
992         }
993     }
994 }
995 ```
996
997 # Complete!
998
999 At this point, you have successfully built the Guessing Game! Congratulations!
1000
1001 This first project showed you a lot: `let`, `match`, methods, associated
1002 functions, using external crates, and more. Our next project will show off
1003 even more.