]> git.lizzy.rs Git - rust.git/blob - src/doc/guide.md
7ecfe7ce578ee2009c73975ffe28552f6713280b
[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`." Rust requires you to
519 initialize the binding with a value before you're allowed to use it. If
520 we try...
521
522 ```{ignore}
523 let x;
524 ```
525
526 ...we'll get an error:
527
528 ```{ignore}
529 src/guessing_game.rs:2:9: 2:10 error: cannot determine a type for this local variable: unconstrained type
530 src/guessing_game.rs:2     let x;
531                                ^
532 ```
533
534 Giving it a type will compile, though:
535
536 ```{ignore}
537 let x: int;
538 ```
539
540 Let's try it out. Change your `src/guessing_game.rs` file to look like this:
541
542 ```{rust}
543 fn main() {
544     let x: int;
545
546     println!("Hello world!");
547 }
548 ```
549
550 You can use `cargo build` on the command line to build it. You'll get a warning,
551 but it will still print "Hello, world!":
552
553 ```{ignore,notrust}
554    Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
555 src/guessing_game.rs:2:9: 2:10 warning: unused variable: `x`, #[warn(unused_variable)] on by default
556 src/guessing_game.rs:2     let x: int;
557                                ^
558 ```
559
560 Rust warns us that we never use the variable binding, but since we never use it,
561 no harm, no foul. Things change if we try to actually use this `x`, however. Let's
562 do that. Change your program to look like this:
563
564 ```{rust,ignore}
565 fn main() {
566     let x: int;
567
568     println!("The value of x is: {}", x);
569 }
570 ```
571
572 And try to build it. You'll get an error:
573
574 ```{bash}
575 $ cargo build
576    Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
577 src/guessing_game.rs:4:39: 4:40 error: use of possibly uninitialized variable: `x`
578 src/guessing_game.rs:4     println!("The value of x is: {}", x);
579                                                              ^
580 note: in expansion of format_args!
581 <std macros>:2:23: 2:77 note: expansion site
582 <std macros>:1:1: 3:2 note: in expansion of println!
583 src/guessing_game.rs:4:5: 4:42 note: expansion site
584 error: aborting due to previous error
585 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)
586 ```
587
588 Rust will not let us use a value that has not been initialized. So why let us
589 declare a binding without initializing it? You'd think our first example would
590 have errored. Well, Rust is smarter than that. Before we get to that, let's talk
591 about this stuff we've added to `println!`.
592
593 If you include two curly braces (`{}`, some call them moustaches...) in your
594 string to print, Rust will interpret this as a request to interpolate some sort
595 of value. **String interpolation** is a computer science term that means "stick
596 in the middle of a string." We add a comma, and then `x`, to indicate that we
597 want `x` to be the value we're interpolating. The comma is used to separate
598 arguments we pass to functions and macros, if you're passing more than one.
599
600 When you just use the double curly braces, Rust will attempt to display the
601 value in a meaningful way by checking out its type. If you want to specify the
602 format in a more detailed manner, there are a [wide number of options
603 available](/std/fmt/index.html). Fow now, we'll just stick to the default:
604 integers aren't very complicated to print.
605
606 So, we've cleared up all of the confusion around bindings, with one exception:
607 why does Rust let us declare a variable binding without an initial value if we
608 must initialize the binding before we use it? And how does it know that we have
609 or have not initialized the binding? For that, we need to learn our next
610 concept: `if`.
611
612 ## If
613
614 Rust's take on `if` is not particularly complex, but it's much more like the
615 `if` you'll find in a dynamically typed language than in a more traditional
616 systems language. So let's talk about it, to make sure you grasp the nuances.
617
618 `if` is a specific form of a more general concept, the 'branch.' The name comes
619 from a branch in a tree: a decision point, where depending on a choice,
620 multiple paths can be taken.
621
622 In the case of `if`, there is one choice that leads down two paths:
623
624 ```rust
625 let x = 5i;
626
627 if x == 5i {
628     println!("x is five!");
629 }
630 ```
631
632 If we changed the value of `x` to something else, this line would not print.
633 More specifically, if the expression after the `if` evaluates to `true`, then
634 the block is executed. If it's `false`, then it is not.
635
636 If you want something to happen in the `false` case, use an `else`:
637
638 ```
639 let x = 5i;
640
641 if x == 5i {
642     println!("x is five!");
643 } else {
644     println!("x is not five :(");
645 }
646 ```
647
648 This is all pretty standard. However, you can also do this:
649
650
651 ```
652 let x = 5i;
653
654 let y = if x == 5i {
655     10i
656 } else {
657     15i
658 };
659 ```
660
661 Which we can (and probably should) write like this:
662
663 ```
664 let x = 5i;
665
666 let y = if x == 5i { 10i } else { 15i };
667 ```
668
669 This reveals two interesting things about Rust: it is an expression-based
670 language, and semicolons are different than in other 'curly brace and
671 semicolon'-based languages. These two things are related.
672
673 ### Expressions vs. Statements
674
675 Rust is primarily an expression based language. There are only two kinds of
676 statements, and everything else is an expression.
677
678 So what's the difference? Expressions return a value, and statements do not.
679 In many languages, `if` is a statement, and therefore, `let x = if ...` would
680 make no sense. But in Rust, `if` is an expression, which means that it returns
681 a value. We can then use this value to initialize the binding.
682
683 Speaking of which, bindings are a kind of the first of Rust's two statements.
684 The proper name is a **declaration statement**. So far, `let` is the only kind
685 of declaration statement we've seen. Let's talk about that some more.
686
687 In some languages, variable bindings can be written as expressions, not just
688 statements. Like Ruby:
689
690 ```{ruby}
691 x = y = 5
692 ```
693
694 In Rust, however, using `let` to introduce a binding is _not_ an expression. The
695 following will produce a compile-time error:
696
697 ```{ignore}
698 let x = (let y = 5i); // found `let` in ident position
699 ```
700
701 The compiler is telling us here that it was expecting to see the beginning of
702 an expression, and a `let` can only begin a statement, not an expression.
703
704 However, re-assigning to a mutable binding is an expression:
705
706 ```{rust}
707 let mut x = 0i;
708 let y = x = 5i;
709 ```
710
711 In this case, we have an assignment expression (`x = 5`) whose value is
712 being used as part of a `let` declaration statement (`let y = ...`).
713
714 The second kind of statement in Rust is the **expression statement**. Its
715 purpose is to turn any expression into a statement. In practical terms, Rust's
716 grammar expects statements to follow other statements. This means that you use
717 semicolons to separate expressions from each other. This means that Rust
718 looks a lot like most other languages that require you to use semicolons
719 at the end of every line, and you will see semicolons at the end of almost
720 every line of Rust code you see.
721
722 What is this exception that makes us say 'almost?' You saw it already, in this
723 code:
724
725 ```
726 let x = 5i;
727
728 let y: int = if x == 5i { 10i } else { 15i };
729 ```
730
731 Note that I've added the type annotation to `y`, to specify explicitly that I
732 want `y` to be an integer.
733
734 This is not the same as this, which won't compile:
735
736 ```{ignore}
737 let x = 5i;
738
739 let y: int = if x == 5 { 10i; } else { 15i; };
740 ```
741
742 Note the semicolons after the 10 and 15. Rust will give us the following error:
743
744 ```{ignore,notrust}
745 error: mismatched types: expected `int` but found `()` (expected int but found ())
746 ```
747
748 We expected an integer, but we got `()`. `()` is pronounced 'unit', and is a
749 special type in Rust's type system. `()` is different than `null` in other
750 languages, because `()` is distinct from other types. For example, in C, `null`
751 is a valid value for a variable of type `int`. In Rust, `()` is _not_ a valid
752 value for a variable of type `int`. It's only a valid value for variables of
753 the type `()`, which aren't very useful. Remember how we said statements don't
754 return a value? Well, that's the purpose of unit in this case. The semicolon
755 turns any expression into a statement by throwing away its value and returning
756 unit instead.
757
758 There's one more time in which you won't see a semicolon at the end of a line
759 of Rust code. For that, we'll need our next concept: functions.
760
761 ## Functions
762
763 You've already seen one function so far, the `main` function:
764
765 ```{rust}
766 fn main() {
767 }
768 ```
769
770 This is the simplest possible function declaration. As we mentioned before,
771 `fn` says 'this is a function,' followed by the name, some parenthesis because
772 this function takes no arguments, and then some curly braces to indicate the
773 body. Here's a function named `foo`:
774
775 ```{rust}
776 fn foo() {
777 }
778 ```
779
780 So, what about taking arguments? Here's a function that prints a number:
781
782 ```{rust}
783 fn print_number(x: int) {
784     println!("x is: {}", x);
785 }
786 ```
787
788 Here's a complete program that uses `print_number`:
789
790 ```{rust}
791 fn main() {
792     print_number(5);
793 }
794
795 fn print_number(x: int) {
796     println!("x is: {}", x);
797 }
798 ```
799
800 As you can see, function arguments work very similar to `let` declarations:
801 you add a type to the argument name, after a colon.
802
803 Here's a complete program that adds two numbers together and prints them:
804
805 ```{rust}
806 fn main() {
807     print_sum(5, 6);
808 }
809
810 fn print_sum(x: int, y: int) {
811     println!("sum is: {}", x + y);
812 }
813 ```
814
815 You separate arguments with a comma, both when you call the function, as well
816 as when you declare it.
817
818 Unlike `let`, you _must_ declare the types of function arguments. This does
819 not work:
820
821 ```{ignore}
822 fn print_number(x, y) {
823     println!("x is: {}", x + y);
824 }
825 ```
826
827 You get this error:
828
829 ```{ignore,notrust}
830 hello.rs:5:18: 5:19 error: expected `:` but found `,`
831 hello.rs:5 fn print_number(x, y) {
832 ```
833
834 This is a deliberate design decision. While full-program inference is possible,
835 languages which have it, like Haskell, often suggest that documenting your
836 types explicitly is a best-practice. We agree that forcing functions to declare
837 types while allowing for inference inside of function bodies is a wonderful
838 compromise between full inference and no inference.
839
840 What about returning a value? Here's a function that adds one to an integer:
841
842 ```{rust}
843 fn add_one(x: int) -> int {
844     x + 1
845 }
846 ```
847
848 Rust functions return exactly one value, and you declare the type after an
849 'arrow', which is a dash (`-`) followed by a greater-than sign (`>`).
850
851 You'll note the lack of a semicolon here. If we added it in:
852
853 ```{ignore}
854 fn add_one(x: int) -> int {
855     x + 1;
856 }
857 ```
858
859 We would get an error:
860
861 ```{ignore,notrust}
862 note: consider removing this semicolon:
863      x + 1;
864           ^
865 error: not all control paths return a value
866 fn add_one(x: int) -> int {
867      x + 1;
868 }
869 ```
870
871 Remember our earlier discussions about semicolons and `()`? Our function claims
872 to return an `int`, but with a semicolon, it would return `()` instead. Rust
873 realizes this probably isn't what we want, and suggests removing the semicolon.
874
875 This is very much like our `if` statement before: the result of the block
876 (`{}`) is the value of the expression. Other expression-oriented languages,
877 such as Ruby, work like this, but it's a bit unusual in the systems programming
878 world. When people first learn about this, they usually assume that it
879 introduces bugs. But because Rust's type system is so strong, and because unit
880 is its own unique type, we have never seen an issue where adding or removing a
881 semicolon in a return position would cause a bug.
882
883 But what about early returns? Rust does have a keyword for that, `return`:
884
885 ```{rust}
886 fn foo(x: int) -> int {
887     if x < 5 { return x; }
888
889     x + 1
890 }
891 ```
892
893 Using a `return` as the last line of a function works, but is considered poor
894 style:
895
896 ```{rust}
897 fn foo(x: int) -> int {
898     if x < 5 { return x; }
899
900     return x + 1;
901 }
902 ```
903
904 There are some additional ways to define functions, but they involve features
905 that we haven't learned about yet, so let's just leave it at that for now.
906
907 ## Comments
908
909 return
910
911 comments
912
913 ## Compound Data Types
914
915 Tuples
916
917 Structs
918
919 Enums
920
921 ## Match
922
923 ## Looping
924
925 for
926
927 while
928
929 loop
930
931 break/continue
932
933 ## Guessing Game: complete
934
935 At this point, you have successfully built the Guessing Game! Congratulations!
936 For reference, [We've placed the sample code on
937 GitHub](https://github.com/steveklabnik/guessing_game).
938
939 You've now learned the basic syntax of Rust. All of this is relatively close to
940 various other programming languages you have used in the past. These
941 fundamental syntactical and semantic elements will form the foundation for the
942 rest of your Rust education.
943
944 Now that you're an expert at the basics, it's time to learn about some of
945 Rust's more unique features.
946
947 ## iterators
948
949 ## Lambdas
950
951 ## Testing
952
953 attributes
954
955 stability markers
956
957 ## Crates and Modules
958
959 visibility
960
961
962 ## Generics
963
964 ## Traits
965
966 ## Operators and built-in Traits
967
968 ## Ownership and Lifetimes
969
970 Move vs. Copy
971
972 Allocation
973
974 ## Tasks
975
976 ## Macros
977
978 ## Unsafe
979