]> git.lizzy.rs Git - rust.git/blob - src/doc/guide.md
auto merge of #15422 : steveklabnik/rust/guide_compound_data_types, r=brson
[rust.git] / src / doc / guide.md
1 % The Rust Guide
2
3 <div style="border: 2px solid red; padding:5px;">
4 This guide is a work in progress. Until it is ready, we highly recommend that
5 you read the <a href="tutorial.html">Tutorial</a> instead. This work-in-progress Guide is being
6 displayed here in line with Rust's open development policy. Please open any
7 issues you find as usual.
8 </div>
9
10 ## Welcome!
11
12 Hey there! Welcome to the Rust guide. This is the place to be if you'd like to
13 learn how to program in Rust. Rust is a systems programming language with a
14 focus on "high-level, bare-metal programming": the lowest level control a
15 programming language can give you, but with zero-cost, higher level
16 abstractions, because people aren't computers. We really think Rust is
17 something special, and we hope you do too.
18
19 To show you how to get going with Rust, we're going to write the traditional
20 "Hello, World!" program. Next, we'll introduce you to a tool that's useful for
21 writing real-world Rust programs and libraries: "Cargo." Then, we'll show off
22 Rust's features by writing a little program together.
23
24 Sound good? Let's go!
25
26 ## Installing Rust
27
28 The first step to using Rust is to install it! There are a number of ways to
29 install Rust, but the easiest is to use the the `rustup` script. If you're on
30 Linux or a Mac, all you need to do is this (note that you don't need to type
31 in the `$`s, they just indicate the start of each command):
32
33 ```{ignore}
34 $ curl -s http://www.rust-lang.org/rustup.sh | sudo sh
35 ```
36
37 (If you're concerned about `curl | sudo sh`, please keep reading. Disclaimer
38 below.)
39
40 If you're on Windows, please [download this .exe and run
41 it](http://static.rust-lang.org/dist/rust-nightly-install.exe).
42
43 If you decide you don't want Rust anymore, we'll be a bit sad, but that's okay.
44 Not every programming language is great for everyone. Just pass an argument to
45 the script:
46
47 ```{ignore}
48 $ curl -s http://www.rust-lang.org/rustup.sh | sudo sh -s -- --uninstall
49 ```
50
51 If you used the Windows installer, just re-run the `.exe` and it will give you
52 an uninstall option.
53
54 You can re-run this script any time you want to update Rust. Which, at this
55 point, is often. Rust is still pre-1.0, and so people assume that you're using
56 a very recent Rust.
57
58 This brings me to one other point: some people, and somewhat rightfully so, get
59 very upset when we tell you to `curl | sudo sh`. And they should be! Basically,
60 when you do this, you are trusting that the good people who maintain Rust
61 aren't going to hack your computer and do bad things. That's a good instinct!
62 If you're one of those people, please check out the documentation on [building
63 Rust from Source](https://github.com/rust-lang/rust#building-from-source), or
64 [the official binary downloads](http://www.rust-lang.org/install.html). And we
65 promise that this method will not be the way to install Rust forever: it's just
66 the easiest way to keep people updated while Rust is in its alpha state.
67
68 Oh, we should also mention the officially supported platforms:
69
70 * Windows (7, 8, Server 2008 R2), x86 only
71 * Linux (2.6.18 or later, various distributions), x86 and x86-64
72 * OSX 10.7 (Lion) or greater, x86 and x86-64
73
74 We extensively test Rust on these platforms, and a few others, too, like
75 Android. But these are the ones most likely to work, as they have the most
76 testing.
77
78 Finally, a comment about Windows. Rust considers Windows to be a first-class
79 platform upon release, but if we're honest, the Windows experience isn't as
80 integrated as the Linux/OS X experience is. We're working on it! If anything
81 does not work, it is a bug. Please let us know if that happens. Each and every
82 commit is tested against Windows just like any other platform.
83
84 If you've got Rust installed, you can open up a shell, and type this:
85
86 ```{ignore}
87 $ rustc --version
88 ```
89
90 You should see some output that looks something like this:
91
92 ```{ignore}
93 rustc 0.11.0-pre (443a1cd 2014-06-08 14:56:52 -0700)
94 ```
95
96 If you did, Rust has been installed successfully! Congrats!
97
98 If not, there are a number of places where you can get help. The easiest is
99 [the #rust IRC channel on irc.mozilla.org](irc://irc.mozilla.org/#rust), which
100 you can access through
101 [Mibbit](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust). Click
102 that link, and you'll be chatting with other Rustaceans (a silly nickname we
103 call ourselves), and we can help you out. Other great resources include [our
104 mailing list](https://mail.mozilla.org/listinfo/rust-dev), [the /r/rust
105 subreddit](http://www.reddit.com/r/rust), and [Stack
106 Overflow](http://stackoverflow.com/questions/tagged/rust).
107
108 ## Hello, world!
109
110 Now that you have Rust installed, let's write your first Rust program. It's
111 traditional to make your first program in any new language one that prints the
112 text "Hello, world!" to the screen. The nice thing about starting with such a
113 simple program is that you can verify that your compiler isn't just installed,
114 but also working properly. And printing information to the screen is a pretty
115 common thing to do.
116
117 The first thing that we need to do is make a file to put our code in. I like
118 to make a projects directory in my home directory, and keep all my projects
119 there. Rust does not care where your code lives.
120
121 This actually leads to one other concern we should address: this tutorial will
122 assume that you have basic familiarity with the command-line. Rust does not
123 require that you know a whole ton about the command line, but until the
124 language is in a more finished state, IDE support is spotty. Rust makes no
125 specific demands on your editing tooling, or where your code lives.
126
127 With that said, let's make a directory in our projects directory.
128
129 ```{bash}
130 $ mkdir ~/projects
131 $ cd ~/projects
132 $ mkdir hello_world
133 $ cd hello_world
134 ```
135
136 If you're on Windows and not using PowerShell, the `~` may not work. Consult
137 the documentation for your shell for more details.
138
139 Let's make a new source file next. I'm going to use the syntax `editor
140 filename` to represent editing a file in these examples, but you should use
141 whatever method you want. We'll call our file `hello_world.rs`:
142
143 ```{bash}
144 $ editor hello_world.rs
145 ```
146
147 Rust files always end in a `.rs` extension. If you're using more than one word
148 in your file name, use an underscore. `hello_world.rs` versus `goodbye.rs`.
149
150 Now that you've got your file open, type this in:
151
152 ```
153 fn main() {
154     println!("Hello, world");
155 }
156 ```
157
158 Save the file, and then type this into your terminal window:
159
160 ```{bash}
161 $ rustc hello_world.rs
162 $ ./hello_world # or hello_world.exe on Windows
163 Hello, world
164 ```
165
166 Success! Let's go over what just happened in detail.
167
168 ```
169 fn main() {
170
171 }
172 ```
173
174 These two lines define a **function** in Rust. The `main` function is special:
175 it's the beginning of every Rust program. The first line says "I'm declaring a
176 function named `main`, which takes no arguments and returns nothing." If there
177 were arguments, they would go inside the parentheses (`(` and `)`), and because
178 we aren't returning anything from this function, we've dropped that notation
179 entirely.  We'll get to it later.
180
181 You'll also note that the function is wrapped in curly braces (`{` and `}`).
182 Rust requires these around all function bodies. It is also considered good
183 style to put the opening curly brace on the same line as the function
184 declaration, with one space in between.
185
186 Next up is this line:
187
188 ```
189     println!("Hello, world");
190 ```
191
192 This line does all of the work in our little program. There are a number of
193 details that are important here. The first is that it's indented with four
194 spaces, not tabs. Please configure your editor of choice to insert four spaces
195 with the tab key. We provide some sample configurations for various editors
196 [here](https://github.com/rust-lang/rust/tree/master/src/etc).
197
198 The second point is the `println!()` part. This is calling a Rust **macro**,
199 which is how metaprogramming is done in Rust. If it were a function instead, it
200 would look like this: `println()`. For our purposes, we don't need to worry
201 about this difference. Just know that sometimes, you'll see a `!`, and that
202 means that you're calling a macro instead of a normal function. One last thing
203 to mention: Rust's macros are significantly different than C macros, if you've
204 used those. Don't be scared of using macros. We'll get to the details
205 eventually, you'll just have to trust us for now.
206
207 Next, `"Hello, world"` is a **string**. Strings are a surprisingly complicated
208 topic in a systems programming language, and this is a **statically allocated**
209 string. We will talk more about different kinds of allocation later. We pass
210 this string as an argument to `println!`, which prints the string to the
211 screen. Easy enough!
212
213 Finally, the line ends with a semicolon (`;`). Rust is an **expression
214 oriented** language, which means that most things are expressions. The `;` is
215 used to indicate that this expression is over, and the next one is ready to
216 begin. Most lines of Rust code end with a `;`. We will cover this in-depth
217 later in the tutorial.
218
219 Finally, actually **compiling** and **running** our program. We can compile
220 with our compiler, `rustc`, by passing it the name of our source file:
221
222 ```{bash}
223 $ rustc hello_world.rs
224 ```
225
226 This is similar to `gcc` or `clang`, if you come from a C or C++ background. Rust
227 will output a binary executable. You can see it with `ls`:
228
229 ```{bash}
230 $ ls
231 hello_world  hello_world.rs
232 ```
233
234 Or on Windows:
235
236 ```{bash}
237 $ dir
238 hello_world.exe  hello_world.rs
239 ```
240
241 There are now two files: our source code, with the `.rs` extension, and the
242 executable (`hello_world.exe` on Windows, `hello_world` everywhere else)
243
244 ```{bash}
245 $ ./hello_world  # or hello_world.exe on Windows
246 ```
247
248 This prints out our `Hello, world!` text to our terminal.
249
250 If you come from a dynamically typed language like Ruby, Python, or JavaScript,
251 you may not be used to these two steps being separate. Rust is an
252 **ahead-of-time compiled language**, which means that you can compile a
253 program, give it to someone else, and they don't need to have Rust installed.
254 If you give someone a `.rb` or `.py` or `.js` file, they need to have
255 Ruby/Python/JavaScript installed, but you just need one command to both compile
256 and run your program. Everything is a tradeoff in language design, and Rust has
257 made its choice.
258
259 Congratulations! You have officially written a Rust program. That makes you a
260 Rust programmer! Welcome.
261
262 Next, I'd like to introduce you to another tool, Cargo, which is used to write
263 real-world Rust programs. Just using `rustc` is nice for simple things, but as
264 your project grows, you'll want something to help you manage all of the options
265 that it has, and to make it easy to share your code with other people and
266 projects.
267
268 ## Hello, Cargo!
269
270 [Cargo](http://crates.io) is a tool that Rustaceans use to help manage their
271 Rust projects. Cargo is currently in an alpha state, just like Rust, and so it
272 is still a work in progress. However, it is already good enough to use for many
273 Rust projects, and so it is assumed that Rust projects will use Cargo from the
274 beginning.
275
276 Programmers love car analogies, so I've got a good one for you to think about
277 the relationship between `cargo` and `rustc`: `rustc` is like a car, and
278 `cargo` is like a robotic driver. You can drive your car yourself, of course,
279 but isn't it just easier to let a computer drive it for you?
280
281 Anyway, Cargo manages three things: building your code, downloading the
282 dependencies your code needs, and building the dependencies your code needs.
283 At first, your program doesn't have any dependencies, so we'll only be using
284 the first part of its functionality. Eventually, we'll add more. Since we
285 started off by using Cargo, it'll be easy to add later.
286
287 Let's convert Hello World to Cargo. The first thing we need to do to begin using Cargo
288 is to install Cargo. To do this, we need to build it from source. There are no binaries
289 yet.
290
291 First, let's go back to our projects directory. We don't want Cargo to
292 live in our project!
293
294 ```{bash}
295 $ cd ..
296 ```
297
298 Next, we need these commands:
299
300 ```{bash}
301 $ git clone --recursive https://github.com/rust-lang/cargo
302 $ cd cargo
303 $ make
304 $ make install # may need sudo or admin permissions
305 ```
306
307 The `--recursive` downloads Cargo's own dependencies. You can't use Cargo to
308 fetch dependencies until you have Cargo installed! Also, you will need to have
309 `git` installed. Much of the Rust world assumes `git` usage, so it's a good
310 thing to have around. Please check out [the git
311 documentation](http://git-scm.com/book/en/Getting-Started-Installing-Git) for
312 more on installing `git`.
313
314 We hope to give Cargo a binary installer, similar to Rust's own, so that
315 this will not be necessary in the future.
316
317 Let's see if that worked. Try this:
318
319 ```{bash}
320 $ cargo
321 Commands:
322   build          # compile the current project
323
324 Options (for all commands):
325
326 -v, [--verbose]
327 -h, [--help]
328 ```
329
330 If you see this output when you run `cargo`, congrats! Cargo is working. If
331 not, please [open an issue](https://github.com/rust-lang/cargo/issues/new) or
332 drop by the Rust IRC, and we can help you out.
333
334 Let's move back into our `hello_world` directory now:
335
336 ```{bash}
337 $ cd ..              # move back up into projects
338 $ cd hello_world     # move into hello_world
339 ```
340
341 To Cargo-ify our project, we need to do two things: Make a `Cargo.toml`
342 configuration file, and put our source file in the right place. Let's
343 do that part first:
344
345 ```{bash}
346 $ mkdir src
347 $ mv hello_world.rs src/hello_world.rs
348 ```
349
350 Cargo expects your source files to live inside a `src` directory. That leaves
351 the top level for other things, like READMEs, licence information, and anything
352 not related to your code. Cargo helps us keep our projects nice and tidy. A
353 place for everything, and everything in its place.
354
355 Next, our configuration file:
356
357 ```{bash}
358 $ editor Cargo.toml
359 ```
360
361 Make sure to get this name right: you need the capital `C`!
362
363 Put this inside:
364
365 ```{ignore}
366 [package]
367
368 name = "hello_world"
369 version = "0.1.0"
370 authors = [ "someone@example.com" ]
371
372 [[bin]]
373
374 name = "hello_world"
375 ```
376
377 This file is in the [TOML](https://github.com/toml-lang/toml) format. Let's let
378 it explain itself to you:
379
380 > TOML aims to be a minimal configuration file format that's easy to read due
381 > to obvious semantics. TOML is designed to map unambiguously to a hash table.
382 > TOML should be easy to parse into data structures in a wide variety of
383 > languages.
384
385 TOML is very similar to INI, but with some extra goodies.
386
387 Anyway, there are two **table**s in this file: `package` and `bin`. The first
388 tells Cargo metadata about your package. The second tells Cargo that we're
389 interested in building a binary, not a library (though we could do both!), as
390 well as what it is named.
391
392 Once you have this file in place, we should be ready to build! Try this:
393
394 ```{bash}
395 $ cargo build
396    Compiling hello_world v0.1.0 (file:/home/yourname/projects/hello_world)
397 $ ./target/hello_world
398 Hello, world!
399 ```
400
401 Bam! We build our project with `cargo build`, and run it with
402 `./target/hello_world`. This hasn't bought us a whole lot over our simple use
403 of `rustc`, but think about the future: when our project has more than one
404 file, we would need to call `rustc` twice, and pass it a bunch of options to
405 tell it to build everything together. With Cargo, as our project grows, we can
406 just `cargo build` and it'll work the right way.
407
408 That's it! We've successfully built `hello_world` with Cargo. Even though our
409 program is simple, it's using much of the real tooling that you'll use for the
410 rest of your Rust career.
411
412 Next, we'll learn more about Rust itself, by starting to write a more complicated
413 program. We hope you want to do more with Rust than just print "Hello, world!"
414
415 ## Guessing Game
416
417 Let's write a bigger program in Rust. We could just go through a laundry list
418 of Rust features, but that's boring. Instead, we'll learn more about how to
419 code in Rust by writing a few example projects.
420
421 For our first project, we'll implement a classic beginner programming problem:
422 the guessing game. Here's how it works: Our program will generate a random
423 integer between one and a hundred. It will then prompt us to enter a guess.
424 Upon entering our guess, it will tell us if we're too low or too high. Once we
425 guess correctly, it will congratulate us, and print the number of guesses we've
426 taken to the screen. Sound good? It sounds easy, but it'll end up showing off a
427 number of basic features of Rust.
428
429 ### Set up
430
431 Let's set up a new project. Go to your projects directory, and make a new
432 directory for the project, as well as a `src` directory for our code:
433
434 ```{bash}
435 $ cd ~/projects
436 $ mkdir guessing_game
437 $ cd guessing_game
438 $ mkdir src
439 ```
440
441 Great. Next, let's make a `Cargo.toml` file so Cargo knows how to build our
442 project:
443
444 ```{ignore}
445 [package]
446
447 name = "guessing_game"
448 version = "0.1.0"
449 authors = [ "someone@example.com" ]
450
451 [[bin]]
452
453 name = "guessing_game"
454 ```
455
456 Finally, we need our source file. Let's just make it hello world for now, so we
457 can check that our setup works. In `src/guessing_game.rs`:
458
459 ```{rust}
460 fn main() {
461     println!("Hello world!");
462 }
463 ```
464
465 Let's make sure that worked:
466
467 ```{bash}
468 $ cargo build
469    Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
470 $
471 ```
472
473 Excellent! Open up your `src/guessing_game.rs` again. We'll be writing all of
474 our code in this file. The next section of the tutorial will show you how to
475 build multiple-file projects.
476
477 ## Variable bindings
478
479 The first thing we'll learn about are 'variable bindings.' They look like this:
480
481 ```{rust}
482 let x = 5i;
483 ```
484
485 In many languages, this is called a 'variable.' But Rust's variable bindings
486 have a few tricks up their sleeves. Rust has a very powerful feature called
487 'pattern matching' that we'll get into detail with later, but the left
488 hand side of a `let` expression is a full pattern, not just a variable name.
489 This means we can do things like:
490
491 ```{rust}
492 let (x, y) = (1i, 2i);
493 ```
494
495 After this expression is evaluated, `x` will be one, and `y` will be two.
496 Patterns are really powerful, but this is about all we can do with them so far.
497 So let's just keep this in the back of our minds as we go forward.
498
499 By the way, in these examples, `i` indicates that the number is an integer.
500
501 Rust is a statically typed language, which means that we specify our types up
502 front. So why does our first example compile? Well, Rust has this thing called
503 "[Hindley-Milner type
504 inference](http://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system)",
505 named after some really smart type theorists. If you clicked that link, don't
506 be scared: what this means for you is that Rust will attempt to infer the types
507 in your program, and it's pretty good at it. If it can infer the type, Rust
508 doesn't require you to actually type it out.
509
510 We can add the type if we want to. Types come after a colon (`:`):
511
512 ```{rust}
513 let x: int = 5;
514 ```
515
516 If I asked you to read this out loud to the rest of the class, you'd say "`x`
517 is a binding with the type `int` and the value `five`."
518
519 By default, bindings are **immutable**. This code will not compile:
520
521 ```{ignore}
522 let x = 5i;
523 x = 10i;
524 ```
525
526 It will give you this error:
527
528 ```{ignore,notrust}
529 error: re-assignment of immutable variable `x`
530      x = 10i;
531      ^~~~~~~
532 ```
533
534 If you want a binding to be mutable, you can use `mut`:
535
536 ```{rust}
537 let mut x = 5i;
538 x = 10i;
539 ```
540
541 There is no single reason that bindings are immutable by default, but we can
542 think about it through one of Rust's primary focuses: safety. If you forget to
543 say `mut`, the compiler will catch it, and let you know that you have mutated
544 something you may not have cared to mutate. If bindings were mutable by
545 default, the compiler would not be able to tell you this. If you _did_ intend
546 mutation, then the solution is quite easy: add `mut`.
547
548 There are other good reasons to avoid mutable state when possible, but they're
549 out of the scope of this guide. In general, you can often avoid explicit
550 mutation, and so it is preferable in Rust. That said, sometimes, mutation is
551 what you need, so it's not verboten.
552
553 Let's get back to bindings. Rust variable bindings have one more aspect that
554 differs from other languages: bindings are required to be initialized with a
555 value before you're allowed to use it. If we try...
556
557 ```{ignore}
558 let x;
559 ```
560
561 ...we'll get an error:
562
563 ```{ignore}
564 src/guessing_game.rs:2:9: 2:10 error: cannot determine a type for this local variable: unconstrained type
565 src/guessing_game.rs:2     let x;
566                                ^
567 ```
568
569 Giving it a type will compile, though:
570
571 ```{ignore}
572 let x: int;
573 ```
574
575 Let's try it out. Change your `src/guessing_game.rs` file to look like this:
576
577 ```{rust}
578 fn main() {
579     let x: int;
580
581     println!("Hello world!");
582 }
583 ```
584
585 You can use `cargo build` on the command line to build it. You'll get a warning,
586 but it will still print "Hello, world!":
587
588 ```{ignore,notrust}
589    Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
590 src/guessing_game.rs:2:9: 2:10 warning: unused variable: `x`, #[warn(unused_variable)] on by default
591 src/guessing_game.rs:2     let x: int;
592                                ^
593 ```
594
595 Rust warns us that we never use the variable binding, but since we never use it,
596 no harm, no foul. Things change if we try to actually use this `x`, however. Let's
597 do that. Change your program to look like this:
598
599 ```{rust,ignore}
600 fn main() {
601     let x: int;
602
603     println!("The value of x is: {}", x);
604 }
605 ```
606
607 And try to build it. You'll get an error:
608
609 ```{bash}
610 $ cargo build
611    Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
612 src/guessing_game.rs:4:39: 4:40 error: use of possibly uninitialized variable: `x`
613 src/guessing_game.rs:4     println!("The value of x is: {}", x);
614                                                              ^
615 note: in expansion of format_args!
616 <std macros>:2:23: 2:77 note: expansion site
617 <std macros>:1:1: 3:2 note: in expansion of println!
618 src/guessing_game.rs:4:5: 4:42 note: expansion site
619 error: aborting due to previous error
620 Could not execute process `rustc src/guessing_game.rs --crate-type bin --out-dir /home/you/projects/guessing_game/target -L /home/you/projects/guessing_game/target -L /home/you/projects/guessing_game/target/deps` (status=101)
621 ```
622
623 Rust will not let us use a value that has not been initialized. So why let us
624 declare a binding without initializing it? You'd think our first example would
625 have errored. Well, Rust is smarter than that. Before we get to that, let's talk
626 about this stuff we've added to `println!`.
627
628 If you include two curly braces (`{}`, some call them moustaches...) in your
629 string to print, Rust will interpret this as a request to interpolate some sort
630 of value. **String interpolation** is a computer science term that means "stick
631 in the middle of a string." We add a comma, and then `x`, to indicate that we
632 want `x` to be the value we're interpolating. The comma is used to separate
633 arguments we pass to functions and macros, if you're passing more than one.
634
635 When you just use the double curly braces, Rust will attempt to display the
636 value in a meaningful way by checking out its type. If you want to specify the
637 format in a more detailed manner, there are a [wide number of options
638 available](/std/fmt/index.html). Fow now, we'll just stick to the default:
639 integers aren't very complicated to print.
640
641 So, we've cleared up all of the confusion around bindings, with one exception:
642 why does Rust let us declare a variable binding without an initial value if we
643 must initialize the binding before we use it? And how does it know that we have
644 or have not initialized the binding? For that, we need to learn our next
645 concept: `if`.
646
647 ## If
648
649 Rust's take on `if` is not particularly complex, but it's much more like the
650 `if` you'll find in a dynamically typed language than in a more traditional
651 systems language. So let's talk about it, to make sure you grasp the nuances.
652
653 `if` is a specific form of a more general concept, the 'branch.' The name comes
654 from a branch in a tree: a decision point, where depending on a choice,
655 multiple paths can be taken.
656
657 In the case of `if`, there is one choice that leads down two paths:
658
659 ```rust
660 let x = 5i;
661
662 if x == 5i {
663     println!("x is five!");
664 }
665 ```
666
667 If we changed the value of `x` to something else, this line would not print.
668 More specifically, if the expression after the `if` evaluates to `true`, then
669 the block is executed. If it's `false`, then it is not.
670
671 If you want something to happen in the `false` case, use an `else`:
672
673 ```
674 let x = 5i;
675
676 if x == 5i {
677     println!("x is five!");
678 } else {
679     println!("x is not five :(");
680 }
681 ```
682
683 This is all pretty standard. However, you can also do this:
684
685
686 ```
687 let x = 5i;
688
689 let y = if x == 5i {
690     10i
691 } else {
692     15i
693 };
694 ```
695
696 Which we can (and probably should) write like this:
697
698 ```
699 let x = 5i;
700
701 let y = if x == 5i { 10i } else { 15i };
702 ```
703
704 This reveals two interesting things about Rust: it is an expression-based
705 language, and semicolons are different than in other 'curly brace and
706 semicolon'-based languages. These two things are related.
707
708 ### Expressions vs. Statements
709
710 Rust is primarily an expression based language. There are only two kinds of
711 statements, and everything else is an expression.
712
713 So what's the difference? Expressions return a value, and statements do not.
714 In many languages, `if` is a statement, and therefore, `let x = if ...` would
715 make no sense. But in Rust, `if` is an expression, which means that it returns
716 a value. We can then use this value to initialize the binding.
717
718 Speaking of which, bindings are a kind of the first of Rust's two statements.
719 The proper name is a **declaration statement**. So far, `let` is the only kind
720 of declaration statement we've seen. Let's talk about that some more.
721
722 In some languages, variable bindings can be written as expressions, not just
723 statements. Like Ruby:
724
725 ```{ruby}
726 x = y = 5
727 ```
728
729 In Rust, however, using `let` to introduce a binding is _not_ an expression. The
730 following will produce a compile-time error:
731
732 ```{ignore}
733 let x = (let y = 5i); // found `let` in ident position
734 ```
735
736 The compiler is telling us here that it was expecting to see the beginning of
737 an expression, and a `let` can only begin a statement, not an expression.
738
739 However, assigning to a variable binding is an expression:
740
741 ```{rust}
742 let x;
743 let y = x = 5i;
744 ```
745
746 In this case, we have an assignment expression (`x = 5`) whose value is
747 being used as part of a `let` declaration statement (`let y = ...`).
748
749 The second kind of statement in Rust is the **expression statement**. Its
750 purpose is to turn any expression into a statement. In practical terms, Rust's
751 grammar expects statements to follow other statements. This means that you use
752 semicolons to separate expressions from each other. This means that Rust
753 looks a lot like most other languages that require you to use semicolons
754 at the end of every line, and you will see semicolons at the end of almost
755 every line of Rust code you see.
756
757 What is this exception that makes us say 'almost?' You saw it already, in this
758 code:
759
760 ```
761 let x = 5i;
762
763 let y: int = if x == 5i { 10i } else { 15i };
764 ```
765
766 Note that I've added the type annotation to `y`, to specify explicitly that I
767 want `y` to be an integer.
768
769 This is not the same as this, which won't compile:
770
771 ```{ignore}
772 let x = 5i;
773
774 let y: int = if x == 5 { 10i; } else { 15i; };
775 ```
776
777 Note the semicolons after the 10 and 15. Rust will give us the following error:
778
779 ```{ignore,notrust}
780 error: mismatched types: expected `int` but found `()` (expected int but found ())
781 ```
782
783 We expected an integer, but we got `()`. `()` is pronounced 'unit', and is a
784 special type in Rust's type system. `()` is different than `null` in other
785 languages, because `()` is distinct from other types. For example, in C, `null`
786 is a valid value for a variable of type `int`. In Rust, `()` is _not_ a valid
787 value for a variable of type `int`. It's only a valid value for variables of
788 the type `()`, which aren't very useful. Remember how we said statements don't
789 return a value? Well, that's the purpose of unit in this case. The semicolon
790 turns any expression into a statement by throwing away its value and returning
791 unit instead.
792
793 There's one more time in which you won't see a semicolon at the end of a line
794 of Rust code. For that, we'll need our next concept: functions.
795
796 ## Functions
797
798 You've already seen one function so far, the `main` function:
799
800 ```{rust}
801 fn main() {
802 }
803 ```
804
805 This is the simplest possible function declaration. As we mentioned before,
806 `fn` says 'this is a function,' followed by the name, some parenthesis because
807 this function takes no arguments, and then some curly braces to indicate the
808 body. Here's a function named `foo`:
809
810 ```{rust}
811 fn foo() {
812 }
813 ```
814
815 So, what about taking arguments? Here's a function that prints a number:
816
817 ```{rust}
818 fn print_number(x: int) {
819     println!("x is: {}", x);
820 }
821 ```
822
823 Here's a complete program that uses `print_number`:
824
825 ```{rust}
826 fn main() {
827     print_number(5);
828 }
829
830 fn print_number(x: int) {
831     println!("x is: {}", x);
832 }
833 ```
834
835 As you can see, function arguments work very similar to `let` declarations:
836 you add a type to the argument name, after a colon.
837
838 Here's a complete program that adds two numbers together and prints them:
839
840 ```{rust}
841 fn main() {
842     print_sum(5, 6);
843 }
844
845 fn print_sum(x: int, y: int) {
846     println!("sum is: {}", x + y);
847 }
848 ```
849
850 You separate arguments with a comma, both when you call the function, as well
851 as when you declare it.
852
853 Unlike `let`, you _must_ declare the types of function arguments. This does
854 not work:
855
856 ```{ignore}
857 fn print_number(x, y) {
858     println!("x is: {}", x + y);
859 }
860 ```
861
862 You get this error:
863
864 ```{ignore,notrust}
865 hello.rs:5:18: 5:19 error: expected `:` but found `,`
866 hello.rs:5 fn print_number(x, y) {
867 ```
868
869 This is a deliberate design decision. While full-program inference is possible,
870 languages which have it, like Haskell, often suggest that documenting your
871 types explicitly is a best-practice. We agree that forcing functions to declare
872 types while allowing for inference inside of function bodies is a wonderful
873 compromise between full inference and no inference.
874
875 What about returning a value? Here's a function that adds one to an integer:
876
877 ```{rust}
878 fn add_one(x: int) -> int {
879     x + 1
880 }
881 ```
882
883 Rust functions return exactly one value, and you declare the type after an
884 'arrow', which is a dash (`-`) followed by a greater-than sign (`>`).
885
886 You'll note the lack of a semicolon here. If we added it in:
887
888 ```{ignore}
889 fn add_one(x: int) -> int {
890     x + 1;
891 }
892 ```
893
894 We would get an error:
895
896 ```{ignore,notrust}
897 error: not all control paths return a value
898 fn add_one(x: int) -> int {
899      x + 1;
900 }
901
902 note: consider removing this semicolon:
903      x + 1;
904           ^
905 ```
906
907 Remember our earlier discussions about semicolons and `()`? Our function claims
908 to return an `int`, but with a semicolon, it would return `()` instead. Rust
909 realizes this probably isn't what we want, and suggests removing the semicolon.
910
911 This is very much like our `if` statement before: the result of the block
912 (`{}`) is the value of the expression. Other expression-oriented languages,
913 such as Ruby, work like this, but it's a bit unusual in the systems programming
914 world. When people first learn about this, they usually assume that it
915 introduces bugs. But because Rust's type system is so strong, and because unit
916 is its own unique type, we have never seen an issue where adding or removing a
917 semicolon in a return position would cause a bug.
918
919 But what about early returns? Rust does have a keyword for that, `return`:
920
921 ```{rust}
922 fn foo(x: int) -> int {
923     if x < 5 { return x; }
924
925     x + 1
926 }
927 ```
928
929 Using a `return` as the last line of a function works, but is considered poor
930 style:
931
932 ```{rust}
933 fn foo(x: int) -> int {
934     if x < 5 { return x; }
935
936     return x + 1;
937 }
938 ```
939
940 There are some additional ways to define functions, but they involve features
941 that we haven't learned about yet, so let's just leave it at that for now.
942
943
944 ## Comments
945
946 Now that we have some functions, it's a good idea to learn about comments.
947 Comments are notes that you leave to other programmers to help explain things
948 about your code. The compiler mostly ignores them.
949
950 Rust has two kinds of comments that you should care about: **line comment**s
951 and **doc comment**s.
952
953 ```{rust}
954 // Line comments are anything after '//' and extend to the end of the line.
955
956 let x = 5i; // this is also a line comment.
957
958 // If you have a long explanation for something, you can put line comments next
959 // to each other. Put a space between the // and your comment so that it's
960 // more readable.
961 ```
962
963 The other kind of comment is a doc comment. Doc comments use `///` instead of
964 `//`, and support Markdown notation inside:
965
966 ```{rust}
967 /// `hello` is a function that prints a greeting that is personalized based on
968 /// the name given.
969 ///
970 /// # Arguments
971 ///
972 /// * `name` - The name of the person you'd like to greet.
973 ///
974 /// # Example
975 ///
976 /// ```rust
977 /// let name = "Steve";
978 /// hello(name); // prints "Hello, Steve!"
979 /// ```
980 fn hello(name: &str) {
981     println!("Hello, {}!", name);
982 }
983 ```
984
985 When writing doc comments, adding sections for any arguments, return values,
986 and providing some examples of usage is very, very helpful.
987
988 You can use the `rustdoc` tool to generate HTML documentation from these doc
989 comments. We will talk more about `rustdoc` when we get to modules, as
990 generally, you want to export documentation for a full module.
991
992 ## Compound Data Types
993
994 Rust, like many programming languages, has a number of different data types
995 that are built-in. You've already done some simple work with integers and
996 strings, but next, let's talk about some more complicated ways of storing data.
997
998 ### Tuples
999
1000 The first compound data type we're going to talk about are called **tuple**s.
1001 Tuples are an ordered list of a fixed size. Like this:
1002
1003 ```rust
1004 let x = (1i, "hello");
1005 ```
1006
1007 The parenthesis and commas form this two-length tuple. Here's the same code, but
1008 with the type annotated:
1009
1010 ```rust
1011 let x: (int, &str) = (1, "hello");
1012 ```
1013
1014 As you can see, the type of a tuple looks just like the tuple, but with each
1015 position having a type name rather than the value. Careful readers will also
1016 note that tuples are heterogeneous: we have an `int` and a `&str` in this tuple.
1017 You haven't seen `&str` as a type before, and we'll discuss the details of
1018 strings later. In systems programming languages, strings are a bit more complex
1019 than in other languages. For now, just read `&str` as "a string slice," and
1020 we'll learn more soon.
1021
1022 You can access the fields in a tuple through a **destructuring let**. Here's
1023 an example:
1024
1025 ```rust
1026 let (x, y, z) = (1i, 2i, 3i);
1027
1028 println!("x is {}", x);
1029 ```
1030
1031 Remember before when I said the left hand side of a `let` statement was more
1032 powerful than just assigning a binding? Here we are. We can put a pattern on
1033 the left hand side of the `let`, and if it matches up to the right hand side,
1034 we can assign multiple bindings at once. In this case, `let` 'destructures,'
1035 or 'breaks up,' the tuple, and assigns the bits to three bindings.
1036
1037 This pattern is very powerful, and we'll see it repeated more later.
1038
1039 The last thing to say about tuples is that they are only equivalent if
1040 the arity, types, and values are all identical.
1041
1042 ```rust
1043 let x = (1i, 2i, 3i);
1044 let y = (2i, 3i, 4i);
1045
1046 if x == y {
1047     println!("yes");
1048 } else {
1049     println!("no");
1050 }
1051 ```
1052
1053 This will print `no`, as the values aren't equal.
1054
1055 One other use of tuples is to return multiple values from a function:
1056
1057 ```rust
1058 fn next_two(x: int) -> (int, int) { (x + 1i, x + 2i) }
1059
1060 fn main() {
1061     let (x, y) = next_two(5i);
1062     println!("x, y = {}, {}", x, y);
1063 }
1064 ```
1065
1066 Even though Rust functions can only return one value, a tuple _is_ one value,
1067 that happens to be made up of two. You can also see in this example how you
1068 can destructure a pattern returned by a function, as well.
1069
1070 Tuples are a very simple data structure, and so are not often what you want.
1071 Let's move on to their bigger sibling, structs.
1072
1073 ### Structs
1074
1075 A struct is another form of a 'record type,' just like a tuple. There's a
1076 difference: structs give each element that they contain a name, called a
1077 'field' or a 'member.' Check it out:
1078
1079 ```rust
1080 struct Point {
1081     x: int,
1082     y: int,
1083 }
1084
1085 fn main() {
1086     let origin = Point { x: 0i, y:  0i };
1087
1088     println!("The origin is at ({}, {})", origin.x, origin.y);
1089 }
1090 ```
1091
1092 There's a lot going on here, so let's break it down. We declare a struct with
1093 the `struct` keyword, and then with a name. By convention, structs begin with a
1094 capital letter and are also camel cased: `PointInSpace`, not `Point_In_Space`.
1095
1096 We can create an instance of our struct via `let`, as usual, but we use a `key:
1097 value` style syntax to set each field. The order doesn't need to be the same as
1098 in the original declaration.
1099
1100 Finally, because fields have names, we can access the field through dot
1101 notation: `origin.x`.
1102
1103 The values in structs are immutable, like other bindings in Rust. However, you
1104 can use `mut` to make them mutable:
1105
1106 ```rust
1107 struct Point {
1108     x: int,
1109     y: int,
1110 }
1111
1112 fn main() {
1113     let mut point = Point { x: 0i, y:  0i };
1114
1115     point.x = 5;
1116
1117     println!("The point is at ({}, {})", point.x, point.y);
1118 }
1119 ```
1120
1121 This will print `The point is at (5, 0)`.
1122
1123 ### Tuple Structs and Newtypes
1124
1125 Rust has another data type that's like a hybrid between a tuple and a struct,
1126 called a **tuple struct**. Tuple structs do have a name, but their fields
1127 don't:
1128
1129
1130 ```
1131 struct Color(int, int, int);
1132 struct Point(int, int, int);
1133 ```
1134
1135 These two will not be equal, even if they have the same values:
1136
1137 ```{rust,ignore}
1138 let black  = Color(0, 0, 0);
1139 let origin = Point(0, 0, 0);
1140 ```
1141
1142 It is almost always better to use a struct than a tuple struct. We would write
1143 `Color` and `Point` like this instead:
1144
1145 ```rust
1146 struct Color {
1147     red: int,
1148     blue: int,
1149     green: int,
1150 }
1151
1152 struct Point {
1153     x: int,
1154     y: int,
1155     z: int,
1156 }
1157 ```
1158
1159 Now, we have actual names, rather than positions. Good names are important,
1160 and with a struct, we have actual names.
1161
1162 There _is_ one case when a tuple struct is very useful, though, and that's a
1163 tuple struct with only one element. We call this a 'newtype,' because it lets
1164 you create a new type that's a synonym for another one:
1165
1166 ```
1167 struct Inches(int);
1168 struct Centimeters(int);
1169
1170 let length = Inches(10);
1171
1172 let Inches(integer_length) = length;
1173 println!("length is {} inches", integer_length);
1174 ```
1175
1176 As you can see here, you can extract the inner integer type through a
1177 destructuring `let`.
1178
1179 ### Enums
1180
1181 Finally, Rust has a "sum type", an **enum**. Enums are an incredibly useful
1182 feature of Rust, and are used throughout the standard library. Enums look
1183 like this:
1184
1185 ```
1186 enum Ordering {
1187     Less,
1188     Equal,
1189     Greater,
1190 }
1191 ```
1192
1193 This is an enum that is provided by the Rust standard library. An `Ordering`
1194 can only be _one_ of `Less`, `Equal`, or `Greater` at any given time. Here's
1195 an example:
1196
1197 ```rust
1198 let x = 5i;
1199 let y = 10i;
1200
1201 let ordering = x.cmp(&y);
1202
1203 if ordering == Less {
1204     println!("less");
1205 } else if ordering == Greater {
1206     println!("greater");
1207 } else if ordering == Equal {
1208     println!("equal");
1209 }
1210 ```
1211
1212 `cmp` is a function that compares two things, and returns an `Ordering`. The
1213 call looks a little bit strange: rather than `cmp(x, y)`, we say `x.cmp(&y)`.
1214 We haven't covered methods and references yet, so it should look a little bit
1215 foreign. Right now, just pretend it says `cmp(x, y)`, and we'll get to those
1216 details soon.
1217
1218 The `ordering` variable has the type `Ordering`, and so contains one of the
1219 three values. We can then do a bunch of `if`/`else` comparisons to check
1220 which one it is.
1221
1222 However, repeated `if`/`else` comparisons get quite tedious. Rust has a feature
1223 that not only makes them nicer to read, but also makes sure that you never
1224 miss a case. Before we get to that, though, let's talk about another kind of
1225 enum: one with values.
1226
1227 This enum has two variants, one of which has a value.:
1228
1229 ```
1230 enum OptionalInt {
1231     Value(int),
1232     Missing
1233 }
1234
1235 fn main() {
1236     let x = Value(5);
1237     let y = Missing;
1238
1239     match x {
1240         Value(n) => println!("x is {:d}", n),
1241         Missing  => println!("x is missing!"),
1242     }
1243
1244     match y {
1245         Value(n) => println!("y is {:d}", n),
1246         Missing  => println!("y is missing!"),
1247     }
1248 }
1249 ```
1250
1251 This enum represents an `int` that we may or may not have. In the `Missing`
1252 case, we have no value, but in the `Value` case, we do. This enum is specific
1253 to `int`s, though. We can make it usable by any type, but we haven't quite
1254 gotten there yet!
1255
1256 You can have any number of values in an enum:
1257
1258 ```
1259 enum OptionalColor {
1260     Color(int, int, int),
1261     Missing
1262 }
1263 ```
1264
1265 Enums with values are quite useful, but as I mentioned, they're even more
1266 useful when they're generic across types. But before we get to generics, let's
1267 talk about how to fix this big `if`/`else` statements we've been writing. We'll
1268 do that with `match`.
1269
1270 ## Match
1271
1272 ## Looping
1273
1274 for
1275
1276 while
1277
1278 loop
1279
1280 break/continue
1281
1282 ## Guessing Game: complete
1283
1284 At this point, you have successfully built the Guessing Game! Congratulations!
1285 For reference, [We've placed the sample code on
1286 GitHub](https://github.com/steveklabnik/guessing_game).
1287
1288 You've now learned the basic syntax of Rust. All of this is relatively close to
1289 various other programming languages you have used in the past. These
1290 fundamental syntactical and semantic elements will form the foundation for the
1291 rest of your Rust education.
1292
1293 Now that you're an expert at the basics, it's time to learn about some of
1294 Rust's more unique features.
1295
1296 ## iterators
1297
1298 ## Lambdas
1299
1300 ## Testing
1301
1302 attributes
1303
1304 stability markers
1305
1306 ## Crates and Modules
1307
1308 visibility
1309
1310
1311 ## Generics
1312
1313 ## Traits
1314
1315 ## Operators and built-in Traits
1316
1317 ## Ownership and Lifetimes
1318
1319 Move vs. Copy
1320
1321 Allocation
1322
1323 ## Tasks
1324
1325 ## Macros
1326
1327 ## Unsafe
1328