3 Hey there! Welcome to the Rust guide. This is the place to be if you'd like to
4 learn how to program in Rust. Rust is a systems programming language with a
5 focus on "high-level, bare-metal programming": the lowest level control a
6 programming language can give you, but with zero-cost, higher level
7 abstractions, because people aren't computers. We really think Rust is
8 something special, and we hope you do too.
10 To show you how to get going with Rust, we're going to write the traditional
11 "Hello, World!" program. Next, we'll introduce you to a tool that's useful for
12 writing real-world Rust programs and libraries: "Cargo." After that, we'll talk
13 about the basics of Rust, write a little program to try them out, and then learn
20 The first step to using Rust is to install it! There are a number of ways to
21 install Rust, but the easiest is to use the `rustup` script. If you're on
22 Linux or a Mac, all you need to do is this (note that you don't need to type
23 in the `$`s, they just indicate the start of each command):
26 curl -L https://static.rust-lang.org/rustup.sh | sudo sh
29 If you're concerned about the [potential insecurity](http://curlpipesh.tumblr.com/) of using `curl | sudo sh`,
30 please keep reading and see our disclaimer below. And feel free to use a two-step version of the installation and examine our installation script:
33 curl -L https://static.rust-lang.org/rustup.sh -O
37 If you're on Windows, please download either the [32-bit
38 installer](https://static.rust-lang.org/dist/rust-nightly-i686-pc-windows-gnu.exe)
40 installer](https://static.rust-lang.org/dist/rust-nightly-x86_64-pc-windows-gnu.exe)
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
48 $ curl -s https://static.rust-lang.org/rustup.sh | sudo sh -s -- --uninstall
51 If you used the Windows installer, just re-run the `.exe` and it will give you
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
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.
68 Oh, we should also mention the officially supported platforms:
70 * Windows (7, 8, Server 2008 R2)
71 * Linux (2.6.18 or later, various distributions), x86 and x86-64
72 * OSX 10.7 (Lion) or greater, x86 and x86-64
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
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.
84 If you've got Rust installed, you can open up a shell, and type this:
90 You should see some output that looks something like this:
93 rustc 0.12.0-nightly (b7aa03a3c 2014-09-28 11:38:01 +0000)
96 If you did, Rust has been installed successfully! Congrats!
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 forum](http://discuss.rust-lang.org/), [the /r/rust
105 subreddit](http://www.reddit.com/r/rust), and [Stack
106 Overflow](http://stackoverflow.com/questions/tagged/rust).
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
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.
121 This actually leads to one other concern we should address: this guide 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.
127 With that said, let's make a directory in our projects directory.
136 If you're on Windows and not using PowerShell, the `~` may not work. Consult
137 the documentation for your shell for more details.
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 `main.rs`:
147 Rust files always end in a `.rs` extension. If you're using more than one word
148 in your filename, use an underscore. `hello_world.rs` rather than
151 Now that you've got your file open, type this in:
155 println!("Hello, world!");
159 Save the file, and then type this into your terminal window:
163 $ ./main # or main.exe on Windows
167 You can also run these examples on [play.rust-lang.org](http://play.rust-lang.org/) by clicking on the arrow that appears in the upper right of the example when you mouse over the code.
169 Success! Let's go over what just happened in detail.
177 These lines define a **function** in Rust. The `main` function is special:
178 it's the beginning of every Rust program. The first line says "I'm declaring a
179 function named `main`, which takes no arguments and returns nothing." If there
180 were arguments, they would go inside the parentheses (`(` and `)`), and because
181 we aren't returning anything from this function, we've dropped that notation
182 entirely. We'll get to it later.
184 You'll also note that the function is wrapped in curly braces (`{` and `}`).
185 Rust requires these around all function bodies. It is also considered good
186 style to put the opening curly brace on the same line as the function
187 declaration, with one space in between.
189 Next up is this line:
192 println!("Hello, world!");
195 This line does all of the work in our little program. There are a number of
196 details that are important here. The first is that it's indented with four
197 spaces, not tabs. Please configure your editor of choice to insert four spaces
198 with the tab key. We provide some [sample configurations for various
199 editors](https://github.com/rust-lang/rust/tree/master/src/etc).
201 The second point is the `println!()` part. This is calling a Rust **macro**,
202 which is how metaprogramming is done in Rust. If it were a function instead, it
203 would look like this: `println()`. For our purposes, we don't need to worry
204 about this difference. Just know that sometimes, you'll see a `!`, and that
205 means that you're calling a macro instead of a normal function. Rust implements
206 `println!` as a macro rather than a function for good reasons, but that's a
207 very advanced topic. You'll learn more when we talk about macros later. One
208 last thing to mention: Rust's macros are significantly different from C macros,
209 if you've used those. Don't be scared of using macros. We'll get to the details
210 eventually, you'll just have to trust us for now.
212 Next, `"Hello, world!"` is a **string**. Strings are a surprisingly complicated
213 topic in a systems programming language, and this is a **statically allocated**
214 string. We will talk more about different kinds of allocation later. We pass
215 this string as an argument to `println!`, which prints the string to the
218 Finally, the line ends with a semicolon (`;`). Rust is an **expression
219 oriented** language, which means that most things are expressions. The `;` is
220 used to indicate that this expression is over, and the next one is ready to
221 begin. Most lines of Rust code end with a `;`. We will cover this in-depth
224 Finally, actually **compiling** and **running** our program. We can compile
225 with our compiler, `rustc`, by passing it the name of our source file:
231 This is similar to `gcc` or `clang`, if you come from a C or C++ background. Rust
232 will output a binary executable. You can see it with `ls`:
246 There are now two files: our source code, with the `.rs` extension, and the
247 executable (`main.exe` on Windows, `main` everywhere else)
250 $ ./main # or main.exe on Windows
253 This prints out our `Hello, world!` text to our terminal.
255 If you come from a dynamically typed language like Ruby, Python, or JavaScript,
256 you may not be used to these two steps being separate. Rust is an
257 **ahead-of-time compiled language**, which means that you can compile a
258 program, give it to someone else, and they don't need to have Rust installed.
259 If you give someone a `.rb` or `.py` or `.js` file, they need to have
260 Ruby/Python/JavaScript installed, but you just need one command to both compile
261 and run your program. Everything is a tradeoff in language design, and Rust has
264 Congratulations! You have officially written a Rust program. That makes you a
265 Rust programmer! Welcome.
267 Next, I'd like to introduce you to another tool, Cargo, which is used to write
268 real-world Rust programs. Just using `rustc` is nice for simple things, but as
269 your project grows, you'll want something to help you manage all of the options
270 that it has, and to make it easy to share your code with other people and
275 [Cargo](http://crates.io) is a tool that Rustaceans use to help manage their
276 Rust projects. Cargo is currently in an alpha state, just like Rust, and so it
277 is still a work in progress. However, it is already good enough to use for many
278 Rust projects, and so it is assumed that Rust projects will use Cargo from the
281 Cargo manages three things: building your code, downloading the dependencies
282 your code needs, and building the dependencies your code needs. At first, your
283 program doesn't have any dependencies, so we'll only be using the first part of
284 its functionality. Eventually, we'll add more. Since we started off by using
285 Cargo, it'll be easy to add later.
287 If you installed Rust via the official installers you will also have
288 Cargo. If you installed Rust some other way, you may want to [check
290 README](https://github.com/rust-lang/cargo#installing-cargo-from-nightlies)
291 for specific instructions about installing it.
293 Let's convert Hello World to Cargo.
295 To Cargo-ify our project, we need to do two things: Make a `Cargo.toml`
296 configuration file, and put our source file in the right place. Let's
301 $ mv main.rs src/main.rs
304 Cargo expects your source files to live inside a `src` directory. That leaves
305 the top level for other things, like READMEs, license information, and anything
306 not related to your code. Cargo helps us keep our projects nice and tidy. A
307 place for everything, and everything in its place.
309 Next, our configuration file:
315 Make sure to get this name right: you need the capital `C`!
324 authors = [ "Your name <you@example.com>" ]
331 This file is in the [TOML](https://github.com/toml-lang/toml) format. Let's let
332 it explain itself to you:
334 > TOML aims to be a minimal configuration file format that's easy to read due
335 > to obvious semantics. TOML is designed to map unambiguously to a hash table.
336 > TOML should be easy to parse into data structures in a wide variety of
339 TOML is very similar to INI, but with some extra goodies.
341 Anyway, there are two **table**s in this file: `package` and `bin`. The first
342 tells Cargo metadata about your package. The second tells Cargo that we're
343 interested in building a binary, not a library (though we could do both!), as
344 well as what it is named.
346 Once you have this file in place, we should be ready to build! Try this:
350 Compiling hello_world v0.0.1 (file:///home/yourname/projects/hello_world)
351 $ ./target/hello_world
355 Bam! We build our project with `cargo build`, and run it with
356 `./target/hello_world`. This hasn't bought us a whole lot over our simple use
357 of `rustc`, but think about the future: when our project has more than one
358 file, we would need to call `rustc` twice, and pass it a bunch of options to
359 tell it to build everything together. With Cargo, as our project grows, we can
360 just `cargo build` and it'll work the right way.
362 You'll also notice that Cargo has created a new file: `Cargo.lock`.
370 This file is used by Cargo to keep track of dependencies in your application.
371 Right now, we don't have any, so it's a bit sparse. You won't ever need
372 to touch this file yourself, just let Cargo handle it.
374 That's it! We've successfully built `hello_world` with Cargo. Even though our
375 program is simple, it's using much of the real tooling that you'll use for the
376 rest of your Rust career.
378 Now that you've got the tools down, let's actually learn more about the Rust
379 language itself. These are the basics that will serve you well through the rest
380 of your time with Rust.
384 The first thing we'll learn about are 'variable bindings.' They look like this:
392 Putting `fn main() {` in each example is a bit tedious, so we'll leave that out
393 in the future. If you're following along, make sure to edit your `main()`
394 function, rather than leaving it off. Otherwise, you'll get an error.
396 In many languages, this is called a 'variable.' But Rust's variable bindings
397 have a few tricks up their sleeves. Rust has a very powerful feature called
398 'pattern matching' that we'll get into detail with later, but the left
399 hand side of a `let` expression is a full pattern, not just a variable name.
400 This means we can do things like:
406 After this expression is evaluated, `x` will be one, and `y` will be two.
407 Patterns are really powerful, but this is about all we can do with them so far.
408 So let's just keep this in the back of our minds as we go forward.
410 Rust is a statically typed language, which means that we specify our types up
411 front. So why does our first example compile? Well, Rust has this thing called
412 "type inference." If it can figure out what the type of something is, Rust
413 doesn't require you to actually type it out.
415 We can add the type if we want to, though. Types come after a colon (`:`):
421 If I asked you to read this out loud to the rest of the class, you'd say "`x`
422 is a binding with the type `i32` and the value `five`."
424 In future examples, we may annotate the type in a comment. The examples will
433 Note the similarities between this annotation and the syntax you use with `let`.
434 Including these kinds of comments is not idiomatic Rust, but we'll occasionally
435 include them to help you understand what the types that Rust infers are.
437 By default, bindings are **immutable**. This code will not compile:
444 It will give you this error:
447 error: re-assignment of immutable variable `x`
452 If you want a binding to be mutable, you can use `mut`:
455 let mut x = 5; // mut x: i32
459 There is no single reason that bindings are immutable by default, but we can
460 think about it through one of Rust's primary focuses: safety. If you forget to
461 say `mut`, the compiler will catch it, and let you know that you have mutated
462 something you may not have intended to mutate. If bindings were mutable by
463 default, the compiler would not be able to tell you this. If you _did_ intend
464 mutation, then the solution is quite easy: add `mut`.
466 There are other good reasons to avoid mutable state when possible, but they're
467 out of the scope of this guide. In general, you can often avoid explicit
468 mutation, and so it is preferable in Rust. That said, sometimes, mutation is
469 what you need, so it's not verboten.
471 Let's get back to bindings. Rust variable bindings have one more aspect that
472 differs from other languages: bindings are required to be initialized with a
473 value before you're allowed to use them. If we try...
479 ...we'll get an error:
482 src/main.rs:2:9: 2:10 error: cannot determine a type for this local variable: unconstrained type
487 Giving it a type will compile, though:
493 Let's try it out. Change your `src/main.rs` file to look like this:
499 println!("Hello world!");
503 You can use `cargo build` on the command line to build it. You'll get a warning,
504 but it will still print "Hello, world!":
507 Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world)
508 src/main.rs:2:9: 2:10 warning: unused variable: `x`, #[warn(unused_variable)] on by default
509 src/main.rs:2 let x: i32;
513 Rust warns us that we never use the variable binding, but since we never use it,
514 no harm, no foul. Things change if we try to actually use this `x`, however. Let's
515 do that. Change your program to look like this:
521 println!("The value of x is: {}", x);
525 And try to build it. You'll get an error:
529 Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world)
530 src/main.rs:4:39: 4:40 error: use of possibly uninitialized variable: `x`
531 src/main.rs:4 println!("The value of x is: {}", x);
533 note: in expansion of format_args!
534 <std macros>:2:23: 2:77 note: expansion site
535 <std macros>:1:1: 3:2 note: in expansion of println!
536 src/main.rs:4:5: 4:42 note: expansion site
537 error: aborting due to previous error
538 Could not compile `hello_world`.
541 Rust will not let us use a value that has not been initialized. Next, let's
542 talk about this stuff we've added to `println!`.
544 If you include two curly braces (`{}`, some call them moustaches...) in your
545 string to print, Rust will interpret this as a request to interpolate some sort
546 of value. **String interpolation** is a computer science term that means "stick
547 in the middle of a string." We add a comma, and then `x`, to indicate that we
548 want `x` to be the value we're interpolating. The comma is used to separate
549 arguments we pass to functions and macros, if you're passing more than one.
551 When you just use the curly braces, Rust will attempt to display the
552 value in a meaningful way by checking out its type. If you want to specify the
553 format in a more detailed manner, there are a [wide number of options
554 available](std/fmt/index.html). For now, we'll just stick to the default:
555 integers aren't very complicated to print.
559 Rust's take on `if` is not particularly complex, but it's much more like the
560 `if` you'll find in a dynamically typed language than in a more traditional
561 systems language. So let's talk about it, to make sure you grasp the nuances.
563 `if` is a specific form of a more general concept, the 'branch.' The name comes
564 from a branch in a tree: a decision point, where depending on a choice,
565 multiple paths can be taken.
567 In the case of `if`, there is one choice that leads down two paths:
573 println!("x is five!");
577 If we changed the value of `x` to something else, this line would not print.
578 More specifically, if the expression after the `if` evaluates to `true`, then
579 the block is executed. If it's `false`, then it is not.
581 If you want something to happen in the `false` case, use an `else`:
587 println!("x is five!");
589 println!("x is not five :(");
593 This is all pretty standard. However, you can also do this:
606 Which we can (and probably should) write like this:
611 let y = if x == 5 { 10 } else { 15 }; // y: i32
614 This reveals two interesting things about Rust: it is an expression-based
615 language, and semicolons are different from semicolons in other 'curly brace
616 and semicolon'-based languages. These two things are related.
618 ## Expressions vs. Statements
620 Rust is primarily an expression based language. There are only two kinds of
621 statements, and everything else is an expression.
623 So what's the difference? Expressions return a value, and statements do not.
624 In many languages, `if` is a statement, and therefore, `let x = if ...` would
625 make no sense. But in Rust, `if` is an expression, which means that it returns
626 a value. We can then use this value to initialize the binding.
628 Speaking of which, bindings are a kind of the first of Rust's two statements.
629 The proper name is a **declaration statement**. So far, `let` is the only kind
630 of declaration statement we've seen. Let's talk about that some more.
632 In some languages, variable bindings can be written as expressions, not just
633 statements. Like Ruby:
639 In Rust, however, using `let` to introduce a binding is _not_ an expression. The
640 following will produce a compile-time error:
643 let x = (let y = 5); // expected identifier, found keyword `let`
646 The compiler is telling us here that it was expecting to see the beginning of
647 an expression, and a `let` can only begin a statement, not an expression.
649 Note that assigning to an already-bound variable (e.g. `y = 5`) is still an
650 expression, although its value is not particularly useful. Unlike C, where an
651 assignment evaluates to the assigned value (e.g. `5` in the previous example),
652 in Rust the value of an assignment is the unit type `()` (which we'll cover later).
654 The second kind of statement in Rust is the **expression statement**. Its
655 purpose is to turn any expression into a statement. In practical terms, Rust's
656 grammar expects statements to follow other statements. This means that you use
657 semicolons to separate expressions from each other. This means that Rust
658 looks a lot like most other languages that require you to use semicolons
659 at the end of every line, and you will see semicolons at the end of almost
660 every line of Rust code you see.
662 What is this exception that makes us say 'almost?' You saw it already, in this
668 let y: i32 = if x == 5 { 10 } else { 15 };
671 Note that I've added the type annotation to `y`, to specify explicitly that I
672 want `y` to be an integer.
674 This is not the same as this, which won't compile:
679 let y: i32 = if x == 5 { 10; } else { 15; };
682 Note the semicolons after the 10 and 15. Rust will give us the following error:
685 error: mismatched types: expected `i32` but found `()` (expected i32 but found ())
688 We expected an integer, but we got `()`. `()` is pronounced 'unit', and is a
689 special type in Rust's type system. In Rust, `()` is _not_ a valid value for a
690 variable of type `i32`. It's only a valid value for variables of the type `()`,
691 which aren't very useful. Remember how we said statements don't return a value?
692 Well, that's the purpose of unit in this case. The semicolon turns any
693 expression into a statement by throwing away its value and returning unit
696 There's one more time in which you won't see a semicolon at the end of a line
697 of Rust code. For that, we'll need our next concept: functions.
701 You've already seen one function so far, the `main` function:
708 This is the simplest possible function declaration. As we mentioned before,
709 `fn` says 'this is a function,' followed by the name, some parentheses because
710 this function takes no arguments, and then some curly braces to indicate the
711 body. Here's a function named `foo`:
718 So, what about taking arguments? Here's a function that prints a number:
721 fn print_number(x: i32) {
722 println!("x is: {}", x);
726 Here's a complete program that uses `print_number`:
733 fn print_number(x: i32) {
734 println!("x is: {}", x);
738 As you can see, function arguments work very similar to `let` declarations:
739 you add a type to the argument name, after a colon.
741 Here's a complete program that adds two numbers together and prints them:
748 fn print_sum(x: i32, y: i32) {
749 println!("sum is: {}", x + y);
753 You separate arguments with a comma, both when you call the function, as well
754 as when you declare it.
756 Unlike `let`, you _must_ declare the types of function arguments. This does
760 fn print_number(x, y) {
761 println!("x is: {}", x + y);
768 hello.rs:5:18: 5:19 error: expected `:` but found `,`
769 hello.rs:5 fn print_number(x, y) {
772 This is a deliberate design decision. While full-program inference is possible,
773 languages which have it, like Haskell, often suggest that documenting your
774 types explicitly is a best-practice. We agree that forcing functions to declare
775 types while allowing for inference inside of function bodies is a wonderful
776 sweet spot between full inference and no inference.
778 What about returning a value? Here's a function that adds one to an integer:
781 fn add_one(x: i32) -> i32 {
786 Rust functions return exactly one value, and you declare the type after an
787 'arrow', which is a dash (`-`) followed by a greater-than sign (`>`).
789 You'll note the lack of a semicolon here. If we added it in:
792 fn add_one(x: i32) -> i32 {
797 We would get an error:
800 error: not all control paths return a value
801 fn add_one(x: i32) -> i32 {
805 help: consider removing this semicolon:
810 Remember our earlier discussions about semicolons and `()`? Our function claims
811 to return an `i32`, but with a semicolon, it would return `()` instead. Rust
812 realizes this probably isn't what we want, and suggests removing the semicolon.
814 This is very much like our `if` statement before: the result of the block
815 (`{}`) is the value of the expression. Other expression-oriented languages,
816 such as Ruby, work like this, but it's a bit unusual in the systems programming
817 world. When people first learn about this, they usually assume that it
818 introduces bugs. But because Rust's type system is so strong, and because unit
819 is its own unique type, we have never seen an issue where adding or removing a
820 semicolon in a return position would cause a bug.
822 But what about early returns? Rust does have a keyword for that, `return`:
825 fn foo(x: i32) -> i32 {
826 if x < 5 { return x; }
832 Using a `return` as the last line of a function works, but is considered poor
836 fn foo(x: i32) -> i32 {
837 if x < 5 { return x; }
843 There are some additional ways to define functions, but they involve features
844 that we haven't learned about yet, so let's just leave it at that for now.
849 Now that we have some functions, it's a good idea to learn about comments.
850 Comments are notes that you leave to other programmers to help explain things
851 about your code. The compiler mostly ignores them.
853 Rust has two kinds of comments that you should care about: **line comment**s
854 and **doc comment**s.
857 // Line comments are anything after '//' and extend to the end of the line.
859 let x = 5; // this is also a line comment.
861 // If you have a long explanation for something, you can put line comments next
862 // to each other. Put a space between the // and your comment so that it's
866 The other kind of comment is a doc comment. Doc comments use `///` instead of
867 `//`, and support Markdown notation inside:
870 /// `hello` is a function that prints a greeting that is personalized based on
875 /// * `name` - The name of the person you'd like to greet.
880 /// let name = "Steve";
881 /// hello(name); // prints "Hello, Steve!"
883 fn hello(name: &str) {
884 println!("Hello, {}!", name);
888 When writing doc comments, adding sections for any arguments, return values,
889 and providing some examples of usage is very, very helpful.
891 You can use the [`rustdoc`](rustdoc.html) tool to generate HTML documentation
892 from these doc comments.
894 # Compound Data Types
896 Rust, like many programming languages, has a number of different data types
897 that are built-in. You've already done some simple work with integers and
898 strings, but next, let's talk about some more complicated ways of storing data.
902 The first compound data type we're going to talk about are called **tuple**s.
903 Tuples are an ordered list of a fixed size. Like this:
906 let x = (1, "hello");
909 The parentheses and commas form this two-length tuple. Here's the same code, but
910 with the type annotated:
913 let x: (i32, &str) = (1, "hello");
916 As you can see, the type of a tuple looks just like the tuple, but with each
917 position having a type name rather than the value. Careful readers will also
918 note that tuples are heterogeneous: we have an `i32` and a `&str` in this tuple.
919 You haven't seen `&str` as a type before, and we'll discuss the details of
920 strings later. In systems programming languages, strings are a bit more complex
921 than in other languages. For now, just read `&str` as "a string slice," and
922 we'll learn more soon.
924 You can access the fields in a tuple through a **destructuring let**. Here's
928 let (x, y, z) = (1, 2, 3);
930 println!("x is {}", x);
933 Remember before when I said the left-hand side of a `let` statement was more
934 powerful than just assigning a binding? Here we are. We can put a pattern on
935 the left-hand side of the `let`, and if it matches up to the right-hand side,
936 we can assign multiple bindings at once. In this case, `let` 'destructures,'
937 or 'breaks up,' the tuple, and assigns the bits to three bindings.
939 This pattern is very powerful, and we'll see it repeated more later.
941 There are also a few things you can do with a tuple as a whole, without
942 destructuring. You can assign one tuple into another, if they have the same
943 arity and contained types.
946 let mut x = (1, 2); // x: (i32, i32)
947 let y = (2, 3); // y: (i32, i32)
952 You can also check for equality with `==`. Again, this will only compile if the
953 tuples have the same type.
966 This will print `no`, because some of the values aren't equal.
968 One other use of tuples is to return multiple values from a function:
971 fn next_two(x: i32) -> (i32, i32) { (x + 1, x + 2) }
974 let (x, y) = next_two(5);
975 println!("x, y = {}, {}", x, y);
979 Even though Rust functions can only return one value, a tuple _is_ one value,
980 that happens to be made up of two. You can also see in this example how you
981 can destructure a pattern returned by a function, as well.
983 Tuples are a very simple data structure, and so are not often what you want.
984 Let's move on to their bigger sibling, structs.
988 A struct is another form of a 'record type,' just like a tuple. There's a
989 difference: structs give each element that they contain a name, called a
990 'field' or a 'member.' Check it out:
999 let origin = Point { x: 0, y: 0 }; // origin: Point
1001 println!("The origin is at ({}, {})", origin.x, origin.y);
1005 There's a lot going on here, so let's break it down. We declare a struct with
1006 the `struct` keyword, and then with a name. By convention, structs begin with a
1007 capital letter and are also camel cased: `PointInSpace`, not `Point_In_Space`.
1009 We can create an instance of our struct via `let`, as usual, but we use a `key:
1010 value` style syntax to set each field. The order doesn't need to be the same as
1011 in the original declaration.
1013 Finally, because fields have names, we can access the field through dot
1014 notation: `origin.x`.
1016 The values in structs are immutable by default, like other bindings in Rust.
1017 Use `mut` to make them mutable:
1026 let mut point = Point { x: 0, y: 0 };
1030 println!("The point is at ({}, {})", point.x, point.y);
1034 This will print `The point is at (5, 0)`.
1036 ## Tuple Structs and Newtypes
1038 Rust has another data type that's like a hybrid between a tuple and a struct,
1039 called a **tuple struct**. Tuple structs do have a name, but their fields
1044 struct Color(i32, i32, i32);
1045 struct Point(i32, i32, i32);
1048 These two will not be equal, even if they have the same values:
1051 # struct Color(i32, i32, i32);
1052 # struct Point(i32, i32, i32);
1053 let black = Color(0, 0, 0);
1054 let origin = Point(0, 0, 0);
1057 It is almost always better to use a struct than a tuple struct. We would write
1058 `Color` and `Point` like this instead:
1074 Now, we have actual names, rather than positions. Good names are important,
1075 and with a struct, we have actual names.
1077 There _is_ one case when a tuple struct is very useful, though, and that's a
1078 tuple struct with only one element. We call this a 'newtype,' because it lets
1079 you create a new type that's a synonym for another one:
1084 let length = Inches(10);
1086 let Inches(integer_length) = length;
1087 println!("length is {} inches", integer_length);
1090 As you can see here, you can extract the inner integer type through a
1091 destructuring `let`.
1095 Finally, Rust has a "sum type", an **enum**. Enums are an incredibly useful
1096 feature of Rust, and are used throughout the standard library. This is an enum
1097 that is provided by the Rust standard library:
1107 An `Ordering` can only be _one_ of `Less`, `Equal`, or `Greater` at any given
1110 Because `Ordering` is provided by the standard library, we can use the `use`
1111 keyword to use it in our code. We'll learn more about `use` later, but it's
1112 used to bring names into scope.
1114 Here's an example of how to use `Ordering`:
1117 use std::cmp::Ordering;
1119 fn cmp(a: i32, b: i32) -> Ordering {
1120 if a < b { Ordering::Less }
1121 else if a > b { Ordering::Greater }
1122 else { Ordering::Equal }
1129 let ordering = cmp(x, y); // ordering: Ordering
1131 if ordering == Ordering::Less {
1133 } else if ordering == Ordering::Greater {
1134 println!("greater");
1135 } else if ordering == Ordering::Equal {
1141 There's a symbol here we haven't seen before: the double colon (`::`).
1142 This is used to indicate a namespace. In this case, `Ordering` lives in
1143 the `cmp` submodule of the `std` module. We'll talk more about modules
1144 later in the guide. For now, all you need to know is that you can `use`
1145 things from the standard library if you need them.
1147 Okay, let's talk about the actual code in the example. `cmp` is a function that
1148 compares two things, and returns an `Ordering`. We return either
1149 `Ordering::Less`, `Ordering::Greater`, or `Ordering::Equal`, depending on if
1150 the two values are greater, less, or equal. Note that each variant of the
1151 `enum` is namespaced under the `enum` itself: it's `Ordering::Greater` not
1154 The `ordering` variable has the type `Ordering`, and so contains one of the
1155 three values. We can then do a bunch of `if`/`else` comparisons to check which
1156 one it is. However, repeated `if`/`else` comparisons get quite tedious. Rust
1157 has a feature that not only makes them nicer to read, but also makes sure that
1158 you never miss a case. Before we get to that, though, let's talk about another
1159 kind of enum: one with values.
1161 This enum has two variants, one of which has a value:
1170 This enum represents an `i32` that we may or may not have. In the `Missing`
1171 case, we have no value, but in the `Value` case, we do. This enum is specific
1172 to `i32`s, though. We can make it usable by any type, but we haven't quite
1175 You can also have any number of values in an enum:
1178 enum OptionalColor {
1179 Color(i32, i32, i32),
1184 And you can also have something like this:
1189 ErrorReason(String),
1192 Where a `StringResult` is either a `StringResult::StringOK`, with the result of
1193 a computation, or an `StringResult::ErrorReason` with a `String` explaining
1194 what caused the computation to fail. These kinds of `enum`s are actually very
1195 useful and are even part of the standard library.
1197 Here is an example of using our `StringResult`:
1202 ErrorReason(String),
1205 fn respond(greeting: &str) -> StringResult {
1206 if greeting == "Hello" {
1207 StringResult::StringOK("Good morning!".to_string())
1209 StringResult::ErrorReason("I didn't understand you!".to_string())
1214 That's a lot of typing! We can use the `use` keyword to make it shorter:
1217 use StringResult::StringOK;
1218 use StringResult::ErrorReason;
1222 ErrorReason(String),
1227 fn respond(greeting: &str) -> StringResult {
1228 if greeting == "Hello" {
1229 StringOK("Good morning!".to_string())
1231 ErrorReason("I didn't understand you!".to_string())
1236 `use` declarations must come before anything else, which looks a little strange in this example,
1237 since we `use` the variants before we define them. Anyway, in the body of `respond`, we can just
1238 say `StringOK` now, rather than the full `StringResult::StringOK`. Importing variants can be
1239 convenient, but can also cause name conflicts, so do this with caution. It's considered good style
1240 to rarely import variants for this reason.
1242 As you can see, `enum`s with values are quite a powerful tool for data representation,
1243 and can be even more useful when they're generic across types. Before we get to generics,
1244 though, let's talk about how to use them with pattern matching, a tool that will
1245 let us deconstruct this sum type (the type theory term for enums) in a very elegant
1246 way and avoid all these messy `if`/`else`s.
1250 Often, a simple `if`/`else` isn't enough, because you have more than two
1251 possible options. Also, `else` conditions can get incredibly complicated, so
1252 what's the solution?
1254 Rust has a keyword, `match`, that allows you to replace complicated `if`/`else`
1255 groupings with something more powerful. Check it out:
1261 1 => println!("one"),
1262 2 => println!("two"),
1263 3 => println!("three"),
1264 4 => println!("four"),
1265 5 => println!("five"),
1266 _ => println!("something else"),
1270 `match` takes an expression and then branches based on its value. Each 'arm' of
1271 the branch is of the form `val => expression`. When the value matches, that arm's
1272 expression will be evaluated. It's called `match` because of the term 'pattern
1273 matching', which `match` is an implementation of.
1275 So what's the big advantage here? Well, there are a few. First of all, `match`
1276 enforces 'exhaustiveness checking'. Do you see that last arm, the one with the
1277 underscore (`_`)? If we remove that arm, Rust will give us an error:
1280 error: non-exhaustive patterns: `_` not covered
1283 In other words, Rust is trying to tell us we forgot a value. Because `x` is an
1284 integer, Rust knows that it can have a number of different values – for example,
1285 `6`. Without the `_`, however, there is no arm that could match, and so Rust refuses
1286 to compile. `_` acts like a 'catch-all arm'. If none of the other arms match,
1287 the arm with `_` will, and since we have this catch-all arm, we now have an arm
1288 for every possible value of `x`, and so our program will compile successfully.
1290 `match` statements also destructure enums, as well. Remember this code from the
1294 use std::cmp::Ordering;
1296 fn cmp(a: i32, b: i32) -> Ordering {
1297 if a < b { Ordering::Less }
1298 else if a > b { Ordering::Greater }
1299 else { Ordering::Equal }
1306 let ordering = cmp(x, y);
1308 if ordering == Ordering::Less {
1310 } else if ordering == Ordering::Greater {
1311 println!("greater");
1312 } else if ordering == Ordering::Equal {
1318 We can re-write this as a `match`:
1321 use std::cmp::Ordering;
1323 fn cmp(a: i32, b: i32) -> Ordering {
1324 if a < b { Ordering::Less }
1325 else if a > b { Ordering::Greater }
1326 else { Ordering::Equal }
1334 Ordering::Less => println!("less"),
1335 Ordering::Greater => println!("greater"),
1336 Ordering::Equal => println!("equal"),
1341 This version has way less noise, and it also checks exhaustively to make sure
1342 that we have covered all possible variants of `Ordering`. With our `if`/`else`
1343 version, if we had forgotten the `Greater` case, for example, our program would
1344 have happily compiled. If we forget in the `match`, it will not. Rust helps us
1345 make sure to cover all of our bases.
1347 `match` expressions also allow us to get the values contained in an `enum`
1348 (also known as destructuring) as follows:
1357 let x = OptionalInt::Value(5);
1358 let y = OptionalInt::Missing;
1361 OptionalInt::Value(n) => println!("x is {}", n),
1362 OptionalInt::Missing => println!("x is missing!"),
1366 OptionalInt::Value(n) => println!("y is {}", n),
1367 OptionalInt::Missing => println!("y is missing!"),
1372 That is how you can get and use the values contained in `enum`s.
1373 It can also allow us to handle errors or unexpected computations; for example, a
1374 function that is not guaranteed to be able to compute a result (an `i32` here)
1375 could return an `OptionalInt`, and we would handle that value with a `match`.
1376 As you can see, `enum` and `match` used together are quite useful!
1378 `match` is also an expression, which means we can use it on the right-hand
1379 side of a `let` binding or directly where an expression is used. We could
1380 also implement the previous line like this:
1383 use std::cmp::Ordering;
1385 fn cmp(a: i32, b: i32) -> Ordering {
1386 if a < b { Ordering::Less }
1387 else if a > b { Ordering::Greater }
1388 else { Ordering::Equal }
1395 println!("{}", match cmp(x, y) {
1396 Ordering::Less => "less",
1397 Ordering::Greater => "greater",
1398 Ordering::Equal => "equal",
1403 Sometimes, it's a nice pattern.
1407 Looping is the last basic construct that we haven't learned yet in Rust. Rust has
1408 two main looping constructs: `for` and `while`.
1412 The `for` loop is used to loop a particular number of times. Rust's `for` loops
1413 work a bit differently than in other systems languages, however. Rust's `for`
1414 loop doesn't look like this "C-style" `for` loop:
1417 for (x = 0; x < 10; x++) {
1418 printf( "%d\n", x );
1422 Instead, it looks like this:
1425 for x in range(0, 10) {
1426 println!("{}", x); // x: i32
1430 In slightly more abstract terms,
1433 for var in expression {
1438 The expression is an iterator, which we will discuss in more depth later in the
1439 guide. The iterator gives back a series of elements. Each element is one
1440 iteration of the loop. That value is then bound to the name `var`, which is
1441 valid for the loop body. Once the body is over, the next value is fetched from
1442 the iterator, and we loop another time. When there are no more values, the
1445 In our example, `range` is a function that takes a start and an end position,
1446 and gives an iterator over those values. The upper bound is exclusive, though,
1447 so our loop will print `0` through `9`, not `10`.
1449 Rust does not have the "C-style" `for` loop on purpose. Manually controlling
1450 each element of the loop is complicated and error prone, even for experienced C
1453 We'll talk more about `for` when we cover **iterator**s, later in the Guide.
1457 The other kind of looping construct in Rust is the `while` loop. It looks like
1461 let mut x = 5u; // mut x: uint
1462 let mut done = false; // mut done: bool
1467 if x % 5 == 0 { done = true; }
1471 `while` loops are the correct choice when you're not sure how many times
1474 If you need an infinite loop, you may be tempted to write this:
1480 However, Rust has a dedicated keyword, `loop`, to handle this case:
1486 Rust's control-flow analysis treats this construct differently than a
1487 `while true`, since we know that it will always loop. The details of what
1488 that _means_ aren't super important to understand at this stage, but in
1489 general, the more information we can give to the compiler, the better it
1490 can do with safety and code generation, so you should always prefer
1491 `loop` when you plan to loop infinitely.
1493 ## Ending iteration early
1495 Let's take a look at that `while` loop we had earlier:
1499 let mut done = false;
1504 if x % 5 == 0 { done = true; }
1508 We had to keep a dedicated `mut` boolean variable binding, `done`, to know
1509 when we should exit out of the loop. Rust has two keywords to help us with
1510 modifying iteration: `break` and `continue`.
1512 In this case, we can write the loop in a better way with `break`:
1520 if x % 5 == 0 { break; }
1524 We now loop forever with `loop` and use `break` to break out early.
1526 `continue` is similar, but instead of ending the loop, goes to the next
1527 iteration. This will only print the odd numbers:
1530 for x in range(0, 10) {
1531 if x % 2 == 0 { continue; }
1537 Both `continue` and `break` are valid in both kinds of loops.
1541 Strings are an important concept for any programmer to master. Rust's string
1542 handling system is a bit different from other languages, due to its systems
1543 focus. Any time you have a data structure of variable size, things can get
1544 tricky, and strings are a re-sizable data structure. That being said, Rust's
1545 strings also work differently than in some other systems languages, such as C.
1547 Let's dig into the details. A **string** is a sequence of Unicode scalar values
1548 encoded as a stream of UTF-8 bytes. All strings are guaranteed to be
1549 validly encoded UTF-8 sequences. Additionally, strings are not null-terminated
1550 and can contain null bytes.
1552 Rust has two main types of strings: `&str` and `String`.
1554 The first kind is a `&str`. This is pronounced a 'string slice.' String literals
1555 are of the type `&str`:
1558 let string = "Hello there."; // string: &str
1561 This string is statically allocated, meaning that it's saved inside our
1562 compiled program, and exists for the entire duration it runs. The `string`
1563 binding is a reference to this statically allocated string. String slices
1564 have a fixed size, and cannot be mutated.
1566 A `String`, on the other hand, is an in-memory string. This string is
1567 growable, and is also guaranteed to be UTF-8.
1570 let mut s = "Hello".to_string(); // mut s: String
1573 s.push_str(", world.");
1577 You can get a `&str` view into a `String` with the `as_slice()` method:
1580 fn takes_slice(slice: &str) {
1581 println!("Got: {}", slice);
1585 let s = "Hello".to_string();
1586 takes_slice(s.as_slice());
1590 To compare a String to a constant string, prefer `as_slice()`...
1593 fn compare(string: String) {
1594 if string.as_slice() == "Hello" {
1600 ... over `to_string()`:
1603 fn compare(string: String) {
1604 if string == "Hello".to_string() {
1610 Viewing a `String` as a `&str` is cheap, but converting the `&str` to a
1611 `String` involves allocating memory. No reason to do that unless you have to!
1613 That's the basics of strings in Rust! They're probably a bit more complicated
1614 than you are used to, if you come from a scripting language, but when the
1615 low-level details matter, they really matter. Just remember that `String`s
1616 allocate memory and control their data, while `&str`s are a reference to
1617 another string, and you'll be all set.
1619 # Arrays, Vectors, and Slices
1621 Like many programming languages, Rust has list types to represent a sequence of
1622 things. The most basic is the **array**, a fixed-size list of elements of the
1623 same type. By default, arrays are immutable.
1626 let a = [1, 2, 3]; // a: [i32; 3]
1627 let mut m = [1, 2, 3]; // mut m: [i32; 3]
1630 There's a shorthand for initializing each element of an array to the same
1631 value. In this example, each element of `a` will be initialized to `0`:
1634 let a = [0; 20]; // a: [i32; 20]
1637 Arrays have type `[T; N]`. We'll talk about this `T` notation later, when we
1640 You can get the number of elements in an array `a` with `a.len()`, and use
1641 `a.iter()` to iterate over them with a for loop. This code will print each
1647 println!("a has {} elements", a.len());
1653 You can access a particular element of an array with **subscript notation**:
1656 let names = ["Graydon", "Brian", "Niko"]; // names: [&str, 3]
1658 println!("The second name is: {}", names[1]);
1661 Subscripts start at zero, like in most programming languages, so the first name
1662 is `names[0]` and the second name is `names[1]`. The above example prints
1663 `The second name is: Brian`. If you try to use a subscript that is not in the
1664 array, you will get an error: array access is bounds-checked at run-time. Such
1665 errant access is the source of many bugs in other systems programming
1668 A **vector** is a dynamic or "growable" array, implemented as the standard
1669 library type [`Vec<T>`](std/vec/) (we'll talk about what the `<T>` means
1670 later). Vectors are to arrays what `String` is to `&str`. You can create them
1671 with the `vec!` macro:
1674 let v = vec![1, 2, 3]; // v: Vec<i32>
1677 (Notice that unlike the `println!` macro we've used in the past, we use square
1678 brackets `[]` with `vec!`. Rust allows you to use either in either situation,
1679 this is just convention.)
1681 You can get the length of, iterate over, and subscript vectors just like
1682 arrays. In addition, (mutable) vectors can grow automatically:
1685 let mut nums = vec![1, 2, 3]; // mut nums: Vec<i32>
1689 println!("The length of nums is now {}", nums.len()); // Prints 4
1692 Vectors have many more useful methods.
1694 A **slice** is a reference to (or "view" into) an array. They are useful for
1695 allowing safe, efficient access to a portion of an array without copying. For
1696 example, you might want to reference just one line of a file read into memory.
1697 By nature, a slice is not created directly, but from an existing variable.
1698 Slices have a length, can be mutable or not, and in many ways behave like
1702 let a = [0, 1, 2, 3, 4];
1703 let middle = a.slice(1, 4); // A slice of a: just the elements [1,2,3]
1705 for e in middle.iter() {
1706 println!("{}", e); // Prints 1, 2, 3
1710 You can also take a slice of a vector, `String`, or `&str`, because they are
1711 backed by arrays. Slices have type `&[T]`, which we'll talk about when we cover
1714 We have now learned all of the most basic Rust concepts. We're ready to start
1715 building our guessing game, we just need to know one last thing: how to get
1716 input from the keyboard. You can't have a guessing game without the ability to
1721 Getting input from the keyboard is pretty easy, but uses some things
1722 we haven't seen before. Here's a simple program that reads some input,
1723 and then prints it back out:
1727 println!("Type something!");
1729 let input = std::io::stdin().read_line().ok().expect("Failed to read line");
1731 println!("{}", input);
1735 Let's go over these chunks, one by one:
1741 This calls a function, `stdin()`, that lives inside the `std::io` module. As
1742 you can imagine, everything in `std` is provided by Rust, the 'standard
1743 library.' We'll talk more about the module system later.
1745 Since writing the fully qualified name all the time is annoying, we can use
1746 the `use` statement to import it in:
1754 However, it's considered better practice to not import individual functions, but
1755 to import the module, and only use one level of qualification:
1763 Let's update our example to use this style:
1769 println!("Type something!");
1771 let input = io::stdin().read_line().ok().expect("Failed to read line");
1773 println!("{}", input);
1783 The `read_line()` method can be called on the result of `stdin()` to return
1784 a full line of input. Nice and easy.
1787 .ok().expect("Failed to read line");
1790 Do you remember this code?
1799 let x = OptionalInt::Value(5);
1800 let y = OptionalInt::Missing;
1803 OptionalInt::Value(n) => println!("x is {}", n),
1804 OptionalInt::Missing => println!("x is missing!"),
1808 OptionalInt::Value(n) => println!("y is {}", n),
1809 OptionalInt::Missing => println!("y is missing!"),
1814 We had to match each time to see if we had a value or not. In this case,
1815 though, we _know_ that `x` has a `Value`, but `match` forces us to handle
1816 the `missing` case. This is what we want 99% of the time, but sometimes, we
1817 know better than the compiler.
1819 Likewise, `read_line()` does not return a line of input. It _might_ return a
1820 line of input, though it might also fail to do so. This could happen if our program
1821 isn't running in a terminal, but as part of a cron job, or some other context
1822 where there's no standard input. Because of this, `read_line` returns a type
1823 very similar to our `OptionalInt`: an `IoResult<T>`. We haven't talked about
1824 `IoResult<T>` yet because it is the **generic** form of our `OptionalInt`.
1825 Until then, you can think of it as being the same thing, just for any type –
1828 Rust provides a method on these `IoResult<T>`s called `ok()`, which does the
1829 same thing as our `match` statement but assumes that we have a valid value.
1830 We then call `expect()` on the result, which will terminate our program if we
1831 don't have a valid value. In this case, if we can't get input, our program
1832 doesn't work, so we're okay with that. In most cases, we would want to handle
1833 the error case explicitly. `expect()` allows us to give an error message if
1836 We will cover the exact details of how all of this works later in the Guide.
1837 For now, this gives you enough of a basic understanding to work with.
1839 Back to the code we were working on! Here's a refresher:
1845 println!("Type something!");
1847 let input = io::stdin().read_line().ok().expect("Failed to read line");
1849 println!("{}", input);
1853 With long lines like this, Rust gives you some flexibility with the whitespace.
1854 We _could_ write the example like this:
1860 println!("Type something!");
1862 // here, we'll show the types at each step
1864 let input = io::stdin() // std::io::stdio::StdinReader
1865 .read_line() // IoResult<String>
1866 .ok() // Option<String>
1867 .expect("Failed to read line"); // String
1869 println!("{}", input);
1873 Sometimes, this makes things more readable – sometimes, less. Use your judgement
1876 That's all you need to get basic input from the standard input! It's not too
1877 complicated, but there are a number of small parts.
1881 Okay! We've got the basics of Rust down. Let's write a bigger program.
1883 For our first project, we'll implement a classic beginner programming problem:
1884 the guessing game. Here's how it works: Our program will generate a random
1885 integer between one and a hundred. It will then prompt us to enter a guess.
1886 Upon entering our guess, it will tell us if we're too low or too high. Once we
1887 guess correctly, it will congratulate us. Sound good?
1891 Let's set up a new project. Go to your projects directory. Remember how we
1892 had to create our directory structure and a `Cargo.toml` for `hello_world`? Cargo
1893 has a command that does that for us. Let's give it a shot:
1897 $ cargo new guessing_game --bin
1901 We pass the name of our project to `cargo new`, and then the `--bin` flag,
1902 since we're making a binary, rather than a library.
1904 Check out the generated `Cargo.toml`:
1909 name = "guessing_game"
1911 authors = ["Your Name <you@example.com>"]
1914 Cargo gets this information from your environment. If it's not correct, go ahead
1917 Finally, Cargo generated a "Hello, world!" for us. Check out `src/main.rs`:
1921 println!("Hello, world!")
1925 Let's try compiling what Cargo gave us:
1929 Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
1932 Excellent! Open up your `src/main.rs` again. We'll be writing all of
1933 our code in this file. We'll talk about multiple-file projects later on in the
1936 Before we move on, let me show you one more Cargo command: `run`. `cargo run`
1937 is kind of like `cargo build`, but it also then runs the produced executable.
1942 Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
1943 Running `target/guessing_game`
1947 Great! The `run` command comes in handy when you need to rapidly iterate on a project.
1948 Our game is just such a project, we need to quickly test each iteration before moving on to the next one.
1950 ## Processing a Guess
1952 Let's get to it! The first thing we need to do for our guessing game is
1953 allow our player to input a guess. Put this in your `src/main.rs`:
1959 println!("Guess the number!");
1961 println!("Please input your guess.");
1963 let input = io::stdin().read_line()
1965 .expect("Failed to read line");
1967 println!("You guessed: {}", input);
1971 You've seen this code before, when we talked about standard input. We
1972 import the `std::io` module with `use`, and then our `main` function contains
1973 our program's logic. We print a little message announcing the game, ask the
1974 user to input a guess, get their input, and then print it out.
1976 Because we talked about this in the section on standard I/O, I won't go into
1977 more details here. If you need a refresher, go re-read that section.
1979 ## Generating a secret number
1981 Next, we need to generate a secret number. To do that, we need to use Rust's
1982 random number generation, which we haven't talked about yet. Rust includes a
1983 bunch of interesting functions in its standard library. If you need a bit of
1984 code, it's possible that it's already been written for you! In this case,
1985 we do know that Rust has random number generation, but we don't know how to
1988 Enter the docs. Rust has a page specifically to document the standard library.
1989 You can find that page [here](std/index.html). There's a lot of information on
1990 that page, but the best part is the search bar. Right up at the top, there's
1991 a box that you can enter in a search term. The search is pretty primitive
1992 right now, but is getting better all the time. If you type 'random' in that
1993 box, the page will update to [this one](std/index.html?search=random). The very
1994 first result is a link to [`std::rand::random`](std/rand/fn.random.html). If we
1995 click on that result, we'll be taken to its documentation page.
1997 This page shows us a few things: the type signature of the function, some
1998 explanatory text, and then an example. Let's try to modify our code to add in the
1999 `random` function and see what happens:
2006 println!("Guess the number!");
2008 let secret_number = (rand::random() % 100) + 1; // secret_number: i32
2010 println!("The secret number is: {}", secret_number);
2012 println!("Please input your guess.");
2014 let input = io::stdin().read_line()
2016 .expect("Failed to read line");
2019 println!("You guessed: {}", input);
2023 The first thing we changed was to `use std::rand`, as the docs
2024 explained. We then added in a `let` expression to create a variable binding
2025 named `secret_number`, and we printed out its result.
2027 Also, you may wonder why we are using `%` on the result of `rand::random()`.
2028 This operator is called 'modulo', and it returns the remainder of a division.
2029 By taking the modulo of the result of `rand::random()`, we're limiting the
2030 values to be between 0 and 99. Then, we add one to the result, making it from 1
2031 to 100. Using modulo can give you a very, very small bias in the result, but
2032 for this example, it is not important.
2034 Let's try to compile this using `cargo build`:
2038 Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
2039 src/main.rs:7:26: 7:34 error: the type of this value must be known in this context
2040 src/main.rs:7 let secret_number = (rand::random() % 100) + 1;
2042 error: aborting due to previous error
2045 It didn't work! Rust says "the type of this value must be known in this
2046 context." What's up with that? Well, as it turns out, `rand::random()` can
2047 generate many kinds of random values, not just integers. And in this case, Rust
2048 isn't sure what kind of value `random()` should generate. So we have to help
2049 it. With number literals, we can just add an `i32` onto the end to tell Rust they're
2050 integers, but that does not work with functions. There's a different syntax,
2051 and it looks like this:
2054 rand::random::<i32>();
2057 This says "please give me a random `i32` value." We can change our code to use
2065 println!("Guess the number!");
2067 let secret_number = (rand::random::<i32>() % 100) + 1;
2069 println!("The secret number is: {}", secret_number);
2071 println!("Please input your guess.");
2073 let input = io::stdin().read_line()
2075 .expect("Failed to read line");
2078 println!("You guessed: {}", input);
2082 Try running our new program a few times:
2086 Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
2087 Running `target/guessing_game`
2089 The secret number is: 7
2090 Please input your guess.
2093 $ ./target/guessing_game
2095 The secret number is: 83
2096 Please input your guess.
2099 $ ./target/guessing_game
2101 The secret number is: -29
2102 Please input your guess.
2107 Wait. Negative 29? We wanted a number between one and a hundred! We have two
2108 options here: we can either ask `random()` to generate an unsigned integer, which
2109 can only be positive, or we can use the `abs()` function. Let's go with the
2110 unsigned integer approach. If we want a random positive number, we should ask for
2111 a random positive number. Our code looks like this now:
2118 println!("Guess the number!");
2120 let secret_number = (rand::random::<uint>() % 100u) + 1u;
2122 println!("The secret number is: {}", secret_number);
2124 println!("Please input your guess.");
2126 let input = io::stdin().read_line()
2128 .expect("Failed to read line");
2131 println!("You guessed: {}", input);
2139 Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
2140 Running `target/guessing_game`
2142 The secret number is: 57
2143 Please input your guess.
2148 Great! Next up: let's compare our guess to the secret guess.
2150 ## Comparing guesses
2152 If you remember, earlier in the guide, we made a `cmp` function that compared
2153 two numbers. Let's add that in, along with a `match` statement to compare our
2154 guess to the secret number:
2159 use std::cmp::Ordering;
2162 println!("Guess the number!");
2164 let secret_number = (rand::random::<uint>() % 100u) + 1u;
2166 println!("The secret number is: {}", secret_number);
2168 println!("Please input your guess.");
2170 let input = io::stdin().read_line()
2172 .expect("Failed to read line");
2175 println!("You guessed: {}", input);
2177 match cmp(input, secret_number) {
2178 Ordering::Less => println!("Too small!"),
2179 Ordering::Greater => println!("Too big!"),
2180 Ordering::Equal => println!("You win!"),
2184 fn cmp(a: i32, b: i32) -> Ordering {
2185 if a < b { Ordering::Less }
2186 else if a > b { Ordering::Greater }
2187 else { Ordering::Equal }
2191 If we try to compile, we'll get some errors:
2195 Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
2196 src/main.rs:20:15: 20:20 error: mismatched types: expected `i32` but found `collections::string::String` (expected i32 but found struct collections::string::String)
2197 src/main.rs:20 match cmp(input, secret_number) {
2199 src/main.rs:20:22: 20:35 error: mismatched types: expected `i32` but found `uint` (expected i32 but found uint)
2200 src/main.rs:20 match cmp(input, secret_number) {
2202 error: aborting due to 2 previous errors
2205 This often happens when writing Rust programs, and is one of Rust's greatest
2206 strengths. You try out some code, see if it compiles, and Rust tells you that
2207 you've done something wrong. In this case, our `cmp` function works on integers,
2208 but we've given it unsigned integers. In this case, the fix is easy, because
2209 we wrote the `cmp` function! Let's change it to take `uint`s:
2214 use std::cmp::Ordering;
2217 println!("Guess the number!");
2219 let secret_number = (rand::random::<uint>() % 100u) + 1u;
2221 println!("The secret number is: {}", secret_number);
2223 println!("Please input your guess.");
2225 let input = io::stdin().read_line()
2227 .expect("Failed to read line");
2230 println!("You guessed: {}", input);
2232 match cmp(input, secret_number) {
2233 Ordering::Less => println!("Too small!"),
2234 Ordering::Greater => println!("Too big!"),
2235 Ordering::Equal => println!("You win!"),
2239 fn cmp(a: uint, b: uint) -> Ordering {
2240 if a < b { Ordering::Less }
2241 else if a > b { Ordering::Greater }
2242 else { Ordering::Equal }
2246 And try compiling again:
2250 Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
2251 src/main.rs:20:15: 20:20 error: mismatched types: expected `uint` but found `collections::string::String` (expected uint but found struct collections::string::String)
2252 src/main.rs:20 match cmp(input, secret_number) {
2254 error: aborting due to previous error
2257 This error is similar to the last one: we expected to get a `uint`, but we got
2258 a `String` instead! That's because our `input` variable is coming from the
2259 standard input, and you can guess anything. Try it:
2262 $ ./target/guessing_game
2264 The secret number is: 73
2265 Please input your guess.
2270 Oops! Also, you'll note that we just ran our program even though it didn't compile.
2271 This works because the older version we did successfully compile was still lying
2272 around. Gotta be careful!
2274 Anyway, we have a `String`, but we need a `uint`. What to do? Well, there's
2275 a function for that:
2278 let input = io::stdin().read_line()
2280 .expect("Failed to read line");
2281 let input_num: Option<uint> = input.parse();
2284 The `parse` function takes in a `&str` value and converts it into something.
2285 We tell it what kind of something with a type hint. Remember our type hint with
2286 `random()`? It looked like this:
2289 rand::random::<uint>();
2292 There's an alternate way of providing a hint too, and that's declaring the type
2296 let x: uint = rand::random();
2299 In this case, we say `x` is a `uint` explicitly, so Rust is able to properly
2300 tell `random()` what to generate. In a similar fashion, both of these work:
2303 let input_num = "5".parse::<uint>(); // input_num: Option<uint>
2304 let input_num: Option<uint> = "5".parse(); // input_num: Option<uint>
2307 Anyway, with us now converting our input to a number, our code looks like this:
2312 use std::cmp::Ordering;
2315 println!("Guess the number!");
2317 let secret_number = (rand::random::<uint>() % 100u) + 1u;
2319 println!("The secret number is: {}", secret_number);
2321 println!("Please input your guess.");
2323 let input = io::stdin().read_line()
2325 .expect("Failed to read line");
2326 let input_num: Option<uint> = input.parse();
2328 println!("You guessed: {}", input_num);
2330 match cmp(input_num, secret_number) {
2331 Ordering::Less => println!("Too small!"),
2332 Ordering::Greater => println!("Too big!"),
2333 Ordering::Equal => println!("You win!"),
2337 fn cmp(a: uint, b: uint) -> Ordering {
2338 if a < b { Ordering::Less }
2339 else if a > b { Ordering::Greater }
2340 else { Ordering::Equal }
2348 Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
2349 src/main.rs:22:15: 22:24 error: mismatched types: expected `uint` but found `core::option::Option<uint>` (expected uint but found enum core::option::Option)
2350 src/main.rs:22 match cmp(input_num, secret_number) {
2352 error: aborting due to previous error
2355 Oh yeah! Our `input_num` has the type `Option<uint>`, rather than `uint`. We
2356 need to unwrap the Option. If you remember from before, `match` is a great way
2357 to do that. Try this code:
2362 use std::cmp::Ordering;
2365 println!("Guess the number!");
2367 let secret_number = (rand::random::<uint>() % 100u) + 1u;
2369 println!("The secret number is: {}", secret_number);
2371 println!("Please input your guess.");
2373 let input = io::stdin().read_line()
2375 .expect("Failed to read line");
2376 let input_num: Option<uint> = input.parse();
2378 let num = match input_num {
2381 println!("Please input a number!");
2387 println!("You guessed: {}", num);
2389 match cmp(num, secret_number) {
2390 Ordering::Less => println!("Too small!"),
2391 Ordering::Greater => println!("Too big!"),
2392 Ordering::Equal => println!("You win!"),
2396 fn cmp(a: uint, b: uint) -> Ordering {
2397 if a < b { Ordering::Less }
2398 else if a > b { Ordering::Greater }
2399 else { Ordering::Equal }
2403 We use a `match` to either give us the `uint` inside of the `Option`, or else
2404 print an error message and return. Let's give this a shot:
2408 Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
2409 Running `target/guessing_game`
2411 The secret number is: 17
2412 Please input your guess.
2414 Please input a number!
2417 Uh, what? But we did!
2419 ... actually, we didn't. See, when you get a line of input from `stdin()`,
2420 you get all the input. Including the `\n` character from you pressing Enter.
2421 Therefore, `parse()` sees the string `"5\n"` and says "nope, that's not a
2422 number; there's non-number stuff in there!" Luckily for us, `&str`s have an easy
2423 method we can use defined on them: `trim()`. One small modification, and our
2424 code looks like this:
2429 use std::cmp::Ordering;
2432 println!("Guess the number!");
2434 let secret_number = (rand::random::<uint>() % 100u) + 1u;
2436 println!("The secret number is: {}", secret_number);
2438 println!("Please input your guess.");
2440 let input = io::stdin().read_line()
2442 .expect("Failed to read line");
2443 let input_num: Option<uint> = input.trim().parse();
2445 let num = match input_num {
2448 println!("Please input a number!");
2454 println!("You guessed: {}", num);
2456 match cmp(num, secret_number) {
2457 Ordering::Less => println!("Too small!"),
2458 Ordering::Greater => println!("Too big!"),
2459 Ordering::Equal => println!("You win!"),
2463 fn cmp(a: uint, b: uint) -> Ordering {
2464 if a < b { Ordering::Less }
2465 else if a > b { Ordering::Greater }
2466 else { Ordering::Equal }
2474 Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
2475 Running `target/guessing_game`
2477 The secret number is: 58
2478 Please input your guess.
2484 Nice! You can see I even added spaces before my guess, and it still figured
2485 out that I guessed 76. Run the program a few times, and verify that guessing
2486 the number works, as well as guessing a number too small.
2488 The Rust compiler helped us out quite a bit there! This technique is called
2489 "lean on the compiler", and it's often useful when working on some code. Let
2490 the error messages help guide you towards the correct types.
2492 Now we've got most of the game working, but we can only make one guess. Let's
2493 change that by adding loops!
2497 As we already discussed, the `loop` keyword gives us an infinite loop.
2503 use std::cmp::Ordering;
2506 println!("Guess the number!");
2508 let secret_number = (rand::random::<uint>() % 100u) + 1u;
2510 println!("The secret number is: {}", secret_number);
2514 println!("Please input your guess.");
2516 let input = io::stdin().read_line()
2518 .expect("Failed to read line");
2519 let input_num: Option<uint> = input.trim().parse();
2521 let num = match input_num {
2524 println!("Please input a number!");
2530 println!("You guessed: {}", num);
2532 match cmp(num, secret_number) {
2533 Ordering::Less => println!("Too small!"),
2534 Ordering::Greater => println!("Too big!"),
2535 Ordering::Equal => println!("You win!"),
2540 fn cmp(a: uint, b: uint) -> Ordering {
2541 if a < b { Ordering::Less }
2542 else if a > b { Ordering::Greater }
2543 else { Ordering::Equal }
2547 And try it out. But wait, didn't we just add an infinite loop? Yup. Remember
2548 that `return`? If we give a non-number answer, we'll `return` and quit. Observe:
2552 Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
2553 Running `target/guessing_game`
2555 The secret number is: 59
2556 Please input your guess.
2560 Please input your guess.
2564 Please input your guess.
2568 Please input your guess.
2570 Please input a number!
2573 Ha! `quit` actually quits. As does any other non-number input. Well, this is
2574 suboptimal to say the least. First, let's actually quit when you win the game:
2579 use std::cmp::Ordering;
2582 println!("Guess the number!");
2584 let secret_number = (rand::random::<uint>() % 100u) + 1u;
2586 println!("The secret number is: {}", secret_number);
2590 println!("Please input your guess.");
2592 let input = io::stdin().read_line()
2594 .expect("Failed to read line");
2595 let input_num: Option<uint> = input.trim().parse();
2597 let num = match input_num {
2600 println!("Please input a number!");
2606 println!("You guessed: {}", num);
2608 match cmp(num, secret_number) {
2609 Ordering::Less => println!("Too small!"),
2610 Ordering::Greater => println!("Too big!"),
2611 Ordering::Equal => {
2612 println!("You win!");
2619 fn cmp(a: uint, b: uint) -> Ordering {
2620 if a < b { Ordering::Less }
2621 else if a > b { Ordering::Greater }
2622 else { Ordering::Equal }
2626 By adding the `return` line after the `You win!`, we'll exit the program when
2627 we win. We have just one more tweak to make: when someone inputs a non-number,
2628 we don't want to quit, we just want to ignore it. Change that `return` to
2635 use std::cmp::Ordering;
2638 println!("Guess the number!");
2640 let secret_number = (rand::random::<uint>() % 100u) + 1u;
2642 println!("The secret number is: {}", secret_number);
2646 println!("Please input your guess.");
2648 let input = io::stdin().read_line()
2650 .expect("Failed to read line");
2651 let input_num: Option<uint> = input.trim().parse();
2653 let num = match input_num {
2656 println!("Please input a number!");
2662 println!("You guessed: {}", num);
2664 match cmp(num, secret_number) {
2665 Ordering::Less => println!("Too small!"),
2666 Ordering::Greater => println!("Too big!"),
2667 Ordering::Equal => {
2668 println!("You win!");
2675 fn cmp(a: uint, b: uint) -> Ordering {
2676 if a < b { Ordering::Less }
2677 else if a > b { Ordering::Greater }
2678 else { Ordering::Equal }
2682 Now we should be good! Let's try:
2686 Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
2687 Running `target/guessing_game`
2689 The secret number is: 61
2690 Please input your guess.
2694 Please input your guess.
2698 Please input your guess.
2700 Please input a number!
2701 Please input your guess.
2707 Awesome! With one tiny last tweak, we have finished the guessing game. Can you
2708 think of what it is? That's right, we don't want to print out the secret number.
2709 It was good for testing, but it kind of ruins the game. Here's our final source:
2714 use std::cmp::Ordering;
2717 println!("Guess the number!");
2719 let secret_number = (rand::random::<uint>() % 100u) + 1u;
2723 println!("Please input your guess.");
2725 let input = io::stdin().read_line()
2727 .expect("Failed to read line");
2728 let input_num: Option<uint> = input.trim().parse();
2730 let num = match input_num {
2733 println!("Please input a number!");
2739 println!("You guessed: {}", num);
2741 match cmp(num, secret_number) {
2742 Ordering::Less => println!("Too small!"),
2743 Ordering::Greater => println!("Too big!"),
2744 Ordering::Equal => {
2745 println!("You win!");
2752 fn cmp(a: uint, b: uint) -> Ordering {
2753 if a < b { Ordering::Less }
2754 else if a > b { Ordering::Greater }
2755 else { Ordering::Equal }
2761 At this point, you have successfully built the Guessing Game! Congratulations!
2763 You've now learned the basic syntax of Rust. All of this is relatively close to
2764 various other programming languages you have used in the past. These
2765 fundamental syntactical and semantic elements will form the foundation for the
2766 rest of your Rust education.
2768 Now that you're an expert at the basics, it's time to learn about some of
2769 Rust's more unique features.
2771 # Crates and Modules
2773 Rust features a strong module system, but it works a bit differently than in
2774 other programming languages. Rust's module system has two main components:
2775 **crate**s and **module**s.
2777 A crate is Rust's unit of independent compilation. Rust always compiles one
2778 crate at a time, producing either a library or an executable. However, executables
2779 usually depend on libraries, and many libraries depend on other libraries as well.
2780 To support this, crates can depend on other crates.
2782 Each crate contains a hierarchy of modules. This tree starts off with a single
2783 module, called the **crate root**. Within the crate root, we can declare other
2784 modules, which can contain other modules, as deeply as you'd like.
2786 Note that we haven't mentioned anything about files yet. Rust does not impose a
2787 particular relationship between your filesystem structure and your module
2788 structure. That said, there is a conventional approach to how Rust looks for
2789 modules on the file system, but it's also overridable.
2791 Enough talk, let's build something! Let's make a new project called `modules`.
2795 $ cargo new modules --bin
2799 Let's double check our work by compiling:
2803 Compiling modules v0.0.1 (file:///home/you/projects/modules)
2804 Running `target/modules`
2808 Excellent! We already have a single crate here: our `src/main.rs` is a crate.
2809 Everything in that file is in the crate root. A crate that generates an executable
2810 defines a `main` function inside its root, as we've done here.
2812 Let's define a new module inside our crate. Edit `src/main.rs` to look like this:
2816 println!("Hello, world!")
2821 println!("Hello, world!")
2826 We now have a module named `hello` inside of our crate root. Modules use
2827 `snake_case` naming, like functions and variable bindings.
2829 Inside the `hello` module, we've defined a `print_hello` function. This will
2830 also print out our "hello world" message. Modules allow you to split up your
2831 program into nice neat boxes of functionality, grouping common things together,
2832 and keeping different things apart. It's kinda like having a set of shelves:
2833 a place for everything and everything in its place.
2835 To call our `print_hello` function, we use the double colon (`::`):
2838 hello::print_hello();
2841 You've seen this before, with `io::stdin()` and `rand::random()`. Now you know
2842 how to make your own. However, crates and modules have rules about
2843 **visibility**, which controls who exactly may use the functions defined in a
2844 given module. By default, everything in a module is private, which means that
2845 it can only be used by other functions in the same module. This will not
2850 hello::print_hello();
2855 println!("Hello, world!")
2863 Compiling modules v0.0.1 (file:///home/you/projects/modules)
2864 src/main.rs:2:5: 2:23 error: function `print_hello` is private
2865 src/main.rs:2 hello::print_hello();
2869 To make it public, we use the `pub` keyword:
2873 hello::print_hello();
2877 pub fn print_hello() {
2878 println!("Hello, world!")
2883 Usage of the `pub` keyword is sometimes called 'exporting', because
2884 we're making the function available for other modules. This will work:
2888 Compiling modules v0.0.1 (file:///home/you/projects/modules)
2889 Running `target/modules`
2893 Nice! There are more things we can do with modules, including moving them into
2894 their own files. This is enough detail for now.
2898 Traditionally, testing has not been a strong suit of most systems programming
2899 languages. Rust, however, has very basic testing built into the language
2900 itself. While automated testing cannot prove that your code is bug-free, it is
2901 useful for verifying that certain behaviors work as intended.
2903 Here's a very basic test:
2907 fn is_one_equal_to_one() {
2912 You may notice something new: that `#[test]`. Before we get into the mechanics
2913 of testing, let's talk about attributes.
2917 Rust's testing system uses **attribute**s to mark which functions are tests.
2918 Attributes can be placed on any Rust **item**. Remember how most things in
2919 Rust are an expression, but `let` is not? Item declarations are also not
2920 expressions. Here's a list of things that qualify as an item:
2931 You haven't learned about all of these things yet, but that's the list. As
2932 you can see, functions are at the top of it.
2934 Attributes can appear in three ways:
2936 1. A single identifier, the attribute name. `#[test]` is an example of this.
2937 2. An identifier followed by an equals sign (`=`) and a literal. `#[cfg=test]`
2938 is an example of this.
2939 3. An identifier followed by a parenthesized list of sub-attribute arguments.
2940 `#[cfg(unix, target_word_size = "32")]` is an example of this, where one of
2941 the sub-arguments is of the second kind.
2943 There are a number of different kinds of attributes, enough that we won't go
2944 over them all here. Before we talk about the testing-specific attributes, I
2945 want to call out one of the most important kinds of attributes: stability
2948 ## Stability attributes
2950 Rust provides six attributes to indicate the stability level of various
2951 parts of your library. The six levels are:
2953 * deprecated: This item should no longer be used. No guarantee of backwards
2955 * experimental: This item was only recently introduced or is otherwise in a
2956 state of flux. It may change significantly, or even be removed. No guarantee
2957 of backwards-compatibility.
2958 * unstable: This item is still under development and requires more testing to
2959 be considered stable. No guarantee of backwards-compatibility.
2960 * stable: This item is considered stable, and will not change significantly.
2961 Guarantee of backwards-compatibility.
2962 * frozen: This item is very stable, and is unlikely to change. Guarantee of
2963 backwards-compatibility.
2964 * locked: This item will never change unless a serious bug is found. Guarantee
2965 of backwards-compatibility.
2967 All of Rust's standard library uses these attribute markers to communicate
2968 their relative stability, and you should use them in your code, as well.
2969 There's an associated attribute, `warn`, that allows you to warn when you
2970 import an item marked with certain levels: deprecated, experimental and
2971 unstable. For now, only deprecated warns by default, but this will change once
2972 the standard library has been stabilized.
2974 You can use the `warn` attribute like this:
2980 And later, when you import a crate:
2983 extern crate some_crate;
2986 You'll get a warning if you use something marked unstable.
2988 You may have noticed an exclamation point in the `warn` attribute declaration.
2989 The `!` in this attribute means that this attribute applies to the enclosing
2990 item, rather than to the item that follows the attribute. This `warn`
2991 attribute declaration applies to the enclosing crate itself, rather than
2992 to whatever item statement follows it:
2995 // applies to the crate we're in
2998 extern crate some_crate;
3000 // applies to the following `fn`.
3009 Let's write a very simple crate in a test-driven manner. You know the drill by
3010 now: make a new project:
3014 $ cargo new testing --bin
3022 Compiling testing v0.0.1 (file:///home/you/projects/testing)
3023 Running `target/testing`
3027 Great. Rust's infrastructure supports tests in two sorts of places, and they're
3028 for two kinds of tests: you include **unit test**s inside of the crate itself,
3029 and you place **integration test**s inside a `tests` directory. "Unit tests"
3030 are small tests that test one focused unit; "integration tests" test multiple
3031 units in integration. That being said, this is a social convention – they're no
3032 different in syntax. Let's make a `tests` directory:
3038 Next, let's create an integration test in `tests/lib.rs`:
3047 It doesn't matter what you name your test functions, though it's nice if
3048 you give them descriptive names. You'll see why in a moment. We then use a
3049 macro, `assert!`, to assert that something is true. In this case, we're giving
3050 it `false`, so this test should fail. Let's try it!
3054 Compiling testing v0.0.1 (file:///home/you/projects/testing)
3055 /home/you/projects/testing/src/main.rs:1:1: 3:2 warning: function is never used: `main`, #[warn(dead_code)] on by default
3056 /home/you/projects/testing/src/main.rs:1 fn main() {
3057 /home/you/projects/testing/src/main.rs:2 println!("Hello, world!")
3058 /home/you/projects/testing/src/main.rs:3 }
3059 Running target/lib-654ce120f310a3a5
3066 ---- foo stdout ----
3067 thread 'foo' failed at 'assertion failed: false', /home/you/projects/testing/tests/lib.rs:3
3074 test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
3076 thread '<main>' failed at 'Some tests failed', /home/you/src/rust/src/libtest/lib.rs:243
3079 Lots of output! Let's break this down:
3083 Compiling testing v0.0.1 (file:///home/you/projects/testing)
3086 You can run all of your tests with `cargo test`. This runs both your tests in
3087 `tests`, as well as the tests you put inside of your crate.
3090 /home/you/projects/testing/src/main.rs:1:1: 3:2 warning: function is never used: `main`, #[warn(dead_code)] on by default
3091 /home/you/projects/testing/src/main.rs:1 fn main() {
3092 /home/you/projects/testing/src/main.rs:2 println!("Hello, world!")
3093 /home/you/projects/testing/src/main.rs:3 }
3096 Rust has a **lint** called 'warn on dead code' used by default. A lint is a
3097 bit of code that checks your code, and can tell you things about it. In this
3098 case, Rust is warning us that we've written some code that's never used: our
3099 `main` function. Of course, since we're running tests, we don't use `main`.
3100 We'll turn this lint off for just this function soon. For now, just ignore this
3104 Running target/lib-654ce120f310a3a5
3110 Now we're getting somewhere. Remember when we talked about naming our tests
3111 with good names? This is why. Here, it says 'test foo' because we called our
3112 test 'foo'. If we had given it a good name, it'd be more clear which test
3113 failed, especially as we accumulate more tests.
3118 ---- foo stdout ----
3119 thread 'foo' failed at 'assertion failed: false', /home/you/projects/testing/tests/lib.rs:3
3126 test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
3128 thread '<main>' failed at 'Some tests failed', /home/you/src/rust/src/libtest/lib.rs:243
3131 After all the tests run, Rust will show us any output from our failed tests.
3132 In this instance, Rust tells us that our assertion failed, with false. This was
3135 Whew! Let's fix our test:
3144 And then try to run our tests again:
3148 Compiling testing v0.0.1 (file:///home/you/projects/testing)
3149 Running target/lib-654ce120f310a3a5
3154 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
3156 Running target/testing-6d7518593c7c3ee5
3160 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
3163 Nice! Our test passes, as we expected. Note how we didn't get the
3164 `main` warning this time? This is because `src/main.rs` didn't
3165 need recompiling, but we'll get that warning again if we
3166 change (and recompile) that file. Let's get rid of that
3167 warning; change your `src/main.rs` to look like this:
3172 println!("Hello, world!")
3176 This attribute combines two things: `cfg` and `not`. The `cfg` attribute allows
3177 you to conditionally compile code based on something. The following item will
3178 only be compiled if the configuration says it's true. And when Cargo compiles
3179 our tests, it sets things up so that `cfg(test)` is true. But we want to only
3180 include `main` when it's _not_ true. So we use `not` to negate things:
3181 `cfg(not(test))` will only compile our code when the `cfg(test)` is false.
3183 With this attribute, we won't get the warning (even
3184 though `src/main.rs` gets recompiled this time):
3188 Compiling testing v0.0.1 (file:///home/you/projects/testing)
3189 Running target/lib-654ce120f310a3a5
3194 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
3196 Running target/testing-6d7518593c7c3ee5
3200 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
3203 Nice. Okay, let's write a real test now. Change your `tests/lib.rs`
3208 fn math_checks_out() {
3209 let result = add_three_times_four(5);
3211 assert_eq!(32, result);
3215 And try to run the test:
3219 Compiling testing v0.0.1 (file:///home/you/projects/testing)
3220 /home/you/projects/testing/tests/lib.rs:3:18: 3:38 error: unresolved name `add_three_times_four`.
3221 /home/you/projects/testing/tests/lib.rs:3 let result = add_three_times_four(5);
3222 ^~~~~~~~~~~~~~~~~~~~
3223 error: aborting due to previous error
3224 Build failed, waiting for other jobs to finish...
3225 Could not compile `testing`.
3227 To learn more, run the command again with `--verbose`.
3230 Rust can't find this function. That makes sense, as we didn't write it yet!
3232 In order to share this code with our tests, we'll need to make a library crate.
3233 This is also just good software design: as we mentioned before, it's a good idea
3234 to put most of your functionality into a library crate, and have your executable
3235 crate use that library. This allows for code reuse.
3237 To do that, we'll need to make a new module. Make a new file, `src/lib.rs`,
3242 pub fn add_three_times_four(x: i32) -> i32 {
3247 We're calling this file `lib.rs`, because Cargo uses that filename as the crate
3250 We'll then need to use this crate in our `src/main.rs`:
3253 extern crate testing;
3257 println!("Hello, world!")
3261 Finally, let's import this function in our `tests/lib.rs`:
3264 extern crate testing;
3265 use testing::add_three_times_four;
3268 fn math_checks_out() {
3269 let result = add_three_times_four(5);
3271 assert_eq!(32, result);
3275 Let's give it a run:
3279 Compiling testing v0.0.1 (file:///home/you/projects/testing)
3280 Running target/lib-654ce120f310a3a5
3283 test math_checks_out ... ok
3285 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
3287 Running target/testing-6d7518593c7c3ee5
3291 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
3293 Running target/testing-8a94b31f7fd2e8fe
3297 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
3303 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
3306 Great! One test passed. We've got an integration test showing that our public
3307 method works, but maybe we want to test some of the internal logic as well.
3308 While this function is simple, if it were more complicated, you can imagine
3309 we'd need more tests. Let's break it up into two helper functions and write
3310 some unit tests to test those.
3312 Change your `src/lib.rs` to look like this:
3315 pub fn add_three_times_four(x: i32) -> i32 {
3316 times_four(add_three(x))
3319 fn add_three(x: i32) -> i32 { x + 3 }
3321 fn times_four(x: i32) -> i32 { x * 4 }
3324 If you run `cargo test`, you should get the same output:
3328 Compiling testing v0.0.1 (file:///home/you/projects/testing)
3329 Running target/lib-654ce120f310a3a5
3332 test math_checks_out ... ok
3334 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
3336 Running target/testing-6d7518593c7c3ee5
3340 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
3342 Running target/testing-8a94b31f7fd2e8fe
3346 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
3352 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
3355 If we tried to write a test for these two new functions, it wouldn't
3359 extern crate testing;
3360 use testing::add_three_times_four;
3361 use testing::add_three;
3364 fn math_checks_out() {
3365 let result = add_three_times_four(5);
3367 assert_eq!(32, result);
3371 fn test_add_three() {
3372 let result = add_three(5);
3374 assert_eq!(8, result);
3378 We'd get this error:
3381 Compiling testing v0.0.1 (file:///home/you/projects/testing)
3382 /home/you/projects/testing/tests/lib.rs:3:5: 3:24 error: function `add_three` is private
3383 /home/you/projects/testing/tests/lib.rs:3 use testing::add_three;
3387 Right. It's private. So external, integration tests won't work. We need a
3388 unit test. Open up your `src/lib.rs` and add this:
3391 pub fn add_three_times_four(x: i32) -> i32 {
3392 times_four(add_three(x))
3395 fn add_three(x: i32) -> i32 { x + 3 }
3397 fn times_four(x: i32) -> i32 { x * 4 }
3401 use super::add_three;
3402 use super::times_four;
3405 fn test_add_three() {
3406 let result = add_three(5);
3408 assert_eq!(8, result);
3412 fn test_times_four() {
3413 let result = times_four(5);
3415 assert_eq!(20, result);
3420 Let's give it a shot:
3424 Compiling testing v0.0.1 (file:///home/you/projects/testing)
3425 Running target/lib-654ce120f310a3a5
3428 test math_checks_out ... ok
3430 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
3432 Running target/testing-6d7518593c7c3ee5
3436 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
3438 Running target/testing-8a94b31f7fd2e8fe
3441 test test::test_times_four ... ok
3442 test test::test_add_three ... ok
3444 test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured
3450 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
3453 Cool! We now have two tests of our internal functions. You'll note that there
3454 are three sets of output now: one for `src/main.rs`, one for `src/lib.rs`, and
3455 one for `tests/lib.rs`. There's one interesting thing that we haven't talked
3456 about yet, and that's these lines:
3459 use super::add_three;
3460 use super::times_four;
3463 Because we've made a nested module, we can import functions from the parent
3464 module by using `super`. Sub-modules are allowed to 'see' private functions in
3467 We've now covered the basics of testing. Rust's tools are primitive, but they
3468 work well in the simple cases. There are some Rustaceans working on building
3469 more complicated frameworks on top of all of this, but they're just starting
3474 In systems programming, pointers are an incredibly important topic. Rust has a
3475 very rich set of pointers, and they operate differently than in many other
3476 languages. They are important enough that we have a specific [Pointer
3477 Guide](guide-pointers.html) that goes into pointers in much detail. In fact,
3478 while you're currently reading this guide, which covers the language in broad
3479 overview, there are a number of other guides that put a specific topic under a
3480 microscope. You can find the list of guides on the [documentation index
3481 page](index.html#guides).
3483 In this section, we'll assume that you're familiar with pointers as a general
3484 concept. If you aren't, please read the [introduction to
3485 pointers](guide-pointers.html#an-introduction) section of the Pointer Guide,
3486 and then come back here. We'll wait.
3488 Got the gist? Great. Let's talk about pointers in Rust.
3492 The most primitive form of pointer in Rust is called a **reference**.
3493 References are created using the ampersand (`&`). Here's a simple
3501 `y` is a reference to `x`. To dereference (get the value being referred to
3502 rather than the reference itself) `y`, we use the asterisk (`*`):
3511 Like any `let` binding, references are immutable by default.
3513 You can declare that functions take a reference:
3516 fn add_one(x: &i32) -> i32 { *x + 1 }
3519 assert_eq!(6, add_one(&5));
3523 As you can see, we can make a reference from a literal by applying `&` as well.
3524 Of course, in this simple function, there's not a lot of reason to take `x` by
3525 reference. It's just an example of the syntax.
3527 Because references are immutable, you can have multiple references that
3528 **alias** (point to the same place):
3536 We can make a mutable reference by using `&mut` instead of `&`:
3543 Note that `x` must also be mutable. If it isn't, like this:
3553 error: cannot borrow immutable local variable `x` as mutable
3558 We don't want a mutable reference to immutable data! This error message uses a
3559 term we haven't talked about yet, 'borrow'. We'll get to that in just a moment.
3561 This simple example actually illustrates a lot of Rust's power: Rust has
3562 prevented us, at compile time, from breaking our own rules. Because Rust's
3563 references check these kinds of rules entirely at compile time, there's no
3564 runtime overhead for this safety. At runtime, these are the same as a raw
3565 machine pointer, like in C or C++. We've just double-checked ahead of time
3566 that we haven't done anything dangerous.
3568 Rust will also prevent us from creating two mutable references that alias.
3577 It gives us this error:
3580 error: cannot borrow `x` as mutable more than once at a time
3583 note: previous borrow of `x` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `x` until the borrow ends
3586 note: previous borrow ends here
3595 This is a big error message. Let's dig into it for a moment. There are three
3596 parts: the error and two notes. The error says what we expected, we cannot have
3597 two mutable pointers that point to the same memory.
3599 The two notes give some extra context. Rust's error messages often contain this
3600 kind of extra information when the error is complex. Rust is telling us two
3601 things: first, that the reason we cannot **borrow** `x` as `z` is that we
3602 previously borrowed `x` as `y`. The second note shows where `y`'s borrowing
3607 In order to truly understand this error, we have to learn a few new concepts:
3608 **ownership**, **borrowing**, and **lifetimes**.
3610 ## Ownership, borrowing, and lifetimes
3612 Whenever a resource of some kind is created, something must be responsible
3613 for destroying that resource as well. Given that we're discussing pointers
3614 right now, let's discuss this in the context of memory allocation, though
3615 it applies to other resources as well.
3617 When you allocate heap memory, you need a mechanism to free that memory. Many
3618 languages use a garbage collector to handle deallocation. This is a valid,
3619 time-tested strategy, but it's not without its drawbacks: it adds overhead, and
3620 can lead to unpredictable pauses in execution. Because the programmer does not
3621 have to think as much about deallocation, allocation becomes something
3622 commonplace, leading to more memory usage. And if you need precise control
3623 over when something is deallocated, leaving it up to your runtime can make this
3626 Rust chooses a different path, and that path is called **ownership**. Any
3627 binding that creates a resource is the **owner** of that resource.
3629 Being an owner affords you some privileges:
3631 1. You control when that resource is deallocated.
3632 2. You may lend that resource, immutably, to as many borrowers as you'd like.
3633 3. You may lend that resource, mutably, to a single borrower.
3635 But it also comes with some restrictions:
3637 1. If someone is borrowing your resource (either mutably or immutably), you may
3638 not mutate the resource or mutably lend it to someone.
3639 2. If someone is mutably borrowing your resource, you may not lend it out at
3640 all (mutably or immutably) or access it in any way.
3642 What's up with all this 'lending' and 'borrowing'? When you allocate memory,
3643 you get a pointer to that memory. This pointer allows you to manipulate said
3644 memory. If you are the owner of a pointer, then you may allow another
3645 binding to temporarily borrow that pointer, and then they can manipulate the
3646 memory. The length of time that the borrower is borrowing the pointer
3647 from you is called a **lifetime**.
3649 If two distinct bindings share a pointer, and the memory that pointer points to
3650 is immutable, then there are no problems. But if it's mutable, the result of
3651 changing it can vary unpredictably depending on who happens to access it first,
3652 which is called a **race condition**. To avoid this, if someone wants to mutate
3653 something that they've borrowed from you, you must not have lent out that
3654 pointer to anyone else.
3656 Rust has a sophisticated system called the **borrow checker** to make sure that
3657 everyone plays by these rules. At compile time, it verifies that none of these
3658 rules are broken. If our program compiles successfully, Rust can guarantee it
3659 is free of data races and other memory errors, and there is no runtime overhead
3660 for any of this. The borrow checker works only at compile time. If the borrow
3661 checker did find a problem, it will report an error and your program will
3664 That's a lot to take in. It's also one of the _most_ important concepts in
3665 all of Rust. Let's see this syntax in action:
3669 let x = 5; // x is the owner of this integer, which is memory on the stack.
3671 // other code here...
3673 } // privilege 1: when x goes out of scope, this memory is deallocated
3675 /// this function borrows an integer. It's given back automatically when the
3676 /// function returns.
3677 fn foo(x: &i32) -> &i32 { x }
3680 // x is the owner of the integer, which is memory on the stack.
3683 // privilege 2: you may lend that resource to as many borrowers as you like
3687 foo(&x); // functions can borrow too!
3689 let a = &x; // we can do this alllllll day!
3693 // x is the owner of this integer, which is memory on the stack.
3696 // privilege 3: you may lend that resource to a single borrower, mutably
3701 If you are a borrower, you get a few privileges as well, but must also obey a
3704 1. If the borrow is immutable, you may read the data the pointer points to.
3705 2. If the borrow is mutable, you may read and write the data the pointer points to.
3706 3. You may lend the pointer to someone else, **BUT**
3707 4. When you do so, they must return it before you can give your own borrow back.
3709 This last requirement can seem odd, but it also makes sense. If you have to
3710 return something, and you've lent it to someone, they need to give it back to
3711 you for you to give it back! If we didn't, then the owner could deallocate
3712 the memory, and the person we've loaned it out to would have a pointer to
3713 invalid memory. This is called a 'dangling pointer'.
3715 Let's re-examine the error that led us to talk about all of this, which was a
3716 violation of the restrictions placed on owners who lend something out mutably.
3728 error: cannot borrow `x` as mutable more than once at a time
3731 note: previous borrow of `x` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `x` until the borrow ends
3734 note: previous borrow ends here
3743 This error comes in three parts. Let's go over each in turn.
3746 error: cannot borrow `x` as mutable more than once at a time
3751 This error states the restriction: you cannot lend out something mutable more
3752 than once at the same time. The borrow checker knows the rules!
3755 note: previous borrow of `x` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `x` until the borrow ends
3760 Some compiler errors come with notes to help you fix the error. This error comes
3761 with two notes, and this is the first. This note informs us of exactly where
3762 the first mutable borrow occurred. The error showed us the second. So now we
3763 see both parts of the problem. It also alludes to rule #3, by reminding us that
3764 we can't change `x` until the borrow is over.
3767 note: previous borrow ends here
3776 Here's the second note, which lets us know where the first borrow would be over.
3777 This is useful, because if we wait to try to borrow `x` after this borrow is
3778 over, then everything will work.
3780 For more advanced patterns, please consult the [Ownership
3781 Guide](guide-ownership.html). You'll also learn what this type signature with
3785 pub fn as_maybe_owned(&self) -> MaybeOwned<'a> { ... }
3790 Most of the types we've seen so far have a fixed size or number of components.
3791 The compiler needs this fact to lay out values in memory. However, some data
3792 structures, such as a linked list, do not have a fixed size. You might think to
3793 implement a linked list with an enum that's either a `Node` or the end of the
3794 list (`Nil`), like this:
3797 enum List { // error: illegal recursive enum type
3803 But the compiler complains that the type is recursive, that is, it could be
3804 arbitrarily large. To remedy this, Rust provides a fixed-size container called
3805 a **box** that can hold any type. You can box up any value with the `box`
3806 keyword. Our boxed List gets the type `Box<List>` (more on the notation when we
3811 Node(u32, Box<List>),
3816 let list = List::Node(0, box List::Node(1, box List::Nil));
3820 A box dynamically allocates memory to hold its contents. The great thing about
3821 Rust is that that memory is *automatically*, *efficiently*, and *predictably*
3822 deallocated when you're done with the box.
3824 A box is a pointer type, and you access what's inside using the `*` operator,
3825 just like regular references. This (rather silly) example dynamically allocates
3826 an integer `5` and makes `x` a pointer to it:
3831 println!("{}", *x); // Prints 5
3835 The great thing about boxes is that we don't have to manually free this
3836 allocation! Instead, when `x` reaches the end of its lifetime – in this case,
3837 when it goes out of scope at the end of the block – Rust `free`s `x`. This
3838 isn't because Rust has a garbage collector (it doesn't). Instead, by tracking
3839 the ownership and lifetime of a variable (with a little help from you, the
3840 programmer), the compiler knows precisely when it is no longer used.
3842 The Rust code above will do the same thing as the following C code:
3846 i32 *x = (i32 *)malloc(sizeof(i32));
3854 We get the benefits of manual memory management, while ensuring we don't
3855 introduce any bugs. We can't forget to `free` our memory.
3857 Boxes are the sole owner of their contents, so you cannot take a mutable
3858 reference to them and then use the original box:
3864 *x; // you might expect 5, but this is actually an error
3867 This gives us this error:
3870 error: cannot use `*x` because it was mutably borrowed
3873 note: borrow of `x` occurs here
3878 As long as `y` is borrowing the contents, we cannot use `x`. After `y` is
3879 done borrowing the value, we can use it again. This works fine:
3886 } // y goes out of scope at the end of the block
3891 Boxes are simple and efficient pointers to dynamically allocated values with a
3892 single owner. They are useful for tree-like structures where the lifetime of a
3893 child depends solely on the lifetime of its (single) parent. If you need a
3894 value that must persist as long as any of several referrers, read on.
3898 Sometimes you need a variable that is referenced from multiple places
3899 (immutably!), lasting as long as any of those places, and disappearing when it
3900 is no longer referenced. For instance, in a graph-like data structure, a node
3901 might be referenced from all of its neighbors. In this case, it is not possible
3902 for the compiler to determine ahead of time when the value can be freed – it
3903 needs a little run-time support.
3905 Rust's **Rc** type provides shared ownership of a dynamically allocated value
3906 that is automatically freed at the end of its last owner's lifetime. (`Rc`
3907 stands for 'reference counted', referring to the way these library types are
3908 implemented.) This provides more flexibility than single-owner boxes, but has
3909 some runtime overhead.
3911 To create an `Rc` value, use `Rc::new()`. To create a second owner, use the
3920 println!("{} {}", *x, *y); // Prints 5 5
3923 The `Rc` will live as long as any of its owners are alive. After that, the
3924 memory will be `free`d.
3926 **Arc** is an 'atomically reference counted' value, identical to `Rc` except
3927 that ownership can be safely shared among multiple threads. Why two types?
3928 `Arc` has more overhead, so if you're not in a multi-threaded scenario, you
3929 don't have to pay the price.
3931 If you use `Rc` or `Arc`, you have to be careful about introducing cycles. If
3932 you have two `Rc`s that point to each other, they will happily keep each other
3933 alive forever, creating a memory leak. To learn more, check out [the section on
3934 `Rc` and `Arc` in the pointers guide](guide-pointers.html#rc-and-arc).
3938 We've made use of patterns a few times in the guide: first with `let` bindings,
3939 then with `match` statements. Let's go on a whirlwind tour of all of the things
3942 A quick refresher: you can match against literals directly, and `_` acts as an
3949 1 => println!("one"),
3950 2 => println!("two"),
3951 3 => println!("three"),
3952 _ => println!("anything"),
3956 You can match multiple patterns with `|`:
3962 1 | 2 => println!("one or two"),
3963 3 => println!("three"),
3964 _ => println!("anything"),
3968 You can match a range of values with `...`:
3974 1 ... 5 => println!("one through five"),
3975 _ => println!("anything"),
3979 Ranges are mostly used with integers and single characters.
3981 If you're matching multiple things, via a `|` or a `...`, you can bind
3982 the value to a name with `@`:
3988 e @ 1 ... 5 => println!("got a range element {}", e),
3989 _ => println!("anything"),
3993 If you're matching on an enum which has variants, you can use `..` to
3994 ignore the value and type in the variant:
4002 let x = OptionalInt::Value(5);
4005 OptionalInt::Value(..) => println!("Got an i32!"),
4006 OptionalInt::Missing => println!("No such luck."),
4010 You can introduce **match guards** with `if`:
4018 let x = OptionalInt::Value(5);
4021 OptionalInt::Value(i) if i > 5 => println!("Got an i32 bigger than five!"),
4022 OptionalInt::Value(..) => println!("Got an i32!"),
4023 OptionalInt::Missing => println!("No such luck."),
4027 If you're matching on a pointer, you can use the same syntax as you declared it
4034 &val => println!("Got a value: {}", val),
4038 Here, the `val` inside the `match` has type `i32`. In other words, the left-hand
4039 side of the pattern destructures the value. If we have `&5`, then in `&val`, `val`
4042 If you want to get a reference, use the `ref` keyword:
4048 ref r => println!("Got a reference to {}", r),
4052 Here, the `r` inside the `match` has the type `&i32`. In other words, the `ref`
4053 keyword _creates_ a reference, for use in the pattern. If you need a mutable
4054 reference, `ref mut` will work in the same way:
4060 ref mut mr => println!("Got a mutable reference to {}", mr),
4064 If you have a struct, you can destructure it inside of a pattern:
4067 # #![allow(non_shorthand_field_patterns)]
4073 let origin = Point { x: 0, y: 0 };
4076 Point { x: x, y: y } => println!("({},{})", x, y),
4080 If we only care about some of the values, we don't have to give them all names:
4083 # #![allow(non_shorthand_field_patterns)]
4089 let origin = Point { x: 0, y: 0 };
4092 Point { x: x, .. } => println!("x is {}", x),
4096 You can do this kind of match on any member, not just the first:
4099 # #![allow(non_shorthand_field_patterns)]
4105 let origin = Point { x: 0, y: 0 };
4108 Point { y: y, .. } => println!("y is {}", y),
4112 If you want to match against a slice or array, you can use `[]`:
4116 let v = vec!["match_this", "1"];
4118 match v.as_slice() {
4119 ["match_this", second] => println!("The second element is {}", second),
4125 Whew! That's a lot of different ways to match things, and they can all be
4126 mixed and matched, depending on what you're doing:
4130 Foo { x: Some(ref name), y: None } => ...
4134 Patterns are very powerful. Make good use of them.
4138 Functions are great, but if you want to call a bunch of them on some data, it
4139 can be awkward. Consider this code:
4145 We would read this left-to right, and so we see 'baz bar foo.' But this isn't the
4146 order that the functions would get called in, that's inside-out: 'foo bar baz.'
4147 Wouldn't it be nice if we could do this instead?
4150 x.foo().bar().baz();
4153 Luckily, as you may have guessed with the leading question, you can! Rust provides
4154 the ability to use this **method call syntax** via the `impl` keyword.
4156 Here's how it works:
4166 fn area(&self) -> f64 {
4167 std::f64::consts::PI * (self.radius * self.radius)
4172 let c = Circle { x: 0.0, y: 0.0, radius: 2.0 };
4173 println!("{}", c.area());
4177 This will print `12.566371`.
4179 We've made a struct that represents a circle. We then write an `impl` block,
4180 and inside it, define a method, `area`. Methods take a special first
4181 parameter, `&self`. There are three variants: `self`, `&self`, and `&mut self`.
4182 You can think of this first parameter as being the `x` in `x.foo()`. The three
4183 variants correspond to the three kinds of things `x` could be: `self` if it's
4184 just a value on the stack, `&self` if it's a reference, and `&mut self` if it's
4185 a mutable reference. We should default to using `&self`, as it's the most
4188 Finally, as you may remember, the value of the area of a circle is `π*r²`.
4189 Because we took the `&self` parameter to `area`, we can use it just like any
4190 other parameter. Because we know it's a `Circle`, we can access the `radius`
4191 just like we would with any other struct. An import of π and some
4192 multiplications later, and we have our area.
4194 You can also define methods that do not take a `self` parameter. Here's a
4195 pattern that's very common in Rust code:
4198 # #![allow(non_shorthand_field_patterns)]
4206 fn new(x: f64, y: f64, radius: f64) -> Circle {
4216 let c = Circle::new(0.0, 0.0, 2.0);
4220 This **static method** builds a new `Circle` for us. Note that static methods
4221 are called with the `Struct::method()` syntax, rather than the `ref.method()`
4226 So far, we've made lots of functions in Rust, but we've given them all names.
4227 Rust also allows us to create anonymous functions. Rust's anonymous
4228 functions are called **closure**s. By themselves, closures aren't all that
4229 interesting, but when you combine them with functions that take closures as
4230 arguments, really powerful things are possible.
4232 Let's make a closure:
4235 let add_one = |x| { 1 + x };
4237 println!("The sum of 5 plus 1 is {}.", add_one(5));
4240 We create a closure using the `|...| { ... }` syntax, and then we create a
4241 binding so we can use it later. Note that we call the function using the
4242 binding name and two parentheses, just like we would for a named function.
4244 Let's compare syntax. The two are pretty close:
4247 let add_one = |x: i32| -> i32 { 1 + x };
4248 fn add_one (x: i32) -> i32 { 1 + x }
4251 As you may have noticed, closures infer their argument and return types, so you
4252 don't need to declare one. This is different from named functions, which
4253 default to returning unit (`()`).
4255 There's one big difference between a closure and named functions, and it's in
4256 the name: a closure "closes over its environment." What does that mean? It means
4263 let printer = || { println!("x is: {}", x); };
4265 printer(); // prints "x is: 5"
4269 The `||` syntax means this is an anonymous closure that takes no arguments.
4270 Without it, we'd just have a block of code in `{}`s.
4272 In other words, a closure has access to variables in the scope where it's
4273 defined. The closure borrows any variables it uses, so this will error:
4279 let printer = || { println!("x is: {}", x); };
4281 x = 6; // error: cannot assign to `x` because it is borrowed
4287 Rust has a second type of closure, called a **moving closure**. Moving
4288 closures are indicated using the `move` keyword (e.g., `move || x *
4289 x`). The difference between a moving closure and an ordinary closure
4290 is that a moving closure always takes ownership of all variables that
4291 it uses. Ordinary closures, in contrast, just create a reference into
4292 the enclosing stack frame. Moving closures are most useful with Rust's
4293 concurrency features, and so we'll just leave it at this for
4294 now. We'll talk about them more in the "Threads" section of the guide.
4296 ## Accepting closures as arguments
4298 Closures are most useful as an argument to another function. Here's an example:
4301 fn twice(x: i32, f: |i32| -> i32) -> i32 {
4306 let square = |x: i32| { x * x };
4308 twice(5, square); // evaluates to 50
4312 Let's break the example down, starting with `main`:
4315 let square = |x: i32| { x * x };
4318 We've seen this before. We make a closure that takes an integer, and returns
4322 # fn twice(x: i32, f: |i32| -> i32) -> i32 { f(x) + f(x) }
4323 # let square = |x: i32| { x * x };
4324 twice(5, square); // evaluates to 50
4327 This line is more interesting. Here, we call our function, `twice`, and we pass
4328 it two arguments: an integer, `5`, and our closure, `square`. This is just like
4329 passing any other two variable bindings to a function, but if you've never
4330 worked with closures before, it can seem a little complex. Just think: "I'm
4331 passing two variables: one is an i32, and one is a function."
4333 Next, let's look at how `twice` is defined:
4336 fn twice(x: i32, f: |i32| -> i32) -> i32 {
4339 `twice` takes two arguments, `x` and `f`. That's why we called it with two
4340 arguments. `x` is an `i32`, we've done that a ton of times. `f` is a function,
4341 though, and that function takes an `i32` and returns an `i32`. Notice
4342 how the `|i32| -> i32` syntax looks a lot like our definition of `square`
4343 above, if we added the return type in:
4346 let square = |x: i32| -> i32 { x * x };
4350 This function takes an `i32` and returns an `i32`.
4352 This is the most complicated function signature we've seen yet! Give it a read
4353 a few times until you can see how it works. It takes a teeny bit of practice, and
4356 Finally, `twice` returns an `i32` as well.
4358 Okay, let's look at the body of `twice`:
4361 fn twice(x: i32, f: |i32| -> i32) -> i32 {
4366 Since our closure is named `f`, we can call it just like we called our closures
4367 before, and we pass in our `x` argument to each one, hence the name `twice`.
4369 If you do the math, `(5 * 5) + (5 * 5) == 50`, so that's the output we get.
4371 Play around with this concept until you're comfortable with it. Rust's standard
4372 library uses lots of closures where appropriate, so you'll be using
4373 this technique a lot.
4375 If we didn't want to give `square` a name, we could just define it inline.
4376 This example is the same as the previous one:
4379 fn twice(x: i32, f: |i32| -> i32) -> i32 {
4384 twice(5, |x: i32| { x * x }); // evaluates to 50
4388 A named function's name can be used wherever you'd use a closure. Another
4389 way of writing the previous example:
4392 fn twice(x: i32, f: |i32| -> i32) -> i32 {
4396 fn square(x: i32) -> i32 { x * x }
4399 twice(5, square); // evaluates to 50
4403 Doing this is not particularly common, but it's useful every once in a while.
4405 That's all you need to get the hang of closures! Closures are a little bit
4406 strange at first, but once you're used to them, you'll miss them
4407 in other languages. Passing functions to other functions is
4408 incredibly powerful, as you will see in the following chapter about iterators.
4412 Let's talk about loops.
4414 Remember Rust's `for` loop? Here's an example:
4417 for x in range(0, 10) {
4422 Now that you know more Rust, we can talk in detail about how this works. The
4423 `range` function returns an **iterator**. An iterator is something that we can
4424 call the `.next()` method on repeatedly, and it gives us a sequence of things.
4429 let mut range = range(0, 10);
4432 match range.next() {
4441 We make a mutable binding to the return value of `range`, which is our iterator.
4442 We then `loop`, with an inner `match`. This `match` is used on the result of
4443 `range.next()`, which gives us a reference to the next value of the iterator.
4444 `next` returns an `Option<i32>`, in this case, which will be `Some(i32)` when
4445 we have a value and `None` once we run out. If we get `Some(i32)`, we print it
4446 out, and if we get `None`, we `break` out of the loop.
4448 This code sample is basically the same as our `for` loop version. The `for`
4449 loop is just a handy way to write this `loop`/`match`/`break` construct.
4451 `for` loops aren't the only thing that uses iterators, however. Writing your
4452 own iterator involves implementing the `Iterator` trait. While doing that is
4453 outside of the scope of this guide, Rust provides a number of useful iterators
4454 to accomplish various tasks. Before we talk about those, we should talk about a
4455 Rust anti-pattern. And that's `range`.
4457 Yes, we just talked about how `range` is cool. But `range` is also very
4458 primitive. For example, if you needed to iterate over the contents of
4459 a vector, you may be tempted to write this:
4462 let nums = vec![1, 2, 3];
4464 for i in range(0u, nums.len()) {
4465 println!("{}", nums[i]);
4469 This is strictly worse than using an actual iterator. The `.iter()` method on
4470 vectors returns an iterator that iterates through a reference to each element
4471 of the vector in turn. So write this:
4474 let nums = vec![1, 2, 3];
4476 for num in nums.iter() {
4477 println!("{}", num);
4481 There are two reasons for this. First, this more directly expresses what we
4482 mean. We iterate through the entire vector, rather than iterating through
4483 indexes, and then indexing the vector. Second, this version is more efficient:
4484 the first version will have extra bounds checking because it used indexing,
4485 `nums[i]`. But since we yield a reference to each element of the vector in turn
4486 with the iterator, there's no bounds checking in the second example. This is
4487 very common with iterators: we can ignore unnecessary bounds checks, but still
4488 know that we're safe.
4490 There's another detail here that's not 100% clear because of how `println!`
4491 works. `num` is actually of type `&i32`. That is, it's a reference to an `i32`,
4492 not an `i32` itself. `println!` handles the dereferencing for us, so we don't
4493 see it. This code works fine too:
4496 let nums = vec![1, 2, 3];
4498 for num in nums.iter() {
4499 println!("{}", *num);
4503 Now we're explicitly dereferencing `num`. Why does `iter()` give us references?
4504 Well, if it gave us the data itself, we would have to be its owner, which would
4505 involve making a copy of the data and giving us the copy. With references,
4506 we're just borrowing a reference to the data, and so it's just passing
4507 a reference, without needing to do the copy.
4509 So, now that we've established that `range` is often not what you want, let's
4510 talk about what you do want instead.
4512 There are three broad classes of things that are relevant here: iterators,
4513 **iterator adapters**, and **consumers**. Here's some definitions:
4515 * 'iterators' give you a sequence of values.
4516 * 'iterator adapters' operate on an iterator, producing a new iterator with a
4517 different output sequence.
4518 * 'consumers' operate on an iterator, producing some final set of values.
4520 Let's talk about consumers first, since you've already seen an iterator,
4525 A 'consumer' operates on an iterator, returning some kind of value or values.
4526 The most common consumer is `collect()`. This code doesn't quite compile,
4527 but it shows the intention:
4530 let one_to_one_hundred = range(1, 101).collect();
4533 As you can see, we call `collect()` on our iterator. `collect()` takes
4534 as many values as the iterator will give it, and returns a collection
4535 of the results. So why won't this compile? Rust can't determine what
4536 type of things you want to collect, and so you need to let it know.
4537 Here's the version that does compile:
4540 let one_to_one_hundred = range(1, 101).collect::<Vec<i32>>();
4543 If you remember, the `::<>` syntax allows us to give a type hint,
4544 and so we tell it that we want a vector of integers.
4546 `collect()` is the most common consumer, but there are others too. `find()`
4550 let greater_than_forty_two = range(0, 100)
4553 match greater_than_forty_two {
4554 Some(_) => println!("We got some numbers!"),
4555 None => println!("No numbers found :("),
4559 `find` takes a closure, and works on a reference to each element of an
4560 iterator. This closure returns `true` if the element is the element we're
4561 looking for, and `false` otherwise. Because we might not find a matching
4562 element, `find` returns an `Option` rather than the element itself.
4564 Another important consumer is `fold`. Here's what it looks like:
4567 let sum = range(1, 4)
4568 .fold(0, |sum, x| sum + x);
4571 `fold()` is a consumer that looks like this:
4572 `fold(base, |accumulator, element| ...)`. It takes two arguments: the first
4573 is an element called the "base". The second is a closure that itself takes two
4574 arguments: the first is called the "accumulator," and the second is an
4575 "element." Upon each iteration, the closure is called, and the result is the
4576 value of the accumulator on the next iteration. On the first iteration, the
4577 base is the value of the accumulator.
4579 Okay, that's a bit confusing. Let's examine the values of all of these things
4582 | base | accumulator | element | closure result |
4583 |------|-------------|---------|----------------|
4588 We called `fold()` with these arguments:
4592 .fold(0, |sum, x| sum + x);
4595 So, `0` is our base, `sum` is our accumulator, and `x` is our element. On the
4596 first iteration, we set `sum` to `0`, and `x` is the first element of `nums`,
4597 `1`. We then add `sum` and `x`, which gives us `0 + 1 = 1`. On the second
4598 iteration, that value becomes our accumulator, `sum`, and the element is
4599 the second element of the array, `2`. `1 + 2 = 3`, and so that becomes
4600 the value of the accumulator for the last iteration. On that iteration,
4601 `x` is the last element, `3`, and `3 + 3 = 6`, which is our final
4602 result for our sum. `1 + 2 + 3 = 6`, and that's the result we got.
4604 Whew. `fold` can be a bit strange the first few times you see it, but once it
4605 clicks, you can use it all over the place. Any time you have a list of things,
4606 and you want a single result, `fold` is appropriate.
4608 Consumers are important due to one additional property of iterators we haven't
4609 talked about yet: laziness. Let's talk some more about iterators, and you'll
4610 see why consumers matter.
4614 As we've said before, an iterator is something that we can call the
4615 `.next()` method on repeatedly, and it gives us a sequence of things.
4616 Because you need to call the method, this means that iterators
4617 are **lazy** and don't need to generate all of the values upfront.
4618 This code, for example, does not actually generate the numbers
4619 `1-100`, and just creates a value that represents the sequence:
4622 let nums = range(1, 100);
4625 Since we didn't do anything with the range, it didn't generate the sequence.
4626 Let's add the consumer:
4629 let nums = range(1, 100).collect::<Vec<i32>>();
4632 Now, `collect()` will require that `range()` give it some numbers, and so
4633 it will do the work of generating the sequence.
4635 `range` is one of two basic iterators that you'll see. The other is `iter()`,
4636 which you've used before. `iter()` can turn a vector into a simple iterator
4637 that gives you each element in turn:
4640 let nums = [1, 2, 3];
4642 for num in nums.iter() {
4643 println!("{}", num);
4647 These two basic iterators should serve you well. There are some more
4648 advanced iterators, including ones that are infinite. Like `count`:
4651 std::iter::count(1, 5);
4654 This iterator counts up from one, adding five each time. It will give
4655 you a new integer every time, forever (well, technically, until it reaches the
4656 maximum number representable by an `i32`). But since iterators are lazy,
4657 that's okay! You probably don't want to use `collect()` on it, though...
4659 That's enough about iterators. Iterator adapters are the last concept
4660 we need to talk about with regards to iterators. Let's get to it!
4662 ## Iterator adapters
4664 "Iterator adapters" take an iterator and modify it somehow, producing
4665 a new iterator. The simplest one is called `map`:
4668 range(1, 100).map(|x| x + 1);
4671 `map` is called upon another iterator, and produces a new iterator where each
4672 element reference has the closure it's been given as an argument called on it.
4673 So this would give us the numbers from `2-100`. Well, almost! If you
4674 compile the example, you'll get a warning:
4677 warning: unused result which must be used: iterator adaptors are lazy and
4678 do nothing unless consumed, #[warn(unused_must_use)] on by default
4679 range(1, 100).map(|x| x + 1);
4680 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4683 Laziness strikes again! That closure will never execute. This example
4684 doesn't print any numbers:
4687 range(1, 100).map(|x| println!("{}", x));
4690 If you are trying to execute a closure on an iterator for its side effects,
4691 just use `for` instead.
4693 There are tons of interesting iterator adapters. `take(n)` will return an
4694 iterator over the next `n` elements of the original iterator, note that this
4695 has no side effect on the original iterator. Let's try it out with our infinite
4696 iterator from before, `count()`:
4699 for i in std::iter::count(1, 5).take(5) {
4714 `filter()` is an adapter that takes a closure as an argument. This closure
4715 returns `true` or `false`. The new iterator `filter()` produces
4716 only the elements that that closure returns `true` for:
4719 for i in range(1, 100).filter(|&x| x % 2 == 0) {
4724 This will print all of the even numbers between one and a hundred.
4725 (Note that because `filter` doesn't consume the elements that are
4726 being iterated over, it is passed a reference to each element, and
4727 thus the filter predicate uses the `&x` pattern to extract the integer
4730 You can chain all three things together: start with an iterator, adapt it
4731 a few times, and then consume the result. Check it out:
4735 .filter(|&x| x % 2 == 0)
4736 .filter(|&x| x % 3 == 0)
4738 .collect::<Vec<i32>>();
4741 This will give you a vector containing `6`, `12`, `18`, `24`, and `30`.
4743 This is just a small taste of what iterators, iterator adapters, and consumers
4744 can help you with. There are a number of really useful iterators, and you can
4745 write your own as well. Iterators provide a safe, efficient way to manipulate
4746 all kinds of lists. They're a little unusual at first, but if you play with
4747 them, you'll get hooked. For a full list of the different iterators and
4748 consumers, check out the [iterator module documentation](std/iter/index.html).
4752 Sometimes, when writing a function or data type, we may want it to work for
4753 multiple types of arguments. For example, remember our `OptionalInt` type?
4762 If we wanted to also have an `OptionalFloat64`, we would need a new enum:
4765 enum OptionalFloat64 {
4771 Such repetition is unfortunate. Luckily, Rust has a feature that gives us a
4772 better way: **generics**. Generics are called **parametric polymorphism** in
4773 type theory, which means that they are types or functions that have multiple
4774 forms over a given parameter ("parametric").
4776 Let's see how generics help us escape `OptionalInt`. `Option` is already
4777 provided in Rust's standard library and looks like this:
4786 The `<T>` part, which you've seen a few times before, indicates that this is a
4787 generic data type. `T` is called a **type parameter**. When we create instances
4788 of `Option`, we need to provide a concrete type in place of the type
4789 parameter. For example, if we wanted something like our `OptionalInt`, we would
4790 need to instantiate an `Option<i32>`. Inside the declaration of our enum,
4791 wherever we see a `T`, we replace it with the type specified (or inferred by the
4795 let x: Option<i32> = Some(5);
4798 In this particular `Option`, `T` has the value of `i32`. On the right-hand side
4799 of the binding, we do make a `Some(T)`, where `T` is `5`. Since that's an
4800 `i32`, the two sides match, and Rust is happy. If they didn't match, we'd get an
4804 let x: Option<f64> = Some(5);
4805 // error: mismatched types: expected `core::option::Option<f64>`,
4806 // found `core::option::Option<i32>` (expected f64, found i32)
4809 That doesn't mean we can't make `Option<T>`s that hold an `f64`! They just have to
4813 let x: Option<i32> = Some(5);
4814 let y: Option<f64> = Some(5.0f64);
4817 Generics don't have to only be generic over one type. Consider Rust's built-in
4818 `Result<T, E>` type:
4827 This type is generic over _two_ types: `T` and `E`. By the way, the capital letters
4828 can be any letter you'd like. We could define `Result<T, E>` as:
4837 Convention says that the first generic parameter should be `T`, for "type," and
4838 that we use `E` for "error."
4840 The `Result<T, E>` type is intended to be used to return the result of a
4841 computation and to have the ability to return an error if it didn't work
4842 out. Here's an example:
4845 let x: Result<f64, String> = Ok(2.3f64);
4846 let y: Result<f64, String> = Err("There was an error.".to_string());
4849 This particular `Result` will return an `f64` upon success and a `String` if
4850 there's a failure. Let's write a function that uses `Result<T, E>`:
4853 fn inverse(x: f64) -> Result<f64, String> {
4854 if x == 0.0f64 { return Err("x cannot be zero!".to_string()); }
4860 We want to indicate that `inverse(0.0f64)` is undefined or is an erroneous usage
4861 of the function, so we check to make sure that we weren't passed zero. If we
4862 were, we return an `Err` with a message. If it's okay, we return an `Ok` with
4865 Why does this matter? Well, remember how `match` does exhaustive matches?
4866 Here's how this function gets used:
4869 # fn inverse(x: f64) -> Result<f64, String> {
4870 # if x == 0.0f64 { return Err("x cannot be zero!".to_string()); }
4873 let x = inverse(25.0f64);
4876 Ok(x) => println!("The inverse of 25 is {}", x),
4877 Err(msg) => println!("Error: {}", msg),
4881 The `match` enforces that we handle the `Err` case. In addition, because the
4882 answer is wrapped up in an `Ok`, we can't just use the result without doing
4886 let x = inverse(25.0f64);
4887 println!("{}", x + 2.0f64); // error: binary operation `+` cannot be applied
4888 // to type `core::result::Result<f64,collections::string::String>`
4891 This function is great, but there's one other problem: it only works for 64 bit
4892 floating point values. If we wanted to handle 32 bit floating point values we'd
4896 fn inverse32(x: f32) -> Result<f32, String> {
4897 if x == 0.0f32 { return Err("x cannot be zero!".to_string()); }
4903 What we need is a **generic function**. We can do that with Rust! However, it
4904 won't _quite_ work yet. We need to talk about syntax. A first attempt at a
4905 generic version of `inverse` might look something like this:
4908 fn inverse<T>(x: T) -> Result<T, String> {
4909 if x == 0.0 { return Err("x cannot be zero!".to_string()); }
4915 Just like how we had `Option<T>`, we use a similar syntax for `inverse<T>`. We
4916 can then use `T` inside the rest of the signature: `x` has type `T`, and half of
4917 the `Result` has type `T`. However, if we try to compile that example, we'll get
4921 error: binary operation `==` cannot be applied to type `T`
4922 if x == 0.0 { return Err("x cannot be zero!".to_string()); }
4924 error: mismatched types: expected `_`, found `T` (expected floating-point variable, found type parameter)
4927 error: mismatched types: expected `core::result::Result<T, collections::string::String>`, found `core::result::Result<_, _>` (expected type parameter, found floating-point variable)
4932 The problem is that `T` is unconstrained: it can be _any_ type. It could be a
4933 `String`, and the expression `1.0 / x` has no meaning if `x` is a `String`. It
4934 may be a type that doesn't implement `==`, and the first line would be
4935 wrong. What do we do?
4937 To fix this example, we need to learn about another Rust feature: **traits**.
4941 Our discussion of **traits** begins with the `impl` keyword. We used it before
4952 fn area(&self) -> f64 {
4953 std::f64::consts::PI * (self.radius * self.radius)
4958 We define a trait in terms of its methods. We then `impl` a trait `for` a type
4969 fn area(&self) -> f64;
4972 impl HasArea for Circle {
4973 fn area(&self) -> f64 {
4974 std::f64::consts::PI * (self.radius * self.radius)
4979 The `trait` block defines only type signatures. When we `impl` a trait, we use
4980 `impl Trait for Item`, rather than just `impl Item`.
4982 The first of the three errors we got with our generic `inverse` function was
4986 error: binary operation `==` cannot be applied to type `T`
4989 We can use traits to constrain generic type parameters. Consider this function,
4990 which does not compile, and gives us a similar error:
4993 fn print_area<T>(shape: T) {
4994 println!("This shape has an area of {}", shape.area());
5001 error: type `T` does not implement any method in scope named `area`
5004 Because `T` can be any type, we can't be sure that it implements the `area`
5005 method. But we can add a **trait constraint** to our generic `T`, ensuring that
5006 we can only compile the function if it's called with types which `impl` the
5011 # fn area(&self) -> f64;
5013 fn print_area<T: HasArea>(shape: T) {
5014 println!("This shape has an area of {}", shape.area());
5018 The syntax `<T: HasArea>` means "any type that implements the HasArea trait."
5019 Because traits define method signatures, we can be sure that any type which
5020 implements `HasArea` will have an `area` method.
5022 Here's an extended example of how this works:
5026 fn area(&self) -> f64;
5035 impl HasArea for Circle {
5036 fn area(&self) -> f64 {
5037 std::f64::consts::PI * (self.radius * self.radius)
5047 impl HasArea for Square {
5048 fn area(&self) -> f64 {
5049 self.side * self.side
5053 fn print_area<T: HasArea>(shape: T) {
5054 println!("This shape has an area of {}", shape.area());
5075 This program outputs:
5078 This shape has an area of 3.141593
5079 This shape has an area of 1
5082 As you can see, `print_area` is now generic, but also ensures that we
5083 have passed in the correct types. If we pass in an incorrect type:
5089 We get a compile-time error:
5092 error: failed to find an implementation of trait main::HasArea for i32
5095 So far, we've only added trait implementations to structs, but you can
5096 implement a trait for any type. So technically, we _could_ implement
5097 `HasArea` for `i32`:
5101 fn area(&self) -> f64;
5104 impl HasArea for i32 {
5105 fn area(&self) -> f64 {
5106 println!("this is silly");
5115 It is considered poor style to implement methods on such primitive types, even
5116 though it is possible.
5118 ## Scoped Method Resolution and Orphan `impl`s
5120 There are two restrictions for implementing traits that prevent this from
5121 getting out of hand.
5123 1. **Scope-based Method Resolution**: Traits must be `use`d in any scope where
5124 you wish to use the trait's methods
5125 2. **No Orphan `impl`s**: Either the trait or the type you're writing the `impl`
5126 for must be inside your crate.
5128 If we organize our crate differently by using modules, we'll need to ensure both
5129 of the conditions are satisfied. Don't worry, you can lean on the compiler since
5130 it won't let you get away with violating them.
5133 use shapes::HasArea; // satisfies #1
5136 use std::f64::consts;
5139 fn area(&self) -> f64;
5148 impl HasArea for Circle {
5149 fn area(&self) -> f64 {
5150 consts::PI * (self.radius * self.radius)
5156 // use shapes::HasArea; // This would satisfy #1, too
5157 let c = shapes::Circle {
5163 println!("{}", c.area());
5167 Requiring us to `use` traits whose methods we want means that even if someone
5168 does something bad like add methods to `i32`, it won't affect us, unless you
5171 The second condition allows us to `impl` built-in `trait`s for types we define,
5172 or allows us to `impl` our own `trait`s for built-in types, but restricts us
5173 from mixing and matching third party or built-in `impl`s with third party or
5176 We could `impl` the `HasArea` trait for `i32`, because `HasArea` is in our
5177 crate. But if we tried to implement `Float`, a standard library `trait`, for
5178 `i32`, we could not, because neither the `trait` nor the `type` are in our
5183 One last thing about generics and traits: the compiler performs
5184 **monomorphization** on generic functions so they are statically dispatched. To
5185 see what that means, let's take a look at `print_area` again:
5188 fn print_area<T: HasArea>(shape: T) {
5189 println!("This shape has an area of {}", shape.area());
5193 let c = Circle { ... };
5195 let s = Square { ... };
5202 Because we have called `print_area` with two different types in place of its
5203 type paramater `T`, Rust will generate two versions of the function with the
5204 appropriate concrete types, replacing the call sites with calls to the concrete
5205 implementations. In other words, the compiler will actually compile something
5209 fn __print_area_circle(shape: Circle) {
5210 println!("This shape has an area of {}", shape.area());
5213 fn __print_area_square(shape: Square) {
5214 println!("This shape has an area of {}", shape.area());
5218 let c = Circle { ... };
5220 let s = Square { ... };
5222 __print_area_circle(c);
5223 __print_area_square(s);
5227 These names are for illustration; the compiler will generate its own cryptic
5228 names for internal uses. The point is that there is no runtime overhead of
5229 deciding which version to call. The function to be called is determined
5230 statically, at compile time. Thus, generic functions are **statically
5231 dispatched**. The downside is that we have two similar functions, so our binary
5236 Concurrency and parallelism are topics that are of increasing interest to a
5237 broad subsection of software developers. Modern computers are often multi-core,
5238 to the point that even embedded devices like cell phones have more than one
5239 processor. Rust's semantics lend themselves very nicely to solving a number of
5240 issues that programmers have with concurrency. Many concurrency errors that are
5241 runtime errors in other languages are compile-time errors in Rust.
5243 Rust's concurrency primitive is called a **thread**. It's worth noting that
5244 threads are implemented as a library, and not part of the language. This means
5245 that in the future, other concurrency libraries can be written for Rust to help
5246 in specific scenarios. Here's an example of creating a thread:
5250 println!("Hello from a thread!");
5254 The `spawn` function takes a closure as an argument, and runs that
5255 closure in a new thread. Typically, you will want to use a moving
5256 closure, so that the closure takes ownership of any variables that it
5257 touches. This implies that those variables are not usable from the
5258 parent thread after the child thread is spawned:
5261 let mut x = vec![1, 2, 3];
5264 println!("The value of x[0] is: {}", x[0]);
5267 println!("The value of x[0] is: {}", x[0]); // error: use of moved value: `x`
5270 `x` is now owned by the closure, and so we can't use it anymore. Many
5271 other languages would let us do this, but it's not safe to do
5272 so. Rust's borrow checker catches the error.
5274 If threads were only able to capture these values, they wouldn't be very useful.
5275 Luckily, threads can communicate with each other through **channel**s. Channels
5279 let (tx, rx) = channel();
5282 tx.send("Hello from a thread!".to_string());
5285 let message = rx.recv();
5286 println!("{}", message);
5289 The `channel()` function returns two endpoints: a `Receiver<T>` and a
5290 `Sender<T>`. You can use the `.send()` method on the `Sender<T>` end, and
5291 receive the message on the `Receiver<T>` side with the `recv()` method. This
5292 method blocks until it gets a message. There's a similar method, `.try_recv()`,
5293 which returns an `Result<T, TryRecvError>` and does not block.
5295 If you want to send messages to the thread as well, create two channels!
5298 let (tx1, rx1) = channel();
5299 let (tx2, rx2) = channel();
5302 tx1.send("Hello from a thread!".to_string());
5303 let message = rx2.recv();
5304 println!("{}", message);
5307 let message = rx1.recv();
5308 println!("{}", message);
5310 tx2.send("Goodbye from main!".to_string());
5313 The closure has one sending end and one receiving end, and the main thread has
5314 one of each as well. Now they can talk back and forth in whatever way they
5317 Notice as well that because `Sender` and `Receiver` are generic, while you can
5318 pass any kind of information through the channel, the ends are strongly typed.
5319 If you try to pass a string, and then an integer, Rust will complain.
5323 With these basic primitives, many different concurrency patterns can be
5324 developed. Rust includes some of these types in its standard library. For
5325 example, if you wish to compute some value in the background, `Future` is
5326 a useful thing to use:
5329 # #![allow(deprecated)]
5330 use std::sync::Future;
5332 let mut delayed_value = Future::spawn(move || {
5333 // just return anything for examples' sake
5337 println!("value = {}", delayed_value.get());
5340 Calling `Future::spawn` works just like `spawn()`: it takes a
5341 closure. In this case, though, you don't need to mess with the
5342 channel: just have the closure return the value.
5344 `Future::spawn` will return a value which we can bind with `let`. It needs
5345 to be mutable, because once the value is computed, it saves a copy of the
5346 value, and if it were immutable, it couldn't update itself.
5348 The future will go on processing in the background, and when we need
5349 the final value, we can call `get()` on it. This will block until the
5350 result is done, but if it's finished computing in the background,
5351 we'll just get the value immediately.
5353 ## Success and failure
5355 Threads don't always succeed, they can also panic. A thread that wishes to panic
5356 can call the `panic!` macro, passing a message:
5364 If a thread panics, it is not possible for it to recover. However, it can
5365 notify other thread that it has panicked. We can do this with `thread::try`:
5371 let result = thread::try(move || {
5380 This thread will randomly panic or succeed. `thread::try` returns a `Result`
5381 type, so we can handle the response like any other computation that may
5386 One of Rust's most advanced features is its system of **macro**s. While
5387 functions allow you to provide abstractions over values and operations, macros
5388 allow you to provide abstractions over syntax. Do you wish Rust had the ability
5389 to do something that it can't currently do? You may be able to write a macro
5390 to extend Rust's capabilities.
5392 You've already used one macro extensively: `println!`. When we invoke
5393 a Rust macro, we need to use the exclamation mark (`!`). There are two reasons
5394 why this is so: the first is that it makes it clear when you're using a
5395 macro. The second is that macros allow for flexible syntax, and so Rust must
5396 be able to tell where a macro starts and ends. The `!(...)` helps with this.
5398 Let's talk some more about `println!`. We could have implemented `println!` as
5399 a function, but it would be worse. Why? Well, what macros allow you to do
5400 is write code that generates more code. So when we call `println!` like this:
5404 println!("x is: {}", x);
5407 The `println!` macro does a few things:
5409 1. It parses the string to find any `{}`s.
5410 2. It checks that the number of `{}`s matches the number of other arguments.
5411 3. It generates a bunch of Rust code, taking this in mind.
5413 What this means is that you get type checking at compile time, because
5414 Rust will generate code that takes all of the types into account. If
5415 `println!` was a function, it could still do this type checking, but it
5416 would happen at run time rather than compile time.
5418 We can check this out using a special flag to `rustc`. Put this code in a file
5424 println!("x is: {}", x);
5428 You can have the macros expanded like this: `rustc --pretty=expanded print.rs`, which will
5429 give us this huge result:
5435 #[phase(plugin, link)]
5436 extern crate "std" as std;
5437 extern crate "native" as rt;
5439 use std::prelude::*;
5446 static __STATIC_FMTSTR: [&'static str, ..1u] = ["x is: "];
5448 &[::std::fmt::argument(::std::fmt::secret_show, __arg0)];
5451 ::std::fmt::Arguments::new(__STATIC_FMTSTR, __args_vec)
5453 ::std::io::stdio::println_args(&__args)
5459 Whew! This isn't too terrible. You can see that we still `let x = 5`,
5460 but then things get a little bit hairy. Three more bindings get set: a
5461 static format string, an argument vector, and the arguments. We then
5462 invoke the `println_args` function with the generated arguments.
5464 This is the code that Rust actually compiles. You can see all of the extra
5465 information that's here. We get all of the type safety and options that it
5466 provides, but at compile time, and without needing to type all of this out.
5467 This is how macros are powerful: without them you would need to type all of
5468 this by hand to get a type-checked `println`.
5470 For more on macros, please consult [the Macros Guide](guide-macros.html).
5471 Macros are a very advanced and still slightly experimental feature, but they don't
5472 require a deep understanding to be called, since they look just like functions. The
5473 Guide can help you if you want to write your own.
5477 Finally, there's one more Rust concept that you should be aware of: `unsafe`.
5478 There are two circumstances where Rust's safety provisions don't work well.
5479 The first is when interfacing with C code, and the second is when building
5480 certain kinds of abstractions.
5482 Rust has support for [FFI](http://en.wikipedia.org/wiki/Foreign_function_interface)
5483 (which you can read about in the [FFI Guide](guide-ffi.html)), but can't guarantee
5484 that the C code will be safe. Therefore, Rust marks such functions with the `unsafe`
5485 keyword, which indicates that the function may not behave properly.
5487 Second, if you'd like to create some sort of shared-memory data structure, Rust
5488 won't allow it, because memory must be owned by a single owner. However, if
5489 you're planning on making access to that shared memory safe – such as with a
5490 mutex – _you_ know that it's safe, but Rust can't know. Writing an `unsafe`
5491 block allows you to ask the compiler to trust you. In this case, the _internal_
5492 implementation of the mutex is considered unsafe, but the _external_ interface
5493 we present is safe. This allows it to be effectively used in normal Rust, while
5494 being able to implement functionality that the compiler can't double check for
5497 Doesn't an escape hatch undermine the safety of the entire system? Well, if
5498 Rust code segfaults, it _must_ be because of unsafe code somewhere. By
5499 annotating exactly where that is, you have a significantly smaller area to
5502 We haven't even talked about any examples here, and that's because I want to
5503 emphasize that you should not be writing unsafe code unless you know exactly
5504 what you're doing. The vast majority of Rust developers will only interact with
5505 it when doing FFI, and advanced library authors may use it to build certain
5506 kinds of abstraction.
5510 We covered a lot of ground here. When you've mastered everything in this Guide,
5511 you will have a firm grasp of basic Rust development. There's a whole lot more
5512 out there, we've just covered the surface. There's tons of topics that you can
5513 dig deeper into, and we've built specialized guides for many of them. To learn
5514 more, dig into the [full documentation index](index.html).