]> git.lizzy.rs Git - rust.git/blob - src/doc/guide.md
Guide: add mutable binding section
[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 host: x86_64-unknown-linux-gnu
95 ```
96
97 If you did, Rust has been installed successfully! Congrats!
98
99 If not, there are a number of places where you can get help. The easiest is
100 [the #rust IRC channel on irc.mozilla.org](irc://irc.mozilla.org/#rust), which
101 you can access through
102 [Mibbit](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust). Click
103 that link, and you'll be chatting with other Rustaceans (a silly nickname we
104 call ourselves), and we can help you out. Other great resources include [our
105 mailing list](https://mail.mozilla.org/listinfo/rust-dev), [the /r/rust
106 subreddit](http://www.reddit.com/r/rust), and [Stack
107 Overflow](http://stackoverflow.com/questions/tagged/rust).
108
109 ## Hello, world!
110
111 Now that you have Rust installed, let's write your first Rust program. It's
112 traditional to make your first program in any new language one that prints the
113 text "Hello, world!" to the screen. The nice thing about starting with such a
114 simple program is that you can verify that your compiler isn't just installed,
115 but also working properly. And printing information to the screen is a pretty
116 common thing to do.
117
118 The first thing that we need to do is make a file to put our code in. I like
119 to make a projects directory in my home directory, and keep all my projects
120 there. Rust does not care where your code lives.
121
122 This actually leads to one other concern we should address: this tutorial will
123 assume that you have basic familiarity with the command-line. Rust does not
124 require that you know a whole ton about the command line, but until the
125 language is in a more finished state, IDE support is spotty. Rust makes no
126 specific demands on your editing tooling, or where your code lives.
127
128 With that said, let's make a directory in our projects directory.
129
130 ```{bash}
131 $ mkdir ~/projects
132 $ cd ~/projects
133 $ mkdir hello_world
134 $ cd hello_world
135 ```
136
137 If you're on Windows and not using PowerShell, the `~` may not work. Consult
138 the documentation for your shell for more details.
139
140 Let's make a new source file next. I'm going to use the syntax `editor
141 filename` to represent editing a file in these examples, but you should use
142 whatever method you want. We'll call our file `hello_world.rs`:
143
144 ```{bash}
145 $ editor hello_world.rs
146 ```
147
148 Rust files always end in a `.rs` extension. If you're using more than one word
149 in your file name, use an underscore. `hello_world.rs` versus `goodbye.rs`.
150
151 Now that you've got your file open, type this in:
152
153 ```
154 fn main() {
155     println!("Hello, world");
156 }
157 ```
158
159 Save the file, and then type this into your terminal window:
160
161 ```{bash}
162 $ rustc hello_world.rs
163 $ ./hello_world # or hello_world.exe on Windows
164 Hello, world
165 ```
166
167 Success! Let's go over what just happened in detail.
168
169 ```
170 fn main() {
171    
172 }
173 ```
174
175 These two lines define a **function** in Rust. The `main` function is special:
176 it's the beginning of every Rust program. The first line says "I'm declaring a
177 function named `main`, which takes no arguments and returns nothing." If there
178 were arguments, they would go inside the parentheses (`(` and `)`), and because
179 we aren't returning anything from this function, we've dropped that notation
180 entirely.  We'll get to it later.
181
182 You'll also note that the function is wrapped in curly braces (`{` and `}`).
183 Rust requires these around all function bodies. It is also considered good
184 style to put the opening curly brace on the same line as the function
185 declaration, with one space in between.
186
187 Next up is this line:
188
189 ```
190     println!("Hello, world");
191 ```
192
193 This line does all of the work in our little program. There are a number of
194 details that are important here. The first is that it's indented with four
195 spaces, not tabs. Please configure your editor of choice to insert four spaces
196 with the tab key. We provide some sample configurations for various editors
197 [here](https://github.com/rust-lang/rust/tree/master/src/etc).
198
199 The second point is the `println!()` part. This is calling a Rust **macro**,
200 which is how metaprogramming is done in Rust. If it were a function instead, it
201 would look like this: `println()`. For our purposes, we don't need to worry
202 about this difference. Just know that sometimes, you'll see a `!`, and that
203 means that you're calling a macro instead of a normal function. One last thing
204 to mention: Rust's macros are significantly different than C macros, if you've
205 used those. Don't be scared of using macros. We'll get to the details
206 eventually, you'll just have to trust us for now.
207
208 Next, `"Hello, world"` is a **string**. Strings are a surprisingly complicated
209 topic in a systems programming language, and this is a **statically allocated**
210 string. We will talk more about different kinds of allocation later. We pass
211 this string as an argument to `println!`, which prints the string to the
212 screen. Easy enough!
213
214 Finally, the line ends with a semicolon (`;`). Rust is an **expression
215 oriented** language, which means that most things are expressions. The `;` is
216 used to indicate that this expression is over, and the next one is ready to
217 begin. Most lines of Rust code end with a `;`. We will cover this in-depth
218 later in the tutorial.
219
220 Finally, actually **compiling** and **running** our program. We can compile
221 with our compiler, `rustc`, by passing it the name of our source file:
222
223 ```{bash}
224 $ rustc hello_world.rs
225 ```
226
227 This is similar to `gcc` or `clang`, if you come from a C or C++ background. Rust
228 will output a binary executable. You can see it with `ls`:
229
230 ```{bash}
231 $ ls
232 hello_world  hello_world.rs
233 ```
234
235 Or on Windows:
236
237 ```{bash}
238 $ dir
239 hello_world.exe  hello_world.rs
240 ```
241
242 There are now two files: our source code, with the `.rs` extension, and the
243 executable (`hello_world.exe` on Windows, `hello_world` everywhere else)
244
245 ```{bash}
246 $ ./hello_world  # or hello_world.exe on Windows
247 ```
248
249 This prints out our `Hello, world!` text to our terminal.
250
251 If you come from a dynamically typed language like Ruby, Python, or JavaScript,
252 you may not be used to these two steps being separate. Rust is an
253 **ahead-of-time compiled language**, which means that you can compile a
254 program, give it to someone else, and they don't need to have Rust installed.
255 If you give someone a `.rb` or `.py` or `.js` file, they need to have
256 Ruby/Python/JavaScript installed, but you just need one command to both compile
257 and run your program. Everything is a tradeoff in language design, and Rust has
258 made its choice.
259
260 Congratulations! You have officially written a Rust program. That makes you a
261 Rust programmer! Welcome.
262
263 Next, I'd like to introduce you to another tool, Cargo, which is used to write
264 real-world Rust programs. Just using `rustc` is nice for simple things, but as
265 your project grows, you'll want something to help you manage all of the options
266 that it has, and to make it easy to share your code with other people and
267 projects.
268
269 ## Hello, Cargo!
270
271 [Cargo](http://crates.io) is a tool that Rustaceans use to help manage their
272 Rust projects. Cargo is currently in an alpha state, just like Rust, and so it
273 is still a work in progress. However, it is already good enough to use for many
274 Rust projects, and so it is assumed that Rust projects will use Cargo from the
275 beginning.
276
277 Programmers love car analogies, so I've got a good one for you to think about
278 the relationship between `cargo` and `rustc`: `rustc` is like a car, and
279 `cargo` is like a robotic driver. You can drive your car yourself, of course,
280 but isn't it just easier to let a computer drive it for you?
281
282 Anyway, Cargo manages three things: building your code, downloading the
283 dependencies your code needs, and building the dependencies your code needs.
284 At first, your program doesn't have any dependencies, so we'll only be using
285 the first part of its functionality. Eventually, we'll add more. Since we
286 started off by using Cargo, it'll be easy to add later.
287
288 Let's convert Hello World to Cargo. The first thing we need to do to begin using Cargo
289 is to install Cargo. To do this, we need to build it from source. There are no binaries
290 yet.
291
292 First, let's go back to our projects directory. We don't want Cargo to
293 live in our project!
294
295 ```{bash}
296 $ cd ..
297 ```
298
299 Next, we need these commands:
300
301 ```{bash}
302 $ git clone --recursive https://github.com/rust-lang/cargo
303 $ cd cargo
304 $ make
305 $ make install # may need sudo or admin permissions
306 ```
307
308 The `--recursive` downloads Cargo's own dependencies. You can't use Cargo to
309 fetch dependencies until you have Cargo installed! Also, you will need to have
310 `git` installed. Much of the Rust world assumes `git` usage, so it's a good
311 thing to have around. Please check out [the git
312 documentation](http://git-scm.com/book/en/Getting-Started-Installing-Git) for
313 more on installing `git`.
314
315 We hope to give Cargo a binary installer, similar to Rust's own, so that
316 this will not be necessary in the future.
317
318 Let's see if that worked. Try this:
319
320 ```{bash}
321 $ cargo
322 Commands:
323   build          # compile the current project
324
325 Options (for all commands):
326
327 -v, [--verbose]
328 -h, [--help]
329 ```
330
331 If you see this output when you run `cargo`, congrats! Cargo is working. If
332 not, please [open an issue](https://github.com/rust-lang/cargo/issues/new) or
333 drop by the Rust IRC, and we can help you out.
334
335 Let's move back into our `hello_world` directory now:
336
337 ```{bash}
338 $ cd ..              # move back up into projects
339 $ cd hello_world     # move into hello_world
340 ```
341
342 To Cargo-ify our project, we need to do two things: Make a `Cargo.toml`
343 configuration file, and put our source file in the right place. Let's
344 do that part first:
345
346 ```{bash}
347 $ mkdir src
348 $ mv hello_world.rs src/hello_world.rs
349 ```
350
351 Cargo expects your source files to live inside a `src` directory. That leaves
352 the top level for other things, like READMEs, licence information, and anything
353 not related to your code. Cargo helps us keep our projects nice and tidy. A
354 place for everything, and everything in its place.
355
356 Next, our configuration file:
357
358 ```{bash}
359 $ editor Cargo.toml
360 ```
361
362 Make sure to get this name right: you need the capital `C`!
363
364 Put this inside:
365
366 ```{ignore}
367 [package]
368
369 name = "hello_world"
370 version = "0.1.0"
371 authors = [ "someone@example.com" ]
372
373 [[bin]]
374
375 name = "hello_world"
376 ```
377
378 This file is in the [TOML](https://github.com/toml-lang/toml) format. Let's let
379 it explain itself to you:
380
381 > TOML aims to be a minimal configuration file format that's easy to read due
382 > to obvious semantics. TOML is designed to map unambiguously to a hash table.
383 > TOML should be easy to parse into data structures in a wide variety of
384 > languages.
385
386 TOML is very similar to INI, but with some extra goodies.
387
388 Anyway, there are two **table**s in this file: `package` and `bin`. The first
389 tells Cargo metadata about your package. The second tells Cargo that we're
390 interested in building a binary, not a library (though we could do both!), as
391 well as what it is named.
392
393 Once you have this file in place, we should be ready to build! Try this:
394
395 ```{bash}
396 $ cargo build
397    Compiling hello_world v0.1.0 (file:/home/yourname/projects/hello_world)
398 $ ./target/hello_world 
399 Hello, world!
400 ```
401
402 Bam! We build our project with `cargo build`, and run it with
403 `./target/hello_world`. This hasn't bought us a whole lot over our simple use
404 of `rustc`, but think about the future: when our project has more than one
405 file, we would need to call `rustc` twice, and pass it a bunch of options to
406 tell it to build everything together. With Cargo, as our project grows, we can
407 just `cargo build` and it'll work the right way.
408
409 That's it! We've successfully built `hello_world` with Cargo. Even though our
410 program is simple, it's using much of the real tooling that you'll use for the
411 rest of your Rust career.
412
413 Next, we'll learn more about Rust itself, by starting to write a more complicated
414 program. We hope you want to do more with Rust than just print "Hello, world!"
415
416 ## Guessing Game
417
418 Let's write a bigger program in Rust. We could just go through a laundry list
419 of Rust features, but that's boring. Instead, we'll learn more about how to
420 code in Rust by writing a few example projects.
421
422 For our first project, we'll implement a classic beginner programming problem:
423 the guessing game. Here's how it works: Our program will generate a random
424 integer between one and a hundred. It will then prompt us to enter a guess.
425 Upon entering our guess, it will tell us if we're too low or too high. Once we
426 guess correctly, it will congratulate us, and print the number of guesses we've
427 taken to the screen. Sound good? It sounds easy, but it'll end up showing off a
428 number of basic features of Rust.
429
430 ### Set up
431
432 Let's set up a new project. Go to your projects directory, and make a new
433 directory for the project, as well as a `src` directory for our code:
434
435 ```{bash}
436 $ cd ~/projects
437 $ mkdir guessing_game
438 $ cd guessing_game
439 $ mkdir src
440 ```
441
442 Great. Next, let's make a `Cargo.toml` file so Cargo knows how to build our
443 project:
444
445 ```{ignore}
446 [package]
447
448 name = "guessing_game"
449 version = "0.1.0"
450 authors = [ "someone@example.com" ]
451
452 [[bin]]
453
454 name = "guessing_game"
455 ```
456
457 Finally, we need our source file. Let's just make it hello world for now, so we
458 can check that our setup works. In `src/guessing_game.rs`:
459
460 ```{rust}
461 fn main() {
462     println!("Hello world!");
463 }
464 ```
465
466 Let's make sure that worked:
467
468 ```{bash}
469 $ cargo build
470    Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
471 $
472 ```
473
474 Excellent! Open up your `src/guessing_game.rs` again. We'll be writing all of
475 our code in this file. The next section of the tutorial will show you how to
476 build multiple-file projects.
477
478 ## Variable bindings
479
480 The first thing we'll learn about are 'variable bindings.' They look like this:
481
482 ```{rust}
483 let x = 5i;
484 ```
485
486 In many languages, this is called a 'variable.' But Rust's variable bindings
487 have a few tricks up their sleeves. Rust has a very powerful feature called
488 'pattern matching' that we'll get into detail with later, but the left
489 hand side of a `let` expression is a full pattern, not just a variable name.
490 This means we can do things like:
491
492 ```{rust}
493 let (x, y) = (1i, 2i);
494 ```
495
496 After this expression is evaluated, `x` will be one, and `y` will be two.
497 Patterns are really powerful, but this is about all we can do with them so far.
498 So let's just keep this in the back of our minds as we go forward.
499
500 By the way, in these examples, `i` indicates that the number is an integer.
501
502 Rust is a statically typed language, which means that we specify our types up
503 front. So why does our first example compile? Well, Rust has this thing called
504 "[Hindley-Milner type
505 inference](http://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system)",
506 named after some really smart type theorists. If you clicked that link, don't
507 be scared: what this means for you is that Rust will attempt to infer the types
508 in your program, and it's pretty good at it. If it can infer the type, Rust
509 doesn't require you to actually type it out.
510
511 We can add the type if we want to. Types come after a colon (`:`):
512
513 ```{rust}
514 let x: int = 5;
515 ```
516
517 If I asked you to read this out loud to the rest of the class, you'd say "`x`
518 is a binding with the type `int` and the value `five`."
519
520 By default, bindings are **immutable**. This code will not compile:
521
522 ```{ignore}
523 let x = 5i;
524 x = 10i;
525 ```
526
527 It will give you this error:
528
529 ```{ignore,notrust}
530 error: re-assignment of immutable variable `x`
531      x = 10i;
532      ^~~~~~~
533 ```
534
535 If you want a binding to be mutable, you can use `mut`:
536
537 ```{rust}
538 let mut x = 5i;
539 x = 10i;
540 ```
541
542 There is no single reason that bindings are immutable by default, but we can
543 think about it through one of Rust's primary focuses: safety. If you forget to
544 say `mut`, the compiler will catch it, and let you know that you have mutated
545 something you may not have cared to mutate. If bindings were mutable by
546 default, the compiler would not be able to tell you this. If you _did_ intend
547 mutation, then the solution is quite easy: add `mut`.
548
549 There are other good reasons to avoid mutable state when possible, but they're
550 out of the scope of this guide. In general, you can often avoid explicit
551 mutation, and so it is preferable in Rust. That said, sometimes, mutation is
552 what you need, so it's not verboten.
553
554 Let's get back to bindings. Rust variable bindings have one more aspect that
555 differs from other languages: bindings are required to be initialized with a
556 value before you're allowed to use it. If we try...
557
558 ```{ignore}
559 let x;
560 ```
561
562 ...we'll get an error:
563
564 ```{ignore}
565 src/guessing_game.rs:2:9: 2:10 error: cannot determine a type for this local variable: unconstrained type
566 src/guessing_game.rs:2     let x;
567                                ^
568 ```
569
570 Giving it a type will compile, though:
571
572 ```{ignore}
573 let x: int;
574 ```
575
576 Let's try it out. Change your `src/guessing_game.rs` file to look like this:
577
578 ```{rust}
579 fn main() {
580     let x: int;
581
582     println!("Hello world!");
583 }
584 ```
585
586 You can use `cargo build` on the command line to build it. You'll get a warning,
587 but it will still print "Hello, world!":
588
589 ```{ignore,notrust}
590    Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
591 src/guessing_game.rs:2:9: 2:10 warning: unused variable: `x`, #[warn(unused_variable)] on by default
592 src/guessing_game.rs:2     let x: int;
593                                ^
594 ```
595
596 Rust warns us that we never use the variable binding, but since we never use it,
597 no harm, no foul. Things change if we try to actually use this `x`, however. Let's
598 do that. Change your program to look like this:
599
600 ```{rust,ignore}
601 fn main() {
602     let x: int;
603
604     println!("The value of x is: {}", x);
605 }
606 ```
607
608 And try to build it. You'll get an error:
609
610 ```{bash}
611 $ cargo build
612    Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
613 src/guessing_game.rs:4:39: 4:40 error: use of possibly uninitialized variable: `x`
614 src/guessing_game.rs:4     println!("The value of x is: {}", x);
615                                                              ^
616 note: in expansion of format_args!
617 <std macros>:2:23: 2:77 note: expansion site
618 <std macros>:1:1: 3:2 note: in expansion of println!
619 src/guessing_game.rs:4:5: 4:42 note: expansion site
620 error: aborting due to previous error
621 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)
622 ```
623
624 Rust will not let us use a value that has not been initialized. So why let us
625 declare a binding without initializing it? You'd think our first example would
626 have errored. Well, Rust is smarter than that. Before we get to that, let's talk
627 about this stuff we've added to `println!`.
628
629 If you include two curly braces (`{}`, some call them moustaches...) in your
630 string to print, Rust will interpret this as a request to interpolate some sort
631 of value. **String interpolation** is a computer science term that means "stick
632 in the middle of a string." We add a comma, and then `x`, to indicate that we
633 want `x` to be the value we're interpolating. The comma is used to separate
634 arguments we pass to functions and macros, if you're passing more than one.
635
636 When you just use the double curly braces, Rust will attempt to display the
637 value in a meaningful way by checking out its type. If you want to specify the
638 format in a more detailed manner, there are a [wide number of options
639 available](/std/fmt/index.html). Fow now, we'll just stick to the default:
640 integers aren't very complicated to print.
641
642 So, we've cleared up all of the confusion around bindings, with one exception:
643 why does Rust let us declare a variable binding without an initial value if we
644 must initialize the binding before we use it? And how does it know that we have
645 or have not initialized the binding? For that, we need to learn our next
646 concept: `if`.
647
648 ## If
649
650 Rust's take on `if` is not particularly complex, but it's much more like the
651 `if` you'll find in a dynamically typed language than in a more traditional
652 systems language. So let's talk about it, to make sure you grasp the nuances.
653
654 `if` is a specific form of a more general concept, the 'branch.' The name comes
655 from a branch in a tree: a decision point, where depending on a choice,
656 multiple paths can be taken.
657
658 In the case of `if`, there is one choice that leads down two paths:
659
660 ```rust
661 let x = 5i;
662
663 if x == 5i {
664     println!("x is five!");
665 }
666 ```
667
668 If we changed the value of `x` to something else, this line would not print.
669 More specifically, if the expression after the `if` evaluates to `true`, then
670 the block is executed. If it's `false`, then it is not.
671
672 If you want something to happen in the `false` case, use an `else`:
673
674 ```
675 let x = 5i;
676
677 if x == 5i {
678     println!("x is five!");
679 } else {
680     println!("x is not five :(");
681 }
682 ```
683
684 This is all pretty standard. However, you can also do this:
685
686
687 ```
688 let x = 5i;
689
690 let y = if x == 5i {
691     10i
692 } else {
693     15i
694 };
695 ```
696
697 Which we can (and probably should) write like this:
698
699 ```
700 let x = 5i;
701
702 let y = if x == 5i { 10i } else { 15i };
703 ```
704
705 This reveals two interesting things about Rust: it is an expression-based
706 language, and semicolons are different than in other 'curly brace and
707 semicolon'-based languages. These two things are related.
708
709 ### Expressions vs. Statements
710
711 Rust is primarily an expression based language. There are only two kinds of
712 statements, and everything else is an expression.
713
714 So what's the difference? Expressions return a value, and statements do not.
715 In many languages, `if` is a statement, and therefore, `let x = if ...` would
716 make no sense. But in Rust, `if` is an expression, which means that it returns
717 a value. We can then use this value to initialize the binding.
718
719 Speaking of which, bindings are a kind of the first of Rust's two statements.
720 The proper name is a **declaration statement**. So far, `let` is the only kind
721 of declaration statement we've seen. Let's talk about that some more.
722
723 In some languages, variable bindings can be written as expressions, not just
724 statements. Like Ruby:
725
726 ```{ruby}
727 x = y = 5
728 ```
729
730 In Rust, however, using `let` to introduce a binding is _not_ an expression. The
731 following will produce a compile-time error:
732
733 ```{ignore}
734 let x = (let y = 5i); // found `let` in ident position
735 ```
736
737 The compiler is telling us here that it was expecting to see the beginning of
738 an expression, and a `let` can only begin a statement, not an expression.
739
740 However, re-assigning to a mutable binding is an expression:
741
742 ```{rust}
743 let mut x = 0i;
744 let y = x = 5i;
745 ```
746
747 In this case, we have an assignment expression (`x = 5`) whose value is
748 being used as part of a `let` declaration statement (`let y = ...`).
749
750 The second kind of statement in Rust is the **expression statement**. Its
751 purpose is to turn any expression into a statement. In practical terms, Rust's
752 grammar expects statements to follow other statements. This means that you use
753 semicolons to separate expressions from each other. This means that Rust
754 looks a lot like most other languages that require you to use semicolons
755 at the end of every line, and you will see semicolons at the end of almost
756 every line of Rust code you see.
757
758 What is this exception that makes us say 'almost?' You saw it already, in this
759 code:
760
761 ```
762 let x = 5i;
763
764 let y: int = if x == 5i { 10i } else { 15i };
765 ```
766
767 Note that I've added the type annotation to `y`, to specify explicitly that I
768 want `y` to be an integer.
769
770 This is not the same as this, which won't compile:
771
772 ```{ignore}
773 let x = 5i;
774
775 let y: int = if x == 5 { 10i; } else { 15i; };
776 ```
777
778 Note the semicolons after the 10 and 15. Rust will give us the following error:
779
780 ```{ignore,notrust}
781 error: mismatched types: expected `int` but found `()` (expected int but found ())
782 ```
783
784 We expected an integer, but we got `()`. `()` is pronounced 'unit', and is a
785 special type in Rust's type system. `()` is different than `null` in other
786 languages, because `()` is distinct from other types. For example, in C, `null`
787 is a valid value for a variable of type `int`. In Rust, `()` is _not_ a valid
788 value for a variable of type `int`. It's only a valid value for variables of
789 the type `()`, which aren't very useful. Remember how we said statements don't
790 return a value? Well, that's the purpose of unit in this case. The semicolon
791 turns any expression into a statement by throwing away its value and returning
792 unit instead.
793
794 There's one more time in which you won't see a semicolon at the end of a line
795 of Rust code. For that, we'll need our next concept: functions.
796
797 ## Functions
798
799 You've already seen one function so far, the `main` function:
800
801 ```{rust}
802 fn main() {
803 }
804 ```
805
806 This is the simplest possible function declaration. As we mentioned before,
807 `fn` says 'this is a function,' followed by the name, some parenthesis because
808 this function takes no arguments, and then some curly braces to indicate the
809 body. Here's a function named `foo`:
810
811 ```{rust}
812 fn foo() {
813 }
814 ```
815
816 So, what about taking arguments? Here's a function that prints a number:
817
818 ```{rust}
819 fn print_number(x: int) {
820     println!("x is: {}", x);
821 }
822 ```
823
824 Here's a complete program that uses `print_number`:
825
826 ```{rust}
827 fn main() {
828     print_number(5);
829 }
830
831 fn print_number(x: int) {
832     println!("x is: {}", x);
833 }
834 ```
835
836 As you can see, function arguments work very similar to `let` declarations:
837 you add a type to the argument name, after a colon.
838
839 Here's a complete program that adds two numbers together and prints them:
840
841 ```{rust}
842 fn main() {
843     print_sum(5, 6);
844 }
845
846 fn print_sum(x: int, y: int) {
847     println!("sum is: {}", x + y);
848 }
849 ```
850
851 You separate arguments with a comma, both when you call the function, as well
852 as when you declare it.
853
854 Unlike `let`, you _must_ declare the types of function arguments. This does
855 not work:
856
857 ```{ignore}
858 fn print_number(x, y) {
859     println!("x is: {}", x + y);
860 }
861 ```
862
863 You get this error:
864
865 ```{ignore,notrust}
866 hello.rs:5:18: 5:19 error: expected `:` but found `,`
867 hello.rs:5 fn print_number(x, y) {
868 ```
869
870 This is a deliberate design decision. While full-program inference is possible,
871 languages which have it, like Haskell, often suggest that documenting your
872 types explicitly is a best-practice. We agree that forcing functions to declare
873 types while allowing for inference inside of function bodies is a wonderful
874 compromise between full inference and no inference.
875
876 What about returning a value? Here's a function that adds one to an integer:
877
878 ```{rust}
879 fn add_one(x: int) -> int {
880     x + 1
881 }
882 ```
883
884 Rust functions return exactly one value, and you declare the type after an
885 'arrow', which is a dash (`-`) followed by a greater-than sign (`>`).
886
887 You'll note the lack of a semicolon here. If we added it in:
888
889 ```{ignore}
890 fn add_one(x: int) -> int {
891     x + 1;
892 }
893 ```
894
895 We would get an error:
896
897 ```{ignore,notrust}
898 note: consider removing this semicolon:
899      x + 1;
900           ^
901 error: not all control paths return a value
902 fn add_one(x: int) -> int {
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 ## Comments
944
945 return
946
947 comments
948
949 ## Compound Data Types
950
951 Tuples
952
953 Structs
954
955 Enums
956
957 ## Match
958
959 ## Looping
960
961 for
962
963 while
964
965 loop
966
967 break/continue
968
969 ## Guessing Game: complete
970
971 At this point, you have successfully built the Guessing Game! Congratulations!
972 For reference, [We've placed the sample code on
973 GitHub](https://github.com/steveklabnik/guessing_game).
974
975 You've now learned the basic syntax of Rust. All of this is relatively close to
976 various other programming languages you have used in the past. These
977 fundamental syntactical and semantic elements will form the foundation for the
978 rest of your Rust education.
979
980 Now that you're an expert at the basics, it's time to learn about some of
981 Rust's more unique features.
982
983 ## iterators
984
985 ## Lambdas
986
987 ## Testing
988
989 attributes
990
991 stability markers
992
993 ## Crates and Modules
994
995 visibility
996
997
998 ## Generics
999
1000 ## Traits
1001
1002 ## Operators and built-in Traits
1003
1004 ## Ownership and Lifetimes
1005
1006 Move vs. Copy
1007
1008 Allocation
1009
1010 ## Tasks
1011
1012 ## Macros
1013
1014 ## Unsafe
1015