├── .gitignore ├── intermediate.md ├── basic.md ├── advanced.md ├── conclusion.md ├── glossary.md ├── SUMMARY.md ├── comments.md ├── README.md ├── strings.md ├── arrays-vectors-and-slices.md ├── looping.md ├── installing-rust.md ├── patterns.md ├── match.md ├── standard-input.md ├── if.md ├── functions.md ├── hello-cargo.md ├── generics.md ├── variable-bindings.md ├── associated-types.md ├── method-syntax.md ├── hello-world.md ├── more-strings.md ├── closures.md ├── advanced-macros.md ├── error-handling.md ├── plugins.md ├── static-and-dynamic-dispatch.md ├── compound-data-types.md ├── concurrency.md ├── traits.md ├── iterators.md ├── macros.md └── documentation.md /.gitignore: -------------------------------------------------------------------------------- 1 | _book 2 | -------------------------------------------------------------------------------- /intermediate.md: -------------------------------------------------------------------------------- 1 | % Intermediate 2 | 3 | This section contains individual chapters, which are self-contained. They focus 4 | on specific topics, and can be read in any order. 5 | 6 | After reading "Intermediate," you will have a solid understanding of Rust, 7 | and will be able to understand most Rust code and write more complex programs. 8 | -------------------------------------------------------------------------------- /basic.md: -------------------------------------------------------------------------------- 1 | % Basics 2 | 3 | This section is a linear introduction to the basic syntax and semantics of 4 | Rust. It has individual sections on each part of Rust's syntax, and cumulates 5 | in a small project: a guessing game. 6 | 7 | After reading "Basics," you will have a good foundation to learn more about 8 | Rust, and can write very simple programs. 9 | -------------------------------------------------------------------------------- /advanced.md: -------------------------------------------------------------------------------- 1 | % Advanced 2 | 3 | In a similar fashion to "Intermediate," this section is full of individual, 4 | deep-dive chapters, which stand alone and can be read in any order. These 5 | chapters focus on the most complex features, as well as some things that 6 | are only available in upcoming versions of Rust. 7 | 8 | After reading "Advanced," you'll be a Rust expert! 9 | -------------------------------------------------------------------------------- /conclusion.md: -------------------------------------------------------------------------------- 1 | % Conclusion 2 | 3 | We covered a lot of ground here. When you've mastered everything in this Guide, 4 | you will have a firm grasp of Rust development. There's a whole lot more 5 | out there, though, we've just covered the surface. There's tons of topics that 6 | you can dig deeper into, e.g. by reading the API documentation of the 7 | [standard library](http://doc.rust-lang.org/std/), by discovering solutions for 8 | common problems on [Rust by Example](http://rustbyexample.com/), or by browsing 9 | crates written by the community on [crates.io](https://crates.io/). 10 | 11 | Happy hacking! 12 | -------------------------------------------------------------------------------- /glossary.md: -------------------------------------------------------------------------------- 1 | % Glossary 2 | 3 | Not every Rustacean has a background in systems programming, nor in computer 4 | science, so we've added explanations of terms that might be unfamiliar. 5 | 6 | ### Arity 7 | 8 | Arity refers to the number of arguments a function or operation takes. 9 | 10 | ```rust 11 | let x = (2, 3); 12 | let y = (4, 6); 13 | let z = (8, 2, 6); 14 | ``` 15 | 16 | In the example above `x` and `y` have arity 2. `z` has arity 3. 17 | 18 | ### Abstract Syntax Tree 19 | 20 | When a compiler is compiling your program, it does a number of different 21 | things. One of the things that it does is turn the text of your program into an 22 | 'abstract syntax tree,' or 'AST.' This tree is a representation of the 23 | structure of your program. For example, `2 + 3` can be turned into a tree: 24 | 25 | ```text 26 | + 27 | / \ 28 | 2 3 29 | ``` 30 | 31 | And `2 + (3 * 4)` would look like this: 32 | 33 | ```text 34 | + 35 | / \ 36 | 2 * 37 | / \ 38 | 3 4 39 | ``` 40 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [The Basics](basic.md) 4 | * [Installing Rust](installing-rust.md) 5 | * [Hello, world!](hello-world.md) 6 | * [Hello, Cargo!](hello-cargo.md) 7 | * [Variable Bindings](variable-bindings.md) 8 | * [If](if.md) 9 | * [Functions](functions.md) 10 | * [Comments](comments.md) 11 | * [Compound Data Types](compound-data-types.md) 12 | * [Match](match.md) 13 | * [Looping](looping.md) 14 | * [Strings](strings.md) 15 | * [Arrays, Vectors, and Slices](arrays-vectors-and-slices.md) 16 | * [Standard Input](standard-input.md) 17 | * [Intermediate Rust](intermediate.md) 18 | * [Crates and Modules](crates-and-modules.md) 19 | * [Testing](testing.md) 20 | * [Pointers](pointers.md) 21 | * [Ownership](ownership.md) 22 | * [More Strings](more-strings.md) 23 | * [Patterns](patterns.md) 24 | * [Method Syntax](method-syntax.md) 25 | * [Associated Types](associated-types.md) 26 | * [Closures](closures.md) 27 | * [Iterators](iterators.md) 28 | * [Generics](generics.md) 29 | * [Traits](traits.md) 30 | * [Static and Dynamic Dispatch](static-and-dynamic-dispatch.md) 31 | * [Macros](macros.md) 32 | * [Concurrency](concurrency.md) 33 | * [Error Handling](error-handling.md) 34 | * [Documentation](documentation.md) 35 | * [Advanced Topics](advanced.md) 36 | * [FFI](ffi.md) 37 | * [Unsafe Code](unsafe.md) 38 | * [Advanced Macros](advanced-macros.md) 39 | * [Compiler Plugins](plugins.md) 40 | * [Conclusion](conclusion.md) 41 | * [Glossary](glossary.md) 42 | -------------------------------------------------------------------------------- /comments.md: -------------------------------------------------------------------------------- 1 | % Comments 2 | 3 | Now that we have some functions, it's a good idea to learn about comments. 4 | Comments are notes that you leave to other programmers to help explain things 5 | about your code. The compiler mostly ignores them. 6 | 7 | Rust has two kinds of comments that you should care about: *line comments* 8 | and *doc comments*. 9 | 10 | ```{rust} 11 | // Line comments are anything after '//' and extend to the end of the line. 12 | 13 | let x = 5; // this is also a line comment. 14 | 15 | // If you have a long explanation for something, you can put line comments next 16 | // to each other. Put a space between the // and your comment so that it's 17 | // more readable. 18 | ``` 19 | 20 | The other kind of comment is a doc comment. Doc comments use `///` instead of 21 | `//`, and support Markdown notation inside: 22 | 23 | ```{rust} 24 | /// `hello` is a function that prints a greeting that is personalized based on 25 | /// the name given. 26 | /// 27 | /// # Arguments 28 | /// 29 | /// * `name` - The name of the person you'd like to greet. 30 | /// 31 | /// # Examples 32 | /// 33 | /// ```rust 34 | /// let name = "Steve"; 35 | /// hello(name); // prints "Hello, Steve!" 36 | /// ``` 37 | fn hello(name: &str) { 38 | println!("Hello, {}!", name); 39 | } 40 | ``` 41 | 42 | When writing doc comments, adding sections for any arguments, return values, 43 | and providing some examples of usage is very, very helpful. Don't worry about 44 | the `&str`, we'll get to it soon. 45 | 46 | You can use the [`rustdoc`](documentation.html) tool to generate HTML documentation 47 | from these doc comments. 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | % The Rust Programming Language 2 | 3 | Welcome! This book will teach you about [the Rust Programming 4 | Language](http://www.rust-lang.org/). Rust is a modern systems programming 5 | language focusing on safety and speed. It accomplishes these goals by being 6 | memory safe without using garbage collection. 7 | 8 | "The Rust Programming Language" is split into three sections, which you can 9 | navigate through the menu on the left. 10 | 11 |

Basics

12 | 13 | This section is a linear introduction to the basic syntax and semantics of 14 | Rust. It has individual sections on each part of Rust's syntax, and culminates 15 | in a small project: a guessing game. 16 | 17 | After reading "Basics," you will have a good foundation to learn more about 18 | Rust, and can write very simple programs. 19 | 20 |

Intermediate

21 | 22 | This section contains individual chapters, which are self-contained. They focus 23 | on specific topics, and can be read in any order. 24 | 25 | After reading "Intermediate," you will have a solid understanding of Rust, 26 | and will be able to understand most Rust code and write more complex programs. 27 | 28 |

Advanced

29 | 30 | In a similar fashion to "Intermediate," this section is full of individual, 31 | deep-dive chapters, which stand alone and can be read in any order. These 32 | chapters focus on the most complex features, as well as some things that 33 | are only available in upcoming versions of Rust. 34 | 35 | After reading "Advanced," you'll be a Rust expert! 36 | -------------------------------------------------------------------------------- /strings.md: -------------------------------------------------------------------------------- 1 | % Strings 2 | 3 | Strings are an important concept for any programmer to master. Rust's string 4 | handling system is a bit different from other languages, due to its systems 5 | focus. Any time you have a data structure of variable size, things can get 6 | tricky, and strings are a re-sizable data structure. That being said, Rust's 7 | strings also work differently than in some other systems languages, such as C. 8 | 9 | Let's dig into the details. A *string* is a sequence of Unicode scalar values 10 | encoded as a stream of UTF-8 bytes. All strings are guaranteed to be 11 | validly encoded UTF-8 sequences. Additionally, strings are not null-terminated 12 | and can contain null bytes. 13 | 14 | Rust has two main types of strings: `&str` and `String`. 15 | 16 | The first kind is a `&str`. These are called *string slices*. String literals 17 | are of the type `&str`: 18 | 19 | ```{rust} 20 | let string = "Hello there."; // string: &str 21 | ``` 22 | 23 | This string is statically allocated, meaning that it's saved inside our 24 | compiled program, and exists for the entire duration it runs. The `string` 25 | binding is a reference to this statically allocated string. String slices 26 | have a fixed size, and cannot be mutated. 27 | 28 | A `String`, on the other hand, is a heap-allocated string. This string 29 | is growable, and is also guaranteed to be UTF-8. `String`s are 30 | commonly created by converting from a string slice using the 31 | `to_string` method. 32 | 33 | ```{rust} 34 | let mut s = "Hello".to_string(); // mut s: String 35 | println!("{}", s); 36 | 37 | s.push_str(", world."); 38 | println!("{}", s); 39 | ``` 40 | 41 | `String`s will coerce into `&str` with an `&`: 42 | 43 | ``` 44 | fn takes_slice(slice: &str) { 45 | println!("Got: {}", slice); 46 | } 47 | 48 | fn main() { 49 | let s = "Hello".to_string(); 50 | takes_slice(&s); 51 | } 52 | ``` 53 | 54 | Viewing a `String` as a `&str` is cheap, but converting the `&str` to a 55 | `String` involves allocating memory. No reason to do that unless you have to! 56 | 57 | That's the basics of strings in Rust! They're probably a bit more complicated 58 | than you are used to, if you come from a scripting language, but when the 59 | low-level details matter, they really matter. Just remember that `String`s 60 | allocate memory and control their data, while `&str`s are a reference to 61 | another string, and you'll be all set. 62 | -------------------------------------------------------------------------------- /arrays-vectors-and-slices.md: -------------------------------------------------------------------------------- 1 | % Arrays, Vectors, and Slices 2 | 3 | Like many programming languages, Rust has list types to represent a sequence of 4 | things. The most basic is the *array*, a fixed-size list of elements of the 5 | same type. By default, arrays are immutable. 6 | 7 | ```{rust} 8 | let a = [1, 2, 3]; // a: [i32; 3] 9 | let mut m = [1, 2, 3]; // mut m: [i32; 3] 10 | ``` 11 | 12 | There's a shorthand for initializing each element of an array to the same 13 | value. In this example, each element of `a` will be initialized to `0`: 14 | 15 | ```{rust} 16 | let a = [0; 20]; // a: [i32; 20] 17 | ``` 18 | 19 | Arrays have type `[T; N]`. We'll talk about this `T` notation later, when we 20 | cover generics. 21 | 22 | You can get the number of elements in an array `a` with `a.len()`, and use 23 | `a.iter()` to iterate over them with a for loop. This code will print each 24 | number in order: 25 | 26 | ```{rust} 27 | let a = [1, 2, 3]; 28 | 29 | println!("a has {} elements", a.len()); 30 | for e in a.iter() { 31 | println!("{}", e); 32 | } 33 | ``` 34 | 35 | You can access a particular element of an array with *subscript notation*: 36 | 37 | ```{rust} 38 | let names = ["Graydon", "Brian", "Niko"]; // names: [&str; 3] 39 | 40 | println!("The second name is: {}", names[1]); 41 | ``` 42 | 43 | Subscripts start at zero, like in most programming languages, so the first name 44 | is `names[0]` and the second name is `names[1]`. The above example prints 45 | `The second name is: Brian`. If you try to use a subscript that is not in the 46 | array, you will get an error: array access is bounds-checked at run-time. Such 47 | errant access is the source of many bugs in other systems programming 48 | languages. 49 | 50 | A *vector* is a dynamic or "growable" array, implemented as the standard 51 | library type [`Vec`](../std/vec/) (we'll talk about what the `` means 52 | later). Vectors always allocate their data on the heap. Vectors are to slices 53 | what `String` is to `&str`. You can create them with the `vec!` macro: 54 | 55 | ```{rust} 56 | let v = vec![1, 2, 3]; // v: Vec 57 | ``` 58 | 59 | (Notice that unlike the `println!` macro we've used in the past, we use square 60 | brackets `[]` with `vec!`. Rust allows you to use either in either situation, 61 | this is just convention.) 62 | 63 | There's an alternate form of `vec!` for repeating an initial value: 64 | 65 | ``` 66 | let v = vec![0; 10]; // ten zeroes 67 | ``` 68 | 69 | You can get the length of, iterate over, and subscript vectors just like 70 | arrays. In addition, (mutable) vectors can grow automatically: 71 | 72 | ```{rust} 73 | let mut nums = vec![1, 2, 3]; // mut nums: Vec 74 | 75 | nums.push(4); 76 | 77 | println!("The length of nums is now {}", nums.len()); // Prints 4 78 | ``` 79 | 80 | Vectors have many more useful methods. 81 | 82 | A *slice* is a reference to (or "view" into) an array. They are useful for 83 | allowing safe, efficient access to a portion of an array without copying. For 84 | example, you might want to reference just one line of a file read into memory. 85 | By nature, a slice is not created directly, but from an existing variable. 86 | Slices have a length, can be mutable or not, and in many ways behave like 87 | arrays: 88 | 89 | ```{rust} 90 | let a = [0, 1, 2, 3, 4]; 91 | let middle = &a[1..4]; // A slice of a: just the elements 1, 2, and 3 92 | 93 | for e in middle.iter() { 94 | println!("{}", e); // Prints 1, 2, 3 95 | } 96 | ``` 97 | 98 | You can also take a slice of a vector, `String`, or `&str`, because they are 99 | backed by arrays. Slices have type `&[T]`, which we'll talk about when we cover 100 | generics. 101 | 102 | We have now learned all of the most basic Rust concepts. We're ready to start 103 | building ourselves a guessing game, we just need to know one last thing: how to 104 | get input from the keyboard. You can't have a guessing game without the ability 105 | to guess! 106 | -------------------------------------------------------------------------------- /looping.md: -------------------------------------------------------------------------------- 1 | % Looping 2 | 3 | Looping is the last basic construct that we haven't learned yet in Rust. Rust has 4 | two main looping constructs: `for` and `while`. 5 | 6 | ## `for` 7 | 8 | The `for` loop is used to loop a particular number of times. Rust's `for` loops 9 | work a bit differently than in other systems languages, however. Rust's `for` 10 | loop doesn't look like this "C-style" `for` loop: 11 | 12 | ```{c} 13 | for (x = 0; x < 10; x++) { 14 | printf( "%d\n", x ); 15 | } 16 | ``` 17 | 18 | Instead, it looks like this: 19 | 20 | ```{rust} 21 | for x in 0..10 { 22 | println!("{}", x); // x: i32 23 | } 24 | ``` 25 | 26 | In slightly more abstract terms, 27 | 28 | ```{ignore} 29 | for var in expression { 30 | code 31 | } 32 | ``` 33 | 34 | The expression is an iterator, which we will discuss in more depth later in the 35 | guide. The iterator gives back a series of elements. Each element is one 36 | iteration of the loop. That value is then bound to the name `var`, which is 37 | valid for the loop body. Once the body is over, the next value is fetched from 38 | the iterator, and we loop another time. When there are no more values, the 39 | `for` loop is over. 40 | 41 | In our example, `0..10` is an expression that takes a start and an end position, 42 | and gives an iterator over those values. The upper bound is exclusive, though, 43 | so our loop will print `0` through `9`, not `10`. 44 | 45 | Rust does not have the "C-style" `for` loop on purpose. Manually controlling 46 | each element of the loop is complicated and error prone, even for experienced C 47 | developers. 48 | 49 | We'll talk more about `for` when we cover *iterators*, later in the Guide. 50 | 51 | ## `while` 52 | 53 | The other kind of looping construct in Rust is the `while` loop. It looks like 54 | this: 55 | 56 | ```{rust} 57 | let mut x = 5; // mut x: u32 58 | let mut done = false; // mut done: bool 59 | 60 | while !done { 61 | x += x - 3; 62 | println!("{}", x); 63 | if x % 5 == 0 { done = true; } 64 | } 65 | ``` 66 | 67 | `while` loops are the correct choice when you're not sure how many times 68 | you need to loop. 69 | 70 | If you need an infinite loop, you may be tempted to write this: 71 | 72 | ```{rust,ignore} 73 | while true { 74 | ``` 75 | 76 | However, Rust has a dedicated keyword, `loop`, to handle this case: 77 | 78 | ```{rust,ignore} 79 | loop { 80 | ``` 81 | 82 | Rust's control-flow analysis treats this construct differently than a 83 | `while true`, since we know that it will always loop. The details of what 84 | that _means_ aren't super important to understand at this stage, but in 85 | general, the more information we can give to the compiler, the better it 86 | can do with safety and code generation, so you should always prefer 87 | `loop` when you plan to loop infinitely. 88 | 89 | ## Ending iteration early 90 | 91 | Let's take a look at that `while` loop we had earlier: 92 | 93 | ```{rust} 94 | let mut x = 5; 95 | let mut done = false; 96 | 97 | while !done { 98 | x += x - 3; 99 | println!("{}", x); 100 | if x % 5 == 0 { done = true; } 101 | } 102 | ``` 103 | 104 | We had to keep a dedicated `mut` boolean variable binding, `done`, to know 105 | when we should exit out of the loop. Rust has two keywords to help us with 106 | modifying iteration: `break` and `continue`. 107 | 108 | In this case, we can write the loop in a better way with `break`: 109 | 110 | ```{rust} 111 | let mut x = 5; 112 | 113 | loop { 114 | x += x - 3; 115 | println!("{}", x); 116 | if x % 5 == 0 { break; } 117 | } 118 | ``` 119 | 120 | We now loop forever with `loop` and use `break` to break out early. 121 | 122 | `continue` is similar, but instead of ending the loop, goes to the next 123 | iteration. This will only print the odd numbers: 124 | 125 | ```{rust} 126 | for x in 0u32..10 { 127 | if x % 2 == 0 { continue; } 128 | 129 | println!("{}", x); 130 | } 131 | ``` 132 | 133 | Both `continue` and `break` are valid in both kinds of loops. 134 | -------------------------------------------------------------------------------- /installing-rust.md: -------------------------------------------------------------------------------- 1 | % Installing Rust 2 | 3 | The first step to using Rust is to install it! There are a number of ways to 4 | install Rust, but the easiest is to use the `rustup` script. If you're on 5 | Linux or a Mac, all you need to do is this (note that you don't need to type 6 | in the `$`s, they just indicate the start of each command): 7 | 8 | ```bash 9 | $ curl -L https://static.rust-lang.org/rustup.sh | sudo sh 10 | ``` 11 | 12 | If you're concerned about the [potential insecurity](http://curlpipesh.tumblr.com/) of using `curl | sudo sh`, 13 | 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: 14 | 15 | ```bash 16 | $ curl -L https://static.rust-lang.org/rustup.sh -O 17 | $ sudo sh rustup.sh 18 | ``` 19 | 20 | If you're on Windows, please download either the [32-bit 21 | installer](https://static.rust-lang.org/dist/rust-nightly-i686-pc-windows-gnu.exe) 22 | or the [64-bit 23 | installer](https://static.rust-lang.org/dist/rust-nightly-x86_64-pc-windows-gnu.exe) 24 | and run it. 25 | 26 | If you decide you don't want Rust anymore, we'll be a bit sad, but that's okay. 27 | Not every programming language is great for everyone. Just run the uninstall 28 | script: 29 | 30 | ```bash 31 | $ sudo /usr/local/lib/rustlib/uninstall.sh 32 | ``` 33 | 34 | If you used the Windows installer, just re-run the `.exe` and it will give you 35 | an uninstall option. 36 | 37 | You can re-run this script any time you want to update Rust. Which, at this 38 | point, is often. Rust is still pre-1.0, and so people assume that you're using 39 | a very recent Rust. 40 | 41 | This brings me to one other point: some people, and somewhat rightfully so, get 42 | very upset when we tell you to `curl | sudo sh`. And they should be! Basically, 43 | when you do this, you are trusting that the good people who maintain Rust 44 | aren't going to hack your computer and do bad things. That's a good instinct! 45 | If you're one of those people, please check out the documentation on [building 46 | Rust from Source](https://github.com/rust-lang/rust#building-from-source), or 47 | [the official binary downloads](http://www.rust-lang.org/install.html). And we 48 | promise that this method will not be the way to install Rust forever: it's just 49 | the easiest way to keep people updated while Rust is in its alpha state. 50 | 51 | Oh, we should also mention the officially supported platforms: 52 | 53 | * Windows (7, 8, Server 2008 R2) 54 | * Linux (2.6.18 or later, various distributions), x86 and x86-64 55 | * OSX 10.7 (Lion) or greater, x86 and x86-64 56 | 57 | We extensively test Rust on these platforms, and a few others, too, like 58 | Android. But these are the ones most likely to work, as they have the most 59 | testing. 60 | 61 | Finally, a comment about Windows. Rust considers Windows to be a first-class 62 | platform upon release, but if we're honest, the Windows experience isn't as 63 | integrated as the Linux/OS X experience is. We're working on it! If anything 64 | does not work, it is a bug. Please let us know if that happens. Each and every 65 | commit is tested against Windows just like any other platform. 66 | 67 | If you've got Rust installed, you can open up a shell, and type this: 68 | 69 | ```bash 70 | $ rustc --version 71 | ``` 72 | 73 | You should see the version number, commit hash, commit date and build date: 74 | 75 | ```bash 76 | rustc 1.0.0-nightly (f11f3e7ba 2015-01-04) (built 2015-01-06) 77 | ``` 78 | 79 | If you did, Rust has been installed successfully! Congrats! 80 | 81 | This installer also installs a copy of the documentation locally, so you can 82 | read it offline. On UNIX systems, `/usr/local/share/doc/rust` is the location. 83 | On Windows, it's in a `share/doc` directory, inside wherever you installed Rust 84 | to. 85 | 86 | If not, there are a number of places where you can get help. The easiest is 87 | [the #rust IRC channel on irc.mozilla.org](irc://irc.mozilla.org/#rust), which 88 | you can access through 89 | [Mibbit](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust). Click 90 | that link, and you'll be chatting with other Rustaceans (a silly nickname we 91 | call ourselves), and we can help you out. Other great resources include [the 92 | /r/rust subreddit](http://www.reddit.com/r/rust), and [Stack 93 | Overflow](http://stackoverflow.com/questions/tagged/rust). 94 | -------------------------------------------------------------------------------- /patterns.md: -------------------------------------------------------------------------------- 1 | % Patterns 2 | 3 | We've made use of patterns a few times in the guide: first with `let` bindings, 4 | then with `match` statements. Let's go on a whirlwind tour of all of the things 5 | patterns can do! 6 | 7 | A quick refresher: you can match against literals directly, and `_` acts as an 8 | *any* case: 9 | 10 | ```{rust} 11 | let x = 1; 12 | 13 | match x { 14 | 1 => println!("one"), 15 | 2 => println!("two"), 16 | 3 => println!("three"), 17 | _ => println!("anything"), 18 | } 19 | ``` 20 | 21 | You can match multiple patterns with `|`: 22 | 23 | ```{rust} 24 | let x = 1; 25 | 26 | match x { 27 | 1 | 2 => println!("one or two"), 28 | 3 => println!("three"), 29 | _ => println!("anything"), 30 | } 31 | ``` 32 | 33 | You can match a range of values with `...`: 34 | 35 | ```{rust} 36 | let x = 1; 37 | 38 | match x { 39 | 1 ... 5 => println!("one through five"), 40 | _ => println!("anything"), 41 | } 42 | ``` 43 | 44 | Ranges are mostly used with integers and single characters. 45 | 46 | If you're matching multiple things, via a `|` or a `...`, you can bind 47 | the value to a name with `@`: 48 | 49 | ```{rust} 50 | let x = 1; 51 | 52 | match x { 53 | e @ 1 ... 5 => println!("got a range element {}", e), 54 | _ => println!("anything"), 55 | } 56 | ``` 57 | 58 | If you're matching on an enum which has variants, you can use `..` to 59 | ignore the value and type in the variant: 60 | 61 | ```{rust} 62 | enum OptionalInt { 63 | Value(i32), 64 | Missing, 65 | } 66 | 67 | let x = OptionalInt::Value(5); 68 | 69 | match x { 70 | OptionalInt::Value(..) => println!("Got an int!"), 71 | OptionalInt::Missing => println!("No such luck."), 72 | } 73 | ``` 74 | 75 | You can introduce *match guards* with `if`: 76 | 77 | ```{rust} 78 | enum OptionalInt { 79 | Value(i32), 80 | Missing, 81 | } 82 | 83 | let x = OptionalInt::Value(5); 84 | 85 | match x { 86 | OptionalInt::Value(i) if i > 5 => println!("Got an int bigger than five!"), 87 | OptionalInt::Value(..) => println!("Got an int!"), 88 | OptionalInt::Missing => println!("No such luck."), 89 | } 90 | ``` 91 | 92 | If you're matching on a pointer, you can use the same syntax as you declared it 93 | with. First, `&`: 94 | 95 | ```{rust} 96 | let x = &5; 97 | 98 | match x { 99 | &val => println!("Got a value: {}", val), 100 | } 101 | ``` 102 | 103 | Here, the `val` inside the `match` has type `i32`. In other words, the left-hand 104 | side of the pattern destructures the value. If we have `&5`, then in `&val`, `val` 105 | would be `5`. 106 | 107 | If you want to get a reference, use the `ref` keyword: 108 | 109 | ```{rust} 110 | let x = 5; 111 | 112 | match x { 113 | ref r => println!("Got a reference to {}", r), 114 | } 115 | ``` 116 | 117 | Here, the `r` inside the `match` has the type `&i32`. In other words, the `ref` 118 | keyword _creates_ a reference, for use in the pattern. If you need a mutable 119 | reference, `ref mut` will work in the same way: 120 | 121 | ```{rust} 122 | let mut x = 5; 123 | 124 | match x { 125 | ref mut mr => println!("Got a mutable reference to {}", mr), 126 | } 127 | ``` 128 | 129 | If you have a struct, you can destructure it inside of a pattern: 130 | 131 | ```{rust} 132 | # #![allow(non_shorthand_field_patterns)] 133 | struct Point { 134 | x: i32, 135 | y: i32, 136 | } 137 | 138 | let origin = Point { x: 0, y: 0 }; 139 | 140 | match origin { 141 | Point { x: x, y: y } => println!("({},{})", x, y), 142 | } 143 | ``` 144 | 145 | If we only care about some of the values, we don't have to give them all names: 146 | 147 | ```{rust} 148 | # #![allow(non_shorthand_field_patterns)] 149 | struct Point { 150 | x: i32, 151 | y: i32, 152 | } 153 | 154 | let origin = Point { x: 0, y: 0 }; 155 | 156 | match origin { 157 | Point { x: x, .. } => println!("x is {}", x), 158 | } 159 | ``` 160 | 161 | You can do this kind of match on any member, not just the first: 162 | 163 | ```{rust} 164 | # #![allow(non_shorthand_field_patterns)] 165 | struct Point { 166 | x: i32, 167 | y: i32, 168 | } 169 | 170 | let origin = Point { x: 0, y: 0 }; 171 | 172 | match origin { 173 | Point { y: y, .. } => println!("y is {}", y), 174 | } 175 | ``` 176 | 177 | If you want to match against a slice or array, you can use `&`: 178 | 179 | ```{rust} 180 | fn main() { 181 | let v = vec!["match_this", "1"]; 182 | 183 | match &v[..] { 184 | ["match_this", second] => println!("The second element is {}", second), 185 | _ => {}, 186 | } 187 | } 188 | ``` 189 | 190 | Whew! That's a lot of different ways to match things, and they can all be 191 | mixed and matched, depending on what you're doing: 192 | 193 | ```{rust,ignore} 194 | match x { 195 | Foo { x: Some(ref name), y: None } => ... 196 | } 197 | ``` 198 | 199 | Patterns are very powerful. Make good use of them. 200 | -------------------------------------------------------------------------------- /match.md: -------------------------------------------------------------------------------- 1 | % Match 2 | 3 | Often, a simple `if`/`else` isn't enough, because you have more than two 4 | possible options. Also, `else` conditions can get incredibly complicated, so 5 | what's the solution? 6 | 7 | Rust has a keyword, `match`, that allows you to replace complicated `if`/`else` 8 | groupings with something more powerful. Check it out: 9 | 10 | ```{rust} 11 | let x = 5; 12 | 13 | match x { 14 | 1 => println!("one"), 15 | 2 => println!("two"), 16 | 3 => println!("three"), 17 | 4 => println!("four"), 18 | 5 => println!("five"), 19 | _ => println!("something else"), 20 | } 21 | ``` 22 | 23 | `match` takes an expression and then branches based on its value. Each *arm* of 24 | the branch is of the form `val => expression`. When the value matches, that arm's 25 | expression will be evaluated. It's called `match` because of the term 'pattern 26 | matching', which `match` is an implementation of. 27 | 28 | So what's the big advantage here? Well, there are a few. First of all, `match` 29 | enforces *exhaustiveness checking*. Do you see that last arm, the one with the 30 | underscore (`_`)? If we remove that arm, Rust will give us an error: 31 | 32 | ```text 33 | error: non-exhaustive patterns: `_` not covered 34 | ``` 35 | 36 | In other words, Rust is trying to tell us we forgot a value. Because `x` is an 37 | integer, Rust knows that it can have a number of different values – for example, 38 | `6`. Without the `_`, however, there is no arm that could match, and so Rust refuses 39 | to compile. `_` acts like a *catch-all arm*. If none of the other arms match, 40 | the arm with `_` will, and since we have this catch-all arm, we now have an arm 41 | for every possible value of `x`, and so our program will compile successfully. 42 | 43 | `match` statements also destructure enums, as well. Remember this code from the 44 | section on enums? 45 | 46 | ```{rust} 47 | use std::cmp::Ordering; 48 | 49 | fn cmp(a: i32, b: i32) -> Ordering { 50 | if a < b { Ordering::Less } 51 | else if a > b { Ordering::Greater } 52 | else { Ordering::Equal } 53 | } 54 | 55 | fn main() { 56 | let x = 5; 57 | let y = 10; 58 | 59 | let ordering = cmp(x, y); 60 | 61 | if ordering == Ordering::Less { 62 | println!("less"); 63 | } else if ordering == Ordering::Greater { 64 | println!("greater"); 65 | } else if ordering == Ordering::Equal { 66 | println!("equal"); 67 | } 68 | } 69 | ``` 70 | 71 | We can re-write this as a `match`: 72 | 73 | ```{rust} 74 | use std::cmp::Ordering; 75 | 76 | fn cmp(a: i32, b: i32) -> Ordering { 77 | if a < b { Ordering::Less } 78 | else if a > b { Ordering::Greater } 79 | else { Ordering::Equal } 80 | } 81 | 82 | fn main() { 83 | let x = 5; 84 | let y = 10; 85 | 86 | match cmp(x, y) { 87 | Ordering::Less => println!("less"), 88 | Ordering::Greater => println!("greater"), 89 | Ordering::Equal => println!("equal"), 90 | } 91 | } 92 | ``` 93 | 94 | This version has way less noise, and it also checks exhaustively to make sure 95 | that we have covered all possible variants of `Ordering`. With our `if`/`else` 96 | version, if we had forgotten the `Greater` case, for example, our program would 97 | have happily compiled. If we forget in the `match`, it will not. Rust helps us 98 | make sure to cover all of our bases. 99 | 100 | `match` expressions also allow us to get the values contained in an `enum` 101 | (also known as destructuring) as follows: 102 | 103 | ```{rust} 104 | enum OptionalInt { 105 | Value(i32), 106 | Missing, 107 | } 108 | 109 | fn main() { 110 | let x = OptionalInt::Value(5); 111 | let y = OptionalInt::Missing; 112 | 113 | match x { 114 | OptionalInt::Value(n) => println!("x is {}", n), 115 | OptionalInt::Missing => println!("x is missing!"), 116 | } 117 | 118 | match y { 119 | OptionalInt::Value(n) => println!("y is {}", n), 120 | OptionalInt::Missing => println!("y is missing!"), 121 | } 122 | } 123 | ``` 124 | 125 | That is how you can get and use the values contained in `enum`s. 126 | It can also allow us to handle errors or unexpected computations; for example, a 127 | function that is not guaranteed to be able to compute a result (an `i32` here) 128 | could return an `OptionalInt`, and we would handle that value with a `match`. 129 | As you can see, `enum` and `match` used together are quite useful! 130 | 131 | `match` is also an expression, which means we can use it on the right-hand 132 | side of a `let` binding or directly where an expression is used. We could 133 | also implement the previous example like this: 134 | 135 | ```{rust} 136 | use std::cmp::Ordering; 137 | 138 | fn cmp(a: i32, b: i32) -> Ordering { 139 | if a < b { Ordering::Less } 140 | else if a > b { Ordering::Greater } 141 | else { Ordering::Equal } 142 | } 143 | 144 | fn main() { 145 | let x = 5; 146 | let y = 10; 147 | 148 | println!("{}", match cmp(x, y) { 149 | Ordering::Less => "less", 150 | Ordering::Greater => "greater", 151 | Ordering::Equal => "equal", 152 | }); 153 | } 154 | ``` 155 | 156 | Sometimes, it's a nice pattern. 157 | -------------------------------------------------------------------------------- /standard-input.md: -------------------------------------------------------------------------------- 1 | % Standard Input 2 | 3 | Getting input from the keyboard is pretty easy, but uses some things 4 | we haven't seen before. Here's a simple program that reads some input, 5 | and then prints it back out: 6 | 7 | ```{rust,ignore} 8 | corefn main() { 9 | println!("Type something!"); 10 | 11 | let input = std::old_io::stdin().read_line().ok().expect("Failed to read line"); 12 | 13 | println!("{}", input); 14 | } 15 | ``` 16 | 17 | Let's go over these chunks, one by one: 18 | 19 | ```{rust,ignore} 20 | std::old_io::stdin(); 21 | ``` 22 | 23 | This calls a function, `stdin()`, that lives inside the `std::old_io` module. As 24 | you can imagine, everything in `std` is provided by Rust, the 'standard 25 | library.' We'll talk more about the module system later. 26 | 27 | Since writing the fully qualified name all the time is annoying, we can use 28 | the `use` statement to import it in: 29 | 30 | ```{rust} 31 | # #![feature(old_io)] 32 | use std::old_io::stdin; 33 | 34 | stdin(); 35 | ``` 36 | 37 | However, it's considered better practice to not import individual functions, but 38 | to import the module, and only use one level of qualification: 39 | 40 | ```{rust} 41 | # #![feature(old_io)] 42 | use std::old_io; 43 | 44 | old_io::stdin(); 45 | ``` 46 | 47 | Let's update our example to use this style: 48 | 49 | ```{rust,ignore} 50 | use std::old_io; 51 | 52 | fn main() { 53 | println!("Type something!"); 54 | 55 | let input = old_io::stdin().read_line().ok().expect("Failed to read line"); 56 | 57 | println!("{}", input); 58 | } 59 | ``` 60 | 61 | Next up: 62 | 63 | ```{rust,ignore} 64 | .read_line() 65 | ``` 66 | 67 | The `read_line()` method can be called on the result of `stdin()` to return 68 | a full line of input. Nice and easy. 69 | 70 | ```{rust,ignore} 71 | .ok().expect("Failed to read line"); 72 | ``` 73 | 74 | Do you remember this code? 75 | 76 | ```{rust} 77 | enum OptionalInt { 78 | Value(i32), 79 | Missing, 80 | } 81 | 82 | fn main() { 83 | let x = OptionalInt::Value(5); 84 | let y = OptionalInt::Missing; 85 | 86 | match x { 87 | OptionalInt::Value(n) => println!("x is {}", n), 88 | OptionalInt::Missing => println!("x is missing!"), 89 | } 90 | 91 | match y { 92 | OptionalInt::Value(n) => println!("y is {}", n), 93 | OptionalInt::Missing => println!("y is missing!"), 94 | } 95 | } 96 | ``` 97 | 98 | We had to match each time to see if we had a value or not. In this case, 99 | though, we _know_ that `x` has a `Value`, but `match` forces us to handle 100 | the `missing` case. This is what we want 99% of the time, but sometimes, we 101 | know better than the compiler. 102 | 103 | Likewise, `read_line()` does not return a line of input. It _might_ return a 104 | line of input, though it might also fail to do so. This could happen if our program 105 | isn't running in a terminal, but as part of a cron job, or some other context 106 | where there's no standard input. Because of this, `read_line` returns a type 107 | very similar to our `OptionalInt`: an `IoResult`. We haven't talked about 108 | `IoResult` yet because it is the *generic* form of our `OptionalInt`. 109 | Until then, you can think of it as being the same thing, just for any type – 110 | not just `i32`s. 111 | 112 | Rust provides a method on these `IoResult`s called `ok()`, which does the 113 | same thing as our `match` statement but assumes that we have a valid value. 114 | We then call `expect()` on the result, which will terminate our program if we 115 | don't have a valid value. In this case, if we can't get input, our program 116 | doesn't work, so we're okay with that. In most cases, we would want to handle 117 | the error case explicitly. `expect()` allows us to give an error message if 118 | this crash happens. 119 | 120 | We will cover the exact details of how all of this works later in the Guide in 121 | [Error Handling]. For now, this gives you enough of a basic understanding to 122 | work with. 123 | 124 | Back to the code we were working on! Here's a refresher: 125 | 126 | ```{rust,ignore} 127 | use std::old_io; 128 | 129 | fn main() { 130 | println!("Type something!"); 131 | 132 | let input = old_io::stdin().read_line().ok().expect("Failed to read line"); 133 | 134 | println!("{}", input); 135 | } 136 | ``` 137 | 138 | With long lines like this, Rust gives you some flexibility with the whitespace. 139 | We _could_ write the example like this: 140 | 141 | ```{rust,ignore} 142 | use std::old_io; 143 | 144 | fn main() { 145 | println!("Type something!"); 146 | 147 | // here, we'll show the types at each step 148 | 149 | let input = old_io::stdin() // std::old_io::stdio::StdinReader 150 | .read_line() // IoResult 151 | .ok() // Option 152 | .expect("Failed to read line"); // String 153 | 154 | println!("{}", input); 155 | } 156 | ``` 157 | 158 | Sometimes, this makes things more readable – sometimes, less. Use your judgement 159 | here. 160 | 161 | That's all you need to get basic input from the standard input! It's not too 162 | complicated, but there are a number of small parts. 163 | 164 | 165 | [Error Handling]: ./error-handling.html 166 | -------------------------------------------------------------------------------- /if.md: -------------------------------------------------------------------------------- 1 | % If 2 | 3 | Rust's take on `if` is not particularly complex, but it's much more like the 4 | `if` you'll find in a dynamically typed language than in a more traditional 5 | systems language. So let's talk about it, to make sure you grasp the nuances. 6 | 7 | `if` is a specific form of a more general concept, the *branch*. The name comes 8 | from a branch in a tree: a decision point, where depending on a choice, 9 | multiple paths can be taken. 10 | 11 | In the case of `if`, there is one choice that leads down two paths: 12 | 13 | ```rust 14 | let x = 5; 15 | 16 | if x == 5 { 17 | println!("x is five!"); 18 | } 19 | ``` 20 | 21 | If we changed the value of `x` to something else, this line would not print. 22 | More specifically, if the expression after the `if` evaluates to `true`, then 23 | the block is executed. If it's `false`, then it is not. 24 | 25 | If you want something to happen in the `false` case, use an `else`: 26 | 27 | ```{rust} 28 | let x = 5; 29 | 30 | if x == 5 { 31 | println!("x is five!"); 32 | } else { 33 | println!("x is not five :("); 34 | } 35 | ``` 36 | 37 | If there is more than one case, use an `else if`: 38 | 39 | ```rust 40 | let x = 5; 41 | 42 | if x == 5 { 43 | println!("x is five!"); 44 | } else if x == 6 { 45 | println!("x is six!"); 46 | } else { 47 | println!("x is not five or six :("); 48 | } 49 | ``` 50 | 51 | This is all pretty standard. However, you can also do this: 52 | 53 | 54 | ```{rust} 55 | let x = 5; 56 | 57 | let y = if x == 5 { 58 | 10 59 | } else { 60 | 15 61 | }; // y: i32 62 | ``` 63 | 64 | Which we can (and probably should) write like this: 65 | 66 | ```{rust} 67 | let x = 5; 68 | 69 | let y = if x == 5 { 10 } else { 15 }; // y: i32 70 | ``` 71 | 72 | This reveals two interesting things about Rust: it is an expression-based 73 | language, and semicolons are different from semicolons in other 'curly brace 74 | and semicolon'-based languages. These two things are related. 75 | 76 | ## Expressions vs. Statements 77 | 78 | Rust is primarily an expression based language. There are only two kinds of 79 | statements, and everything else is an expression. 80 | 81 | So what's the difference? Expressions return a value, and statements do not. 82 | In many languages, `if` is a statement, and therefore, `let x = if ...` would 83 | make no sense. But in Rust, `if` is an expression, which means that it returns 84 | a value. We can then use this value to initialize the binding. 85 | 86 | Speaking of which, bindings are a kind of the first of Rust's two statements. 87 | The proper name is a *declaration statement*. So far, `let` is the only kind 88 | of declaration statement we've seen. Let's talk about that some more. 89 | 90 | In some languages, variable bindings can be written as expressions, not just 91 | statements. Like Ruby: 92 | 93 | ```{ruby} 94 | x = y = 5 95 | ``` 96 | 97 | In Rust, however, using `let` to introduce a binding is _not_ an expression. The 98 | following will produce a compile-time error: 99 | 100 | ```{ignore} 101 | let x = (let y = 5); // expected identifier, found keyword `let` 102 | ``` 103 | 104 | The compiler is telling us here that it was expecting to see the beginning of 105 | an expression, and a `let` can only begin a statement, not an expression. 106 | 107 | Note that assigning to an already-bound variable (e.g. `y = 5`) is still an 108 | expression, although its value is not particularly useful. Unlike C, where an 109 | assignment evaluates to the assigned value (e.g. `5` in the previous example), 110 | in Rust the value of an assignment is the unit type `()` (which we'll cover later). 111 | 112 | The second kind of statement in Rust is the *expression statement*. Its 113 | purpose is to turn any expression into a statement. In practical terms, Rust's 114 | grammar expects statements to follow other statements. This means that you use 115 | semicolons to separate expressions from each other. This means that Rust 116 | looks a lot like most other languages that require you to use semicolons 117 | at the end of every line, and you will see semicolons at the end of almost 118 | every line of Rust code you see. 119 | 120 | What is this exception that makes us say "almost"? You saw it already, in this 121 | code: 122 | 123 | ```{rust} 124 | let x = 5; 125 | 126 | let y: i32 = if x == 5 { 10 } else { 15 }; 127 | ``` 128 | 129 | Note that I've added the type annotation to `y`, to specify explicitly that I 130 | want `y` to be an integer. 131 | 132 | This is not the same as this, which won't compile: 133 | 134 | ```{ignore} 135 | let x = 5; 136 | 137 | let y: i32 = if x == 5 { 10; } else { 15; }; 138 | ``` 139 | 140 | Note the semicolons after the 10 and 15. Rust will give us the following error: 141 | 142 | ```text 143 | error: mismatched types: expected `i32`, found `()` (expected i32, found ()) 144 | ``` 145 | 146 | We expected an integer, but we got `()`. `()` is pronounced *unit*, and is a 147 | special type in Rust's type system. In Rust, `()` is _not_ a valid value for a 148 | variable of type `i32`. It's only a valid value for variables of the type `()`, 149 | which aren't very useful. Remember how we said statements don't return a value? 150 | Well, that's the purpose of unit in this case. The semicolon turns any 151 | expression into a statement by throwing away its value and returning unit 152 | instead. 153 | 154 | There's one more time in which you won't see a semicolon at the end of a line 155 | of Rust code. For that, we'll need our next concept: functions. 156 | -------------------------------------------------------------------------------- /functions.md: -------------------------------------------------------------------------------- 1 | % Functions 2 | 3 | You've already seen one function so far, the `main` function: 4 | 5 | ```rust 6 | fn main() { 7 | } 8 | ``` 9 | 10 | This is the simplest possible function declaration. As we mentioned before, 11 | `fn` says "this is a function," followed by the name, some parentheses because 12 | this function takes no arguments, and then some curly braces to indicate the 13 | body. Here's a function named `foo`: 14 | 15 | ```rust 16 | fn foo() { 17 | } 18 | ``` 19 | 20 | So, what about taking arguments? Here's a function that prints a number: 21 | 22 | ```rust 23 | fn print_number(x: i32) { 24 | println!("x is: {}", x); 25 | } 26 | ``` 27 | 28 | Here's a complete program that uses `print_number`: 29 | 30 | ```rust 31 | fn main() { 32 | print_number(5); 33 | } 34 | 35 | fn print_number(x: i32) { 36 | println!("x is: {}", x); 37 | } 38 | ``` 39 | 40 | As you can see, function arguments work very similar to `let` declarations: 41 | you add a type to the argument name, after a colon. 42 | 43 | Here's a complete program that adds two numbers together and prints them: 44 | 45 | ```rust 46 | fn main() { 47 | print_sum(5, 6); 48 | } 49 | 50 | fn print_sum(x: i32, y: i32) { 51 | println!("sum is: {}", x + y); 52 | } 53 | ``` 54 | 55 | You separate arguments with a comma, both when you call the function, as well 56 | as when you declare it. 57 | 58 | Unlike `let`, you _must_ declare the types of function arguments. This does 59 | not work: 60 | 61 | ```{rust,ignore} 62 | fn print_sum(x, y) { 63 | println!("sum is: {}", x + y); 64 | } 65 | ``` 66 | 67 | You get this error: 68 | 69 | ```text 70 | hello.rs:5:18: 5:19 expected one of `!`, `:`, or `@`, found `)` 71 | hello.rs:5 fn print_number(x, y) { 72 | ``` 73 | 74 | This is a deliberate design decision. While full-program inference is possible, 75 | languages which have it, like Haskell, often suggest that documenting your 76 | types explicitly is a best-practice. We agree that forcing functions to declare 77 | types while allowing for inference inside of function bodies is a wonderful 78 | sweet spot between full inference and no inference. 79 | 80 | What about returning a value? Here's a function that adds one to an integer: 81 | 82 | ```rust 83 | fn add_one(x: i32) -> i32 { 84 | x + 1 85 | } 86 | ``` 87 | 88 | Rust functions return exactly one value, and you declare the type after an 89 | "arrow," which is a dash (`-`) followed by a greater-than sign (`>`). 90 | 91 | You'll note the lack of a semicolon here. If we added it in: 92 | 93 | ```{rust,ignore} 94 | fn add_one(x: i32) -> i32 { 95 | x + 1; 96 | } 97 | ``` 98 | 99 | We would get an error: 100 | 101 | ```text 102 | error: not all control paths return a value 103 | fn add_one(x: i32) -> i32 { 104 | x + 1; 105 | } 106 | 107 | help: consider removing this semicolon: 108 | x + 1; 109 | ^ 110 | ``` 111 | 112 | Remember our earlier discussions about semicolons and `()`? Our function claims 113 | to return an `i32`, but with a semicolon, it would return `()` instead. Rust 114 | realizes this probably isn't what we want, and suggests removing the semicolon. 115 | 116 | This is very much like our `if` statement before: the result of the block 117 | (`{}`) is the value of the expression. Other expression-oriented languages, 118 | such as Ruby, work like this, but it's a bit unusual in the systems programming 119 | world. When people first learn about this, they usually assume that it 120 | introduces bugs. But because Rust's type system is so strong, and because unit 121 | is its own unique type, we have never seen an issue where adding or removing a 122 | semicolon in a return position would cause a bug. 123 | 124 | But what about early returns? Rust does have a keyword for that, `return`: 125 | 126 | ```rust 127 | fn foo(x: i32) -> i32 { 128 | if x < 5 { return x; } 129 | 130 | x + 1 131 | } 132 | ``` 133 | 134 | Using a `return` as the last line of a function works, but is considered poor 135 | style: 136 | 137 | ```rust 138 | fn foo(x: i32) -> i32 { 139 | if x < 5 { return x; } 140 | 141 | return x + 1; 142 | } 143 | ``` 144 | 145 | The previous definition without `return` may look a bit strange if you haven't 146 | worked in an expression-based language before, but it becomes intuitive over 147 | time. If this were production code, we wouldn't write it in that way anyway, 148 | we'd write this: 149 | 150 | ```rust 151 | fn foo(x: i32) -> i32 { 152 | if x < 5 { 153 | x 154 | } else { 155 | x + 1 156 | } 157 | } 158 | ``` 159 | 160 | Because `if` is an expression, and it's the only expression in this function, 161 | the value will be the result of the `if`. 162 | 163 | ## Diverging functions 164 | 165 | Rust has some special syntax for 'diverging functions', which are functions that 166 | do not return: 167 | 168 | ``` 169 | fn diverges() -> ! { 170 | panic!("This function never returns!"); 171 | } 172 | ``` 173 | 174 | `panic!` is a macro, similar to `println!()` that we've already seen. Unlike 175 | `println!()`, `panic!()` causes the current thread of execution to crash with 176 | the given message. 177 | 178 | Because this function will cause a crash, it will never return, and so it has 179 | the type '`!`', which is read "diverges." A diverging function can be used 180 | as any type: 181 | 182 | ```should_panic 183 | # fn diverges() -> ! { 184 | # panic!("This function never returns!"); 185 | # } 186 | 187 | let x: i32 = diverges(); 188 | let x: String = diverges(); 189 | ``` 190 | 191 | We don't have a good use for diverging functions yet, because they're used in 192 | conjunction with other Rust features. But when you see `-> !` later, you'll 193 | know what it's called. 194 | -------------------------------------------------------------------------------- /hello-cargo.md: -------------------------------------------------------------------------------- 1 | % Hello, Cargo! 2 | 3 | [Cargo](http://crates.io) is a tool that Rustaceans use to help manage their 4 | Rust projects. Cargo is currently in an alpha state, just like Rust, and so it 5 | is still a work in progress. However, it is already good enough to use for many 6 | Rust projects, and so it is assumed that Rust projects will use Cargo from the 7 | beginning. 8 | 9 | Cargo manages three things: building your code, downloading the dependencies 10 | your code needs, and building those dependencies. At first, your 11 | program doesn't have any dependencies, so we'll only be using the first part of 12 | its functionality. Eventually, we'll add more. Since we started off by using 13 | Cargo, it'll be easy to add later. 14 | 15 | If you installed Rust via the official installers you will also have 16 | Cargo. If you installed Rust some other way, you may want to [check 17 | the Cargo 18 | README](https://github.com/rust-lang/cargo#installing-cargo-from-nightlies) 19 | for specific instructions about installing it. 20 | 21 | ## Converting to Cargo 22 | 23 | Let's convert Hello World to Cargo. 24 | 25 | To Cargo-ify our project, we need to do two things: Make a `Cargo.toml` 26 | configuration file, and put our source file in the right place. Let's 27 | do that part first: 28 | 29 | ```bash 30 | $ mkdir src 31 | $ mv main.rs src/main.rs 32 | ``` 33 | 34 | Cargo expects your source files to live inside a `src` directory. That leaves 35 | the top level for other things, like READMEs, license information, and anything 36 | not related to your code. Cargo helps us keep our projects nice and tidy. A 37 | place for everything, and everything in its place. 38 | 39 | Next, our configuration file: 40 | 41 | ```bash 42 | $ editor Cargo.toml 43 | ``` 44 | 45 | Make sure to get this name right: you need the capital `C`! 46 | 47 | Put this inside: 48 | 49 | ```toml 50 | [package] 51 | 52 | name = "hello_world" 53 | version = "0.0.1" 54 | authors = [ "Your name " ] 55 | 56 | [[bin]] 57 | 58 | name = "hello_world" 59 | ``` 60 | 61 | This file is in the [TOML](https://github.com/toml-lang/toml) format. Let's let 62 | it explain itself to you: 63 | 64 | > TOML aims to be a minimal configuration file format that's easy to read due 65 | > to obvious semantics. TOML is designed to map unambiguously to a hash table. 66 | > TOML should be easy to parse into data structures in a wide variety of 67 | > languages. 68 | 69 | TOML is very similar to INI, but with some extra goodies. 70 | 71 | Anyway, there are two *tables* in this file: `package` and `bin`. The first 72 | tells Cargo metadata about your package. The second tells Cargo that we're 73 | interested in building a binary, not a library (though we could do both!), as 74 | well as what it is named. 75 | 76 | Once you have this file in place, we should be ready to build! Try this: 77 | 78 | ```bash 79 | $ cargo build 80 | Compiling hello_world v0.0.1 (file:///home/yourname/projects/hello_world) 81 | $ ./target/debug/hello_world 82 | Hello, world! 83 | ``` 84 | 85 | Bam! We build our project with `cargo build`, and run it with 86 | `./target/debug/hello_world`. This hasn't bought us a whole lot over our simple use 87 | of `rustc`, but think about the future: when our project has more than one 88 | file, we would need to call `rustc` more than once and pass it a bunch of options to 89 | tell it to build everything together. With Cargo, as our project grows, we can 90 | just `cargo build`, and it'll work the right way. When your project is finally 91 | ready for release, you can use `cargo build --release` to compile your crates with 92 | optimizations. 93 | 94 | You'll also notice that Cargo has created a new file: `Cargo.lock`. 95 | 96 | ```toml 97 | [root] 98 | name = "hello_world" 99 | version = "0.0.1" 100 | ``` 101 | 102 | This file is used by Cargo to keep track of dependencies in your application. 103 | Right now, we don't have any, so it's a bit sparse. You won't ever need 104 | to touch this file yourself, just let Cargo handle it. 105 | 106 | That's it! We've successfully built `hello_world` with Cargo. Even though our 107 | program is simple, it's using much of the real tooling that you'll use for the 108 | rest of your Rust career. 109 | 110 | ## A New Project 111 | 112 | You don't have to go through this whole process every time you want to start a new 113 | project! Cargo has the ability to make a bare-bones project directory in which you 114 | can start developing right away. 115 | 116 | To start a new project with Cargo, use `cargo new`: 117 | 118 | ```bash 119 | $ cargo new hello_world --bin 120 | ``` 121 | 122 | We're passing `--bin` because we're making a binary program: if we 123 | were making a library, we'd leave it off. 124 | 125 | Let's check out what Cargo has generated for us: 126 | 127 | ```bash 128 | $ cd hello_world 129 | $ tree . 130 | . 131 | ├── Cargo.toml 132 | └── src 133 | └── main.rs 134 | 135 | 1 directory, 2 files 136 | ``` 137 | 138 | If you don't have the `tree` command, you can probably get it from your distro's package 139 | manager. It's not necessary, but it's certainly useful. 140 | 141 | This is all we need to get started. First, let's check out `Cargo.toml`: 142 | 143 | ```toml 144 | [package] 145 | 146 | name = "hello_world" 147 | version = "0.0.1" 148 | authors = ["Your Name "] 149 | ``` 150 | 151 | Cargo has populated this file with reasonable defaults based off the arguments you gave 152 | it and your `git` global configuration. You may notice that Cargo has also initialized 153 | the `hello_world` directory as a `git` repository. 154 | 155 | Here's what's in `src/main.rs`: 156 | 157 | ```rust 158 | fn main() { 159 | println!("Hello, world!"); 160 | } 161 | ``` 162 | 163 | Cargo has generated a "Hello World!" for us, and you're ready to start coding! A 164 | much more in-depth guide to Cargo can be found [here](http://doc.crates.io/guide.html). 165 | 166 | Now that you've got the tools down, let's actually learn more about the Rust 167 | language itself. These are the basics that will serve you well through the rest 168 | of your time with Rust. 169 | -------------------------------------------------------------------------------- /generics.md: -------------------------------------------------------------------------------- 1 | % Generics 2 | 3 | Sometimes, when writing a function or data type, we may want it to work for 4 | multiple types of arguments. For example, remember our `OptionalInt` type? 5 | 6 | ```{rust} 7 | enum OptionalInt { 8 | Value(i32), 9 | Missing, 10 | } 11 | ``` 12 | 13 | If we wanted to also have an `OptionalFloat64`, we would need a new enum: 14 | 15 | ```{rust} 16 | enum OptionalFloat64 { 17 | Valuef64(f64), 18 | Missingf64, 19 | } 20 | ``` 21 | 22 | This is really unfortunate. Luckily, Rust has a feature that gives us a better 23 | way: generics. Generics are called *parametric polymorphism* in type theory, 24 | which means that they are types or functions that have multiple forms (*poly* 25 | is multiple, *morph* is form) over a given parameter (*parametric*). 26 | 27 | Anyway, enough with type theory declarations, let's check out the generic form 28 | of `OptionalInt`. It is actually provided by Rust itself, and looks like this: 29 | 30 | ```rust 31 | enum Option { 32 | Some(T), 33 | None, 34 | } 35 | ``` 36 | 37 | The `` part, which you've seen a few times before, indicates that this is 38 | a generic data type. Inside the declaration of our enum, wherever we see a `T`, 39 | we substitute that type for the same type used in the generic. Here's an 40 | example of using `Option`, with some extra type annotations: 41 | 42 | ```{rust} 43 | let x: Option = Some(5); 44 | ``` 45 | 46 | In the type declaration, we say `Option`. Note how similar this looks to 47 | `Option`. So, in this particular `Option`, `T` has the value of `i32`. On 48 | the right-hand side of the binding, we do make a `Some(T)`, where `T` is `5`. 49 | Since that's an `i32`, the two sides match, and Rust is happy. If they didn't 50 | match, we'd get an error: 51 | 52 | ```{rust,ignore} 53 | let x: Option = Some(5); 54 | // error: mismatched types: expected `core::option::Option`, 55 | // found `core::option::Option<_>` (expected f64 but found integral variable) 56 | ``` 57 | 58 | That doesn't mean we can't make `Option`s that hold an `f64`! They just have to 59 | match up: 60 | 61 | ```{rust} 62 | let x: Option = Some(5); 63 | let y: Option = Some(5.0f64); 64 | ``` 65 | 66 | This is just fine. One definition, multiple uses. 67 | 68 | Generics don't have to only be generic over one type. Consider Rust's built-in 69 | `Result` type: 70 | 71 | ```{rust} 72 | enum Result { 73 | Ok(T), 74 | Err(E), 75 | } 76 | ``` 77 | 78 | This type is generic over _two_ types: `T` and `E`. By the way, the capital letters 79 | can be any letter you'd like. We could define `Result` as: 80 | 81 | ```{rust} 82 | enum Result { 83 | Ok(A), 84 | Err(Z), 85 | } 86 | ``` 87 | 88 | if we wanted to. Convention says that the first generic parameter should be 89 | `T`, for 'type,' and that we use `E` for 'error.' Rust doesn't care, however. 90 | 91 | The `Result` type is intended to be used to return the result of a 92 | computation, and to have the ability to return an error if it didn't work out. 93 | Here's an example: 94 | 95 | ```{rust} 96 | let x: Result = Ok(2.3f64); 97 | let y: Result = Err("There was an error.".to_string()); 98 | ``` 99 | 100 | This particular Result will return an `f64` if there's a success, and a 101 | `String` if there's a failure. Let's write a function that uses `Result`: 102 | 103 | ```{rust} 104 | fn inverse(x: f64) -> Result { 105 | if x == 0.0f64 { return Err("x cannot be zero!".to_string()); } 106 | 107 | Ok(1.0f64 / x) 108 | } 109 | ``` 110 | 111 | We don't want to take the inverse of zero, so we check to make sure that we 112 | weren't passed zero. If we were, then we return an `Err`, with a message. If 113 | it's okay, we return an `Ok`, with the answer. 114 | 115 | Why does this matter? Well, remember how `match` does exhaustive matches? 116 | Here's how this function gets used: 117 | 118 | ```{rust} 119 | # fn inverse(x: f64) -> Result { 120 | # if x == 0.0f64 { return Err("x cannot be zero!".to_string()); } 121 | # Ok(1.0f64 / x) 122 | # } 123 | let x = inverse(25.0f64); 124 | 125 | match x { 126 | Ok(x) => println!("The inverse of 25 is {}", x), 127 | Err(msg) => println!("Error: {}", msg), 128 | } 129 | ``` 130 | 131 | The `match` enforces that we handle the `Err` case. In addition, because the 132 | answer is wrapped up in an `Ok`, we can't just use the result without doing 133 | the match: 134 | 135 | ```{rust,ignore} 136 | let x = inverse(25.0f64); 137 | println!("{}", x + 2.0f64); // error: binary operation `+` cannot be applied 138 | // to type `core::result::Result` 139 | ``` 140 | 141 | This function is great, but there's one other problem: it only works for 64 bit 142 | floating point values. What if we wanted to handle 32 bit floating point as 143 | well? We'd have to write this: 144 | 145 | ```{rust} 146 | fn inverse32(x: f32) -> Result { 147 | if x == 0.0f32 { return Err("x cannot be zero!".to_string()); } 148 | 149 | Ok(1.0f32 / x) 150 | } 151 | ``` 152 | 153 | Bummer. What we need is a *generic function*. Luckily, we can write one! 154 | However, it won't _quite_ work yet. Before we get into that, let's talk syntax. 155 | A generic version of `inverse` would look something like this: 156 | 157 | ```{rust,ignore} 158 | fn inverse(x: T) -> Result { 159 | if x == 0.0 { return Err("x cannot be zero!".to_string()); } 160 | 161 | Ok(1.0 / x) 162 | } 163 | ``` 164 | 165 | Just like how we had `Option`, we use a similar syntax for `inverse`. 166 | We can then use `T` inside the rest of the signature: `x` has type `T`, and half 167 | of the `Result` has type `T`. However, if we try to compile that example, we'll get 168 | an error: 169 | 170 | ```text 171 | error: binary operation `==` cannot be applied to type `T` 172 | ``` 173 | 174 | Because `T` can be _any_ type, it may be a type that doesn't implement `==`, 175 | and therefore, the first line would be wrong. What do we do? 176 | 177 | To fix this example, we need to learn about another Rust feature: traits. 178 | -------------------------------------------------------------------------------- /variable-bindings.md: -------------------------------------------------------------------------------- 1 | % Variable Bindings 2 | 3 | The first thing we'll learn about are *variable bindings*. They look like this: 4 | 5 | ```{rust} 6 | fn main() { 7 | let x = 5; 8 | } 9 | ``` 10 | 11 | Putting `fn main() {` in each example is a bit tedious, so we'll leave that out 12 | in the future. If you're following along, make sure to edit your `main()` 13 | function, rather than leaving it off. Otherwise, you'll get an error. 14 | 15 | In many languages, this is called a *variable*. But Rust's variable bindings 16 | have a few tricks up their sleeves. Rust has a very powerful feature called 17 | *pattern matching* that we'll get into detail with later, but the left 18 | hand side of a `let` expression is a full pattern, not just a variable name. 19 | This means we can do things like: 20 | 21 | ```{rust} 22 | let (x, y) = (1, 2); 23 | ``` 24 | 25 | After this expression is evaluated, `x` will be one, and `y` will be two. 26 | Patterns are really powerful, but this is about all we can do with them so far. 27 | So let's just keep this in the back of our minds as we go forward. 28 | 29 | Rust is a statically typed language, which means that we specify our types up 30 | front. So why does our first example compile? Well, Rust has this thing called 31 | *type inference*. If it can figure out what the type of something is, Rust 32 | doesn't require you to actually type it out. 33 | 34 | We can add the type if we want to, though. Types come after a colon (`:`): 35 | 36 | ```{rust} 37 | let x: i32 = 5; 38 | ``` 39 | 40 | If I asked you to read this out loud to the rest of the class, you'd say "`x` 41 | is a binding with the type `i32` and the value `five`." 42 | 43 | In this case we chose to represent `x` as a 32-bit signed integer. Rust has 44 | many different primitive integer types. They begin with `i` for signed integers 45 | and `u` for unsigned integers. The possible integer sizes are 8, 16, 32, and 64 46 | bits. 47 | 48 | In future examples, we may annotate the type in a comment. The examples will 49 | look like this: 50 | 51 | ```{rust} 52 | fn main() { 53 | let x = 5; // x: i32 54 | } 55 | ``` 56 | 57 | Note the similarities between this annotation and the syntax you use with `let`. 58 | Including these kinds of comments is not idiomatic Rust, but we'll occasionally 59 | include them to help you understand what the types that Rust infers are. 60 | 61 | By default, bindings are *immutable*. This code will not compile: 62 | 63 | ```{ignore} 64 | let x = 5; 65 | x = 10; 66 | ``` 67 | 68 | It will give you this error: 69 | 70 | ```text 71 | error: re-assignment of immutable variable `x` 72 | x = 10; 73 | ^~~~~~~ 74 | ``` 75 | 76 | If you want a binding to be mutable, you can use `mut`: 77 | 78 | ```{rust} 79 | let mut x = 5; // mut x: i32 80 | x = 10; 81 | ``` 82 | 83 | There is no single reason that bindings are immutable by default, but we can 84 | think about it through one of Rust's primary focuses: safety. If you forget to 85 | say `mut`, the compiler will catch it, and let you know that you have mutated 86 | something you may not have intended to mutate. If bindings were mutable by 87 | default, the compiler would not be able to tell you this. If you _did_ intend 88 | mutation, then the solution is quite easy: add `mut`. 89 | 90 | There are other good reasons to avoid mutable state when possible, but they're 91 | out of the scope of this guide. In general, you can often avoid explicit 92 | mutation, and so it is preferable in Rust. That said, sometimes, mutation is 93 | what you need, so it's not verboten. 94 | 95 | Let's get back to bindings. Rust variable bindings have one more aspect that 96 | differs from other languages: bindings are required to be initialized with a 97 | value before you're allowed to use them. 98 | 99 | Let's try it out. Change your `src/main.rs` file to look like this: 100 | 101 | ```{rust} 102 | fn main() { 103 | let x: i32; 104 | 105 | println!("Hello world!"); 106 | } 107 | ``` 108 | 109 | You can use `cargo build` on the command line to build it. You'll get a warning, 110 | but it will still print "Hello, world!": 111 | 112 | ```text 113 | Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world) 114 | src/main.rs:2:9: 2:10 warning: unused variable: `x`, #[warn(unused_variable)] on by default 115 | src/main.rs:2 let x: i32; 116 | ^ 117 | ``` 118 | 119 | Rust warns us that we never use the variable binding, but since we never use it, 120 | no harm, no foul. Things change if we try to actually use this `x`, however. Let's 121 | do that. Change your program to look like this: 122 | 123 | ```{rust,ignore} 124 | fn main() { 125 | let x: i32; 126 | 127 | println!("The value of x is: {}", x); 128 | } 129 | ``` 130 | 131 | And try to build it. You'll get an error: 132 | 133 | ```{bash} 134 | $ cargo build 135 | Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world) 136 | src/main.rs:4:39: 4:40 error: use of possibly uninitialized variable: `x` 137 | src/main.rs:4 println!("The value of x is: {}", x); 138 | ^ 139 | note: in expansion of format_args! 140 | :2:23: 2:77 note: expansion site 141 | :1:1: 3:2 note: in expansion of println! 142 | src/main.rs:4:5: 4:42 note: expansion site 143 | error: aborting due to previous error 144 | Could not compile `hello_world`. 145 | ``` 146 | 147 | Rust will not let us use a value that has not been initialized. Next, let's 148 | talk about this stuff we've added to `println!`. 149 | 150 | If you include two curly braces (`{}`, some call them moustaches...) in your 151 | string to print, Rust will interpret this as a request to interpolate some sort 152 | of value. *String interpolation* is a computer science term that means "stick 153 | in the middle of a string." We add a comma, and then `x`, to indicate that we 154 | want `x` to be the value we're interpolating. The comma is used to separate 155 | arguments we pass to functions and macros, if you're passing more than one. 156 | 157 | When you just use the curly braces, Rust will attempt to display the 158 | value in a meaningful way by checking out its type. If you want to specify the 159 | format in a more detailed manner, there are a [wide number of options 160 | available](../std/fmt/index.html). For now, we'll just stick to the default: 161 | integers aren't very complicated to print. 162 | -------------------------------------------------------------------------------- /associated-types.md: -------------------------------------------------------------------------------- 1 | % Associated Types 2 | 3 | Associated types are a powerful part of Rust's type system. They're related to 4 | the idea of a 'type family', in other words, grouping multiple types together. That 5 | description is a bit abstract, so let's dive right into an example. If you want 6 | to write a `Graph` trait, you have two types to be generic over: the node type 7 | and the edge type. So you might write a trait, `Graph`, that looks like 8 | this: 9 | 10 | ```rust 11 | trait Graph { 12 | fn has_edge(&self, &N, &N) -> bool; 13 | fn edges(&self, &N) -> Vec; 14 | // etc 15 | } 16 | ``` 17 | 18 | While this sort of works, it ends up being awkward. For example, any function 19 | that wants to take a `Graph` as a parameter now _also_ needs to be generic over 20 | the `N`ode and `E`dge types too: 21 | 22 | ```rust,ignore 23 | fn distance>(graph: &G, start: &N, end: &N) -> u32 { ... } 24 | ``` 25 | 26 | Our distance calculation works regardless of our `Edge` type, so the `E` stuff in 27 | this signature is just a distraction. 28 | 29 | What we really want to say is that a certain `E`dge and `N`ode type come together 30 | to form each kind of `Graph`. We can do that with associated types: 31 | 32 | ```rust 33 | trait Graph { 34 | type N; 35 | type E; 36 | 37 | fn has_edge(&self, &Self::N, &Self::N) -> bool; 38 | fn edges(&self, &Self::N) -> Vec; 39 | // etc 40 | } 41 | ``` 42 | 43 | Now, our clients can be abstract over a given `Graph`: 44 | 45 | ```rust,ignore 46 | fn distance(graph: &G, start: &G::N, end: &G::N) -> uint { ... } 47 | ``` 48 | 49 | No need to deal with the `E`dge type here! 50 | 51 | Let's go over all this in more detail. 52 | 53 | ## Defining associated types 54 | 55 | Let's build that `Graph` trait. Here's the definition: 56 | 57 | ```rust 58 | trait Graph { 59 | type N; 60 | type E; 61 | 62 | fn has_edge(&self, &Self::N, &Self::N) -> bool; 63 | fn edges(&self, &Self::N) -> Vec; 64 | } 65 | ``` 66 | 67 | Simple enough. Associated types use the `type` keyword, and go inside the body 68 | of the trait, with the functions. 69 | 70 | These `type` declarations can have all the same thing as functions do. For example, 71 | if we wanted our `N` type to implement `Display`, so we can print the nodes out, 72 | we could do this: 73 | 74 | ```rust 75 | use std::fmt; 76 | 77 | trait Graph { 78 | type N: fmt::Display; 79 | type E; 80 | 81 | fn has_edge(&self, &Self::N, &Self::N) -> bool; 82 | fn edges(&self, &Self::N) -> Vec; 83 | } 84 | ``` 85 | 86 | ## Implementing associated types 87 | 88 | Just like any trait, traits that use associated types use the `impl` keyword to 89 | provide implementations. Here's a simple implementation of Graph: 90 | 91 | ```rust 92 | # trait Graph { 93 | # type N; 94 | # type E; 95 | # fn has_edge(&self, &Self::N, &Self::N) -> bool; 96 | # fn edges(&self, &Self::N) -> Vec; 97 | # } 98 | struct Node; 99 | 100 | struct Edge; 101 | 102 | struct MyGraph; 103 | 104 | impl Graph for MyGraph { 105 | type N = Node; 106 | type E = Edge; 107 | 108 | fn has_edge(&self, n1: &Node, n2: &Node) -> bool { 109 | true 110 | } 111 | 112 | fn edges(&self, n: &Node) -> Vec { 113 | Vec::new() 114 | } 115 | } 116 | ``` 117 | 118 | This silly implementation always returns `true` and an empty `Vec`, but it 119 | gives you an idea of how to implement this kind of thing. We first need three 120 | `struct`s, one for the graph, one for the node, and one for the edge. If it made 121 | more sense to use a different type, that would work as well, we're just going to 122 | use `struct`s for all three here. 123 | 124 | Next is the `impl` line, which is just like implementing any other trait. 125 | 126 | From here, we use `=` to define our associated types. The name the trait uses 127 | goes on the left of the `=`, and the concrete type we're `impl`ementing this 128 | for goes on the right. Finally, we use the concrete types in our function 129 | declarations. 130 | 131 | ## Trait objects with associated types 132 | 133 | There’s one more bit of syntax we should talk about: trait objects. If you 134 | try to create a trait object from an associated type, like this: 135 | 136 | ```rust,ignore 137 | # trait Graph { 138 | # type N; 139 | # type E; 140 | # fn has_edge(&self, &Self::N, &Self::N) -> bool; 141 | # fn edges(&self, &Self::N) -> Vec; 142 | # } 143 | # struct Node; 144 | # struct Edge; 145 | # struct MyGraph; 146 | # impl Graph for MyGraph { 147 | # type N = Node; 148 | # type E = Edge; 149 | # fn has_edge(&self, n1: &Node, n2: &Node) -> bool { 150 | # true 151 | # } 152 | # fn edges(&self, n: &Node) -> Vec { 153 | # Vec::new() 154 | # } 155 | # } 156 | let graph = MyGraph; 157 | let obj = Box::new(graph) as Box; 158 | ``` 159 | 160 | You’ll get two errors: 161 | 162 | ```text 163 | error: the value of the associated type `E` (from the trait `main::Graph`) must 164 | be specified [E0191] 165 | let obj = Box::new(graph) as Box; 166 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 167 | 24:44 error: the value of the associated type `N` (from the trait 168 | `main::Graph`) must be specified [E0191] 169 | let obj = Box::new(graph) as Box; 170 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 171 | ``` 172 | 173 | We can’t create a trait object like this, becuase we don’t know the associated 174 | types. Instead, we can write this: 175 | 176 | ```rust 177 | # trait Graph { 178 | # type N; 179 | # type E; 180 | # fn has_edge(&self, &Self::N, &Self::N) -> bool; 181 | # fn edges(&self, &Self::N) -> Vec; 182 | # } 183 | # struct Node; 184 | # struct Edge; 185 | # struct MyGraph; 186 | # impl Graph for MyGraph { 187 | # type N = Node; 188 | # type E = Edge; 189 | # fn has_edge(&self, n1: &Node, n2: &Node) -> bool { 190 | # true 191 | # } 192 | # fn edges(&self, n: &Node) -> Vec { 193 | # Vec::new() 194 | # } 195 | # } 196 | let graph = MyGraph; 197 | let obj = Box::new(graph) as Box>; 198 | ``` 199 | 200 | The `N=Node` syntax allows us to provide a concrete type, `Node`, for the `N` 201 | type parameter. Same with `E=Edge`. If we didn’t proide this constraint, we 202 | couldn’t be sure which `impl` to match this trait object to. 203 | -------------------------------------------------------------------------------- /method-syntax.md: -------------------------------------------------------------------------------- 1 | % Method Syntax 2 | 3 | Functions are great, but if you want to call a bunch of them on some data, it 4 | can be awkward. Consider this code: 5 | 6 | ```{rust,ignore} 7 | baz(bar(foo(x))); 8 | ``` 9 | 10 | We would read this left-to right, and so we see "baz bar foo." But this isn't the 11 | order that the functions would get called in, that's inside-out: "foo bar baz." 12 | Wouldn't it be nice if we could do this instead? 13 | 14 | ```{rust,ignore} 15 | x.foo().bar().baz(); 16 | ``` 17 | 18 | Luckily, as you may have guessed with the leading question, you can! Rust provides 19 | the ability to use this *method call syntax* via the `impl` keyword. 20 | 21 | ## Method calls 22 | 23 | Here's how it works: 24 | 25 | ```{rust} 26 | # #![feature(core)] 27 | struct Circle { 28 | x: f64, 29 | y: f64, 30 | radius: f64, 31 | } 32 | 33 | impl Circle { 34 | fn area(&self) -> f64 { 35 | std::f64::consts::PI * (self.radius * self.radius) 36 | } 37 | } 38 | 39 | fn main() { 40 | let c = Circle { x: 0.0, y: 0.0, radius: 2.0 }; 41 | println!("{}", c.area()); 42 | } 43 | ``` 44 | 45 | This will print `12.566371`. 46 | 47 | We've made a struct that represents a circle. We then write an `impl` block, 48 | and inside it, define a method, `area`. Methods take a special first 49 | parameter, `&self`. There are three variants: `self`, `&self`, and `&mut self`. 50 | You can think of this first parameter as being the `x` in `x.foo()`. The three 51 | variants correspond to the three kinds of thing `x` could be: `self` if it's 52 | just a value on the stack, `&self` if it's a reference, and `&mut self` if it's 53 | a mutable reference. We should default to using `&self`, as it's the most 54 | common. Here's an example of all three variants: 55 | 56 | ```rust 57 | struct Circle { 58 | x: f64, 59 | y: f64, 60 | radius: f64, 61 | } 62 | 63 | impl Circle { 64 | fn reference(&self) { 65 | println!("taking self by reference!"); 66 | } 67 | 68 | fn mutable_reference(&mut self) { 69 | println!("taking self by mutable reference!"); 70 | } 71 | 72 | fn takes_ownership(self) { 73 | println!("taking ownership of self!"); 74 | } 75 | } 76 | ``` 77 | 78 | Finally, as you may remember, the value of the area of a circle is `π*r²`. 79 | Because we took the `&self` parameter to `area`, we can use it just like any 80 | other parameter. Because we know it's a `Circle`, we can access the `radius` 81 | just like we would with any other struct. An import of π and some 82 | multiplications later, and we have our area. 83 | 84 | ## Chaining method calls 85 | 86 | So, now we know how to call a method, such as `foo.bar()`. But what about our 87 | original example, `foo.bar().baz()`? This is called 'method chaining', and we 88 | can do it by returning `self`. 89 | 90 | ``` 91 | # #![feature(core)] 92 | struct Circle { 93 | x: f64, 94 | y: f64, 95 | radius: f64, 96 | } 97 | 98 | impl Circle { 99 | fn area(&self) -> f64 { 100 | std::f64::consts::PI * (self.radius * self.radius) 101 | } 102 | 103 | fn grow(&self) -> Circle { 104 | Circle { x: self.x, y: self.y, radius: (self.radius * 10.0) } 105 | } 106 | } 107 | 108 | fn main() { 109 | let c = Circle { x: 0.0, y: 0.0, radius: 2.0 }; 110 | println!("{}", c.area()); 111 | 112 | let d = c.grow().area(); 113 | println!("{}", d); 114 | } 115 | ``` 116 | 117 | Check the return type: 118 | 119 | ``` 120 | # struct Circle; 121 | # impl Circle { 122 | fn grow(&self) -> Circle { 123 | # Circle } } 124 | ``` 125 | 126 | We just say we're returning a `Circle`. With this method, we can grow a new 127 | circle with an area that's 100 times larger than the old one. 128 | 129 | ## Static methods 130 | 131 | You can also define methods that do not take a `self` parameter. Here's a 132 | pattern that's very common in Rust code: 133 | 134 | ``` 135 | struct Circle { 136 | x: f64, 137 | y: f64, 138 | radius: f64, 139 | } 140 | 141 | impl Circle { 142 | fn new(x: f64, y: f64, radius: f64) -> Circle { 143 | Circle { 144 | x: x, 145 | y: y, 146 | radius: radius, 147 | } 148 | } 149 | } 150 | 151 | fn main() { 152 | let c = Circle::new(0.0, 0.0, 2.0); 153 | } 154 | ``` 155 | 156 | This *static method* builds a new `Circle` for us. Note that static methods 157 | are called with the `Struct::method()` syntax, rather than the `ref.method()` 158 | syntax. 159 | 160 | ## Builder Pattern 161 | 162 | Let's say that we want our users to be able to create Circles, but we will 163 | allow them to only set the properties they care about. Otherwise, the `x` 164 | and `y` attributes will be `0.0`, and the `radius` will be `1.0`. Rust doesn't 165 | have method overloading, named arguments, or variable arguments. We employ 166 | the builder pattern instead. It looks like this: 167 | 168 | ``` 169 | # #![feature(core)] 170 | struct Circle { 171 | x: f64, 172 | y: f64, 173 | radius: f64, 174 | } 175 | 176 | impl Circle { 177 | fn area(&self) -> f64 { 178 | std::f64::consts::PI * (self.radius * self.radius) 179 | } 180 | } 181 | 182 | struct CircleBuilder { 183 | coordinate: f64, 184 | radius: f64, 185 | } 186 | 187 | impl CircleBuilder { 188 | fn new() -> CircleBuilder { 189 | CircleBuilder { coordinate: 0.0, radius: 0.0, } 190 | } 191 | 192 | fn coordinate(&mut self, coordinate: f64) -> &mut CircleBuilder { 193 | self.coordinate = coordinate; 194 | self 195 | } 196 | 197 | fn radius(&mut self, radius: f64) -> &mut CircleBuilder { 198 | self.radius = radius; 199 | self 200 | } 201 | 202 | fn finalize(&self) -> Circle { 203 | Circle { x: self.coordinate, y: self.coordinate, radius: self.radius } 204 | } 205 | } 206 | 207 | fn main() { 208 | let c = CircleBuilder::new() 209 | .coordinate(10.0) 210 | .radius(5.0) 211 | .finalize(); 212 | 213 | 214 | println!("area: {}", c.area()); 215 | } 216 | ``` 217 | 218 | What we've done here is make another struct, `CircleBuilder`. We've defined our 219 | builder methods on it. We've also defined our `area()` method on `Circle`. We 220 | also made one more method on `CircleBuilder`: `finalize()`. This method creates 221 | our final `Circle` from the builder. Now, we've used the type system to enforce 222 | our concerns: we can use the methods on `CircleBuilder` to constrain making 223 | `Circle`s in any way we choose. 224 | -------------------------------------------------------------------------------- /hello-world.md: -------------------------------------------------------------------------------- 1 | % Hello, world! 2 | 3 | Now that you have Rust installed, let's write your first Rust program. It's 4 | traditional to make your first program in any new language one that prints the 5 | text "Hello, world!" to the screen. The nice thing about starting with such a 6 | simple program is that you can verify that your compiler isn't just installed, 7 | but also working properly. And printing information to the screen is a pretty 8 | common thing to do. 9 | 10 | The first thing that we need to do is make a file to put our code in. I like 11 | to make a `projects` directory in my home directory, and keep all my projects 12 | there. Rust does not care where your code lives. 13 | 14 | This actually leads to one other concern we should address: this guide will 15 | assume that you have basic familiarity with the command line. Rust does not 16 | require that you know a whole ton about the command line, but until the 17 | language is in a more finished state, IDE support is spotty. Rust makes no 18 | specific demands on your editing tooling, or where your code lives. 19 | 20 | With that said, let's make a directory in our projects directory. 21 | 22 | ```{bash} 23 | $ mkdir ~/projects 24 | $ cd ~/projects 25 | $ mkdir hello_world 26 | $ cd hello_world 27 | ``` 28 | 29 | If you're on Windows and not using PowerShell, the `~` may not work. Consult 30 | the documentation for your shell for more details. 31 | 32 | Let's make a new source file next. I'm going to use the syntax `editor 33 | filename` to represent editing a file in these examples, but you should use 34 | whatever method you want. We'll call our file `main.rs`: 35 | 36 | ```{bash} 37 | $ editor main.rs 38 | ``` 39 | 40 | Rust files always end in a `.rs` extension. If you're using more than one word 41 | in your filename, use an underscore. `hello_world.rs` rather than 42 | `helloworld.rs`. 43 | 44 | Now that you've got your file open, type this in: 45 | 46 | ```{rust} 47 | fn main() { 48 | println!("Hello, world!"); 49 | } 50 | ``` 51 | 52 | Save the file, and then type this into your terminal window: 53 | 54 | ```{bash} 55 | $ rustc main.rs 56 | $ ./main # or main.exe on Windows 57 | Hello, world! 58 | ``` 59 | 60 | 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. 61 | 62 | Success! Let's go over what just happened in detail. 63 | 64 | ```{rust} 65 | fn main() { 66 | 67 | } 68 | ``` 69 | 70 | These lines define a *function* in Rust. The `main` function is special: 71 | it's the beginning of every Rust program. The first line says "I'm declaring a 72 | function named `main`, which takes no arguments and returns nothing." If there 73 | were arguments, they would go inside the parentheses (`(` and `)`), and because 74 | we aren't returning anything from this function, we can omit the return type 75 | entirely. We'll get to it later. 76 | 77 | You'll also note that the function is wrapped in curly braces (`{` and `}`). 78 | Rust requires these around all function bodies. It is also considered good 79 | style to put the opening curly brace on the same line as the function 80 | declaration, with one space in between. 81 | 82 | Next up is this line: 83 | 84 | ```{rust} 85 | println!("Hello, world!"); 86 | ``` 87 | 88 | This line does all of the work in our little program. There are a number of 89 | details that are important here. The first is that it's indented with four 90 | spaces, not tabs. Please configure your editor of choice to insert four spaces 91 | with the tab key. We provide some [sample configurations for various 92 | editors](https://github.com/rust-lang/rust/tree/master/src/etc/CONFIGS.md). 93 | 94 | The second point is the `println!()` part. This is calling a Rust *macro*, 95 | which is how metaprogramming is done in Rust. If it were a function instead, it 96 | would look like this: `println()`. For our purposes, we don't need to worry 97 | about this difference. Just know that sometimes, you'll see a `!`, and that 98 | means that you're calling a macro instead of a normal function. Rust implements 99 | `println!` as a macro rather than a function for good reasons, but that's a 100 | very advanced topic. You'll learn more when we talk about macros later. One 101 | last thing to mention: Rust's macros are significantly different from C macros, 102 | if you've used those. Don't be scared of using macros. We'll get to the details 103 | eventually, you'll just have to trust us for now. 104 | 105 | Next, `"Hello, world!"` is a *string*. Strings are a surprisingly complicated 106 | topic in a systems programming language, and this is a *statically allocated* 107 | string. We will talk more about different kinds of allocation later. We pass 108 | this string as an argument to `println!`, which prints the string to the 109 | screen. Easy enough! 110 | 111 | Finally, the line ends with a semicolon (`;`). Rust is an *expression 112 | oriented* language, which means that most things are expressions. The `;` is 113 | used to indicate that this expression is over, and the next one is ready to 114 | begin. Most lines of Rust code end with a `;`. We will cover this in-depth 115 | later in the guide. 116 | 117 | Finally, actually *compiling* and *running* our program. We can compile 118 | with our compiler, `rustc`, by passing it the name of our source file: 119 | 120 | ```{bash} 121 | $ rustc main.rs 122 | ``` 123 | 124 | This is similar to `gcc` or `clang`, if you come from a C or C++ background. Rust 125 | will output a binary executable. You can see it with `ls`: 126 | 127 | ```{bash} 128 | $ ls 129 | main main.rs 130 | ``` 131 | 132 | Or on Windows: 133 | 134 | ```{bash} 135 | $ dir 136 | main.exe main.rs 137 | ``` 138 | 139 | There are now two files: our source code, with the `.rs` extension, and the 140 | executable (`main.exe` on Windows, `main` everywhere else) 141 | 142 | ```{bash} 143 | $ ./main # or main.exe on Windows 144 | ``` 145 | 146 | This prints out our `Hello, world!` text to our terminal. 147 | 148 | If you come from a dynamically typed language like Ruby, Python, or JavaScript, 149 | you may not be used to these two steps being separate. Rust is an 150 | *ahead-of-time compiled language*, which means that you can compile a 151 | program, give it to someone else, and they don't need to have Rust installed. 152 | If you give someone a `.rb` or `.py` or `.js` file, they need to have 153 | Ruby/Python/JavaScript installed, but you just need one command to both compile 154 | and run your program. Everything is a tradeoff in language design, and Rust has 155 | made its choice. 156 | 157 | Congratulations! You have officially written a Rust program. That makes you a 158 | Rust programmer! Welcome. 159 | 160 | Next, I'd like to introduce you to another tool, Cargo, which is used to write 161 | real-world Rust programs. Just using `rustc` is nice for simple things, but as 162 | your project grows, you'll want something to help you manage all of the options 163 | that it has, and to make it easy to share your code with other people and 164 | projects. 165 | -------------------------------------------------------------------------------- /more-strings.md: -------------------------------------------------------------------------------- 1 | % More Strings 2 | 3 | Strings are an important concept to master in any programming language. If you 4 | come from a managed language background, you may be surprised at the complexity 5 | of string handling in a systems programming language. Efficient access and 6 | allocation of memory for a dynamically sized structure involves a lot of 7 | details. Luckily, Rust has lots of tools to help us here. 8 | 9 | A **string** is a sequence of unicode scalar values encoded as a stream of 10 | UTF-8 bytes. All strings are guaranteed to be validly-encoded UTF-8 sequences. 11 | Additionally, strings are not null-terminated and can contain null bytes. 12 | 13 | Rust has two main types of strings: `&str` and `String`. 14 | 15 | # `&str` 16 | 17 | The first kind is a `&str`. This is pronounced a 'string slice'. 18 | String literals are of the type `&str`: 19 | 20 | ``` 21 | let string = "Hello there."; 22 | ``` 23 | 24 | Like any Rust reference, string slices have an associated lifetime. A string 25 | literal is a `&'static str`. A string slice can be written without an explicit 26 | lifetime in many cases, such as in function arguments. In these cases the 27 | lifetime will be inferred: 28 | 29 | ``` 30 | fn takes_slice(slice: &str) { 31 | println!("Got: {}", slice); 32 | } 33 | ``` 34 | 35 | Like vector slices, string slices are simply a pointer plus a length. This 36 | means that they're a 'view' into an already-allocated string, such as a 37 | string literal or a `String`. 38 | 39 | ## `str` 40 | 41 | You may occasionally see references to a `str` type, without the `&`. While 42 | this type does exist, it’s not something you want to use yourself. Sometimes, 43 | people confuse `str` for `String`, and write this: 44 | 45 | ```rust 46 | struct S { 47 | s: str, 48 | } 49 | ``` 50 | 51 | This leads to ugly errors: 52 | 53 | ```text 54 | error: the trait `core::marker::Sized` is not implemented for the type `str` [E0277] 55 | note: `str` does not have a constant size known at compile-time 56 | ``` 57 | 58 | Instead, this `struct` should be 59 | 60 | ```rust 61 | struct S { 62 | s: String, 63 | } 64 | ``` 65 | 66 | So let’s talk about `String`s. 67 | 68 | # `String` 69 | 70 | A `String` is a heap-allocated string. This string is growable, and is 71 | also guaranteed to be UTF-8. `String`s are commonly created by 72 | converting from a string slice using the `to_string` method. 73 | 74 | ``` 75 | let mut s = "Hello".to_string(); 76 | println!("{}", s); 77 | 78 | s.push_str(", world."); 79 | println!("{}", s); 80 | ``` 81 | 82 | A reference to a `String` will automatically coerce to a string slice: 83 | 84 | ``` 85 | fn takes_slice(slice: &str) { 86 | println!("Got: {}", slice); 87 | } 88 | 89 | fn main() { 90 | let s = "Hello".to_string(); 91 | takes_slice(&s); 92 | } 93 | ``` 94 | 95 | You can also get a `&str` from a stack-allocated array of bytes: 96 | 97 | ``` 98 | use std::str; 99 | 100 | let x: &[u8] = &[b'a', b'b']; 101 | let stack_str: &str = str::from_utf8(x).unwrap(); 102 | ``` 103 | 104 | # Best Practices 105 | 106 | ## `String` vs. `&str` 107 | 108 | In general, you should prefer `String` when you need ownership, and `&str` when 109 | you just need to borrow a string. This is very similar to using `Vec` vs. `&[T]`, 110 | and `T` vs `&T` in general. 111 | 112 | This means starting off with this: 113 | 114 | ```{rust,ignore} 115 | fn foo(s: &str) { 116 | ``` 117 | 118 | and only moving to this: 119 | 120 | ```{rust,ignore} 121 | fn foo(s: String) { 122 | ``` 123 | 124 | if you have good reason. It's not polite to hold on to ownership you don't 125 | need, and it can make your lifetimes more complex. 126 | 127 | ## Generic functions 128 | 129 | To write a function that's generic over types of strings, use `&str`. 130 | 131 | ``` 132 | fn some_string_length(x: &str) -> uint { 133 | x.len() 134 | } 135 | 136 | fn main() { 137 | let s = "Hello, world"; 138 | 139 | println!("{}", some_string_length(s)); 140 | 141 | let s = "Hello, world".to_string(); 142 | 143 | println!("{}", some_string_length(&s)); 144 | } 145 | ``` 146 | 147 | Both of these lines will print `12`. 148 | 149 | ## Indexing strings 150 | 151 | You may be tempted to try to access a certain character of a `String`, like 152 | this: 153 | 154 | ```{rust,ignore} 155 | let s = "hello".to_string(); 156 | 157 | println!("{}", s[0]); 158 | ``` 159 | 160 | This does not compile. This is on purpose. In the world of UTF-8, direct 161 | indexing is basically never what you want to do. The reason is that each 162 | character can be a variable number of bytes. This means that you have to iterate 163 | through the characters anyway, which is an O(n) operation. 164 | 165 | There's 3 basic levels of unicode (and its encodings): 166 | 167 | - code units, the underlying data type used to store everything 168 | - code points/unicode scalar values (char) 169 | - graphemes (visible characters) 170 | 171 | Rust provides iterators for each of these situations: 172 | 173 | - `.bytes()` will iterate over the underlying bytes 174 | - `.chars()` will iterate over the code points 175 | - `.graphemes()` will iterate over each grapheme 176 | 177 | Usually, the `graphemes()` method on `&str` is what you want: 178 | 179 | ``` 180 | # #![feature(unicode)] 181 | let s = "u͔n͈̰̎i̙̮͚̦c͚̉o̼̩̰͗d͔̆̓ͥé"; 182 | 183 | for l in s.graphemes(true) { 184 | println!("{}", l); 185 | } 186 | ``` 187 | 188 | This prints: 189 | 190 | ```text 191 | u͔ 192 | n͈̰̎ 193 | i̙̮͚̦ 194 | c͚̉ 195 | o̼̩̰͗ 196 | d͔̆̓ͥ 197 | é 198 | ``` 199 | 200 | Note that `l` has the type `&str` here, since a single grapheme can consist of 201 | multiple codepoints, so a `char` wouldn't be appropriate. 202 | 203 | This will print out each visible character in turn, as you'd expect: first `u͔`, then 204 | `n͈̰̎`, etc. If you wanted each individual codepoint of each grapheme, you can use `.chars()`: 205 | 206 | ``` 207 | let s = "u͔n͈̰̎i̙̮͚̦c͚̉o̼̩̰͗d͔̆̓ͥé"; 208 | 209 | for l in s.chars() { 210 | println!("{}", l); 211 | } 212 | ``` 213 | 214 | This prints: 215 | 216 | ```text 217 | u 218 | ͔ 219 | n 220 | ̎ 221 | ͈ 222 | ̰ 223 | i 224 | ̙ 225 | ̮ 226 | ͚ 227 | ̦ 228 | c 229 | ̉ 230 | ͚ 231 | o 232 | ͗ 233 | ̼ 234 | ̩ 235 | ̰ 236 | d 237 | ̆ 238 | ̓ 239 | ͥ 240 | ͔ 241 | e 242 | ́ 243 | ``` 244 | 245 | You can see how some of them are combining characters, and therefore the output 246 | looks a bit odd. 247 | 248 | If you want the individual byte representation of each codepoint, you can use 249 | `.bytes()`: 250 | 251 | ``` 252 | let s = "u͔n͈̰̎i̙̮͚̦c͚̉o̼̩̰͗d͔̆̓ͥé"; 253 | 254 | for l in s.bytes() { 255 | println!("{}", l); 256 | } 257 | ``` 258 | 259 | This will print: 260 | 261 | ```text 262 | 117 263 | 205 264 | 148 265 | 110 266 | 204 267 | 142 268 | 205 269 | 136 270 | 204 271 | 176 272 | 105 273 | 204 274 | 153 275 | 204 276 | 174 277 | 205 278 | 154 279 | 204 280 | 166 281 | 99 282 | 204 283 | 137 284 | 205 285 | 154 286 | 111 287 | 205 288 | 151 289 | 204 290 | 188 291 | 204 292 | 169 293 | 204 294 | 176 295 | 100 296 | 204 297 | 134 298 | 205 299 | 131 300 | 205 301 | 165 302 | 205 303 | 148 304 | 101 305 | 204 306 | 129 307 | ``` 308 | 309 | Many more bytes than graphemes! 310 | 311 | # `Deref` coercions 312 | 313 | References to `String`s will automatically coerce into `&str`s. Like this: 314 | 315 | ``` 316 | fn hello(s: &str) { 317 | println!("Hello, {}!", s); 318 | } 319 | 320 | let slice = "Steve"; 321 | let string = "Steve".to_string(); 322 | 323 | hello(slice); 324 | hello(&string); 325 | ``` 326 | -------------------------------------------------------------------------------- /closures.md: -------------------------------------------------------------------------------- 1 | % Closures 2 | 3 | So far, we've made lots of functions in Rust, but we've given them all names. 4 | Rust also allows us to create anonymous functions. Rust's anonymous 5 | functions are called *closures*. By themselves, closures aren't all that 6 | interesting, but when you combine them with functions that take closures as 7 | arguments, really powerful things are possible. 8 | 9 | Let's make a closure: 10 | 11 | ```{rust} 12 | let add_one = |x| { 1 + x }; 13 | 14 | println!("The sum of 5 plus 1 is {}.", add_one(5)); 15 | ``` 16 | 17 | We create a closure using the `|...| { ... }` syntax, and then we create a 18 | binding so we can use it later. Note that we call the function using the 19 | binding name and two parentheses, just like we would for a named function. 20 | 21 | Let's compare syntax. The two are pretty close: 22 | 23 | ```{rust} 24 | let add_one = |x: i32| -> i32 { 1 + x }; 25 | fn add_one (x: i32) -> i32 { 1 + x } 26 | ``` 27 | 28 | As you may have noticed, closures infer their argument and return types, so you 29 | don't need to declare one. This is different from named functions, which 30 | default to returning unit (`()`). 31 | 32 | There's one big difference between a closure and named functions, and it's in 33 | the name: a closure "closes over its environment." What does that mean? It means 34 | this: 35 | 36 | ```{rust} 37 | fn main() { 38 | let x: i32 = 5; 39 | 40 | let printer = || { println!("x is: {}", x); }; 41 | 42 | printer(); // prints "x is: 5" 43 | } 44 | ``` 45 | 46 | The `||` syntax means this is an anonymous closure that takes no arguments. 47 | Without it, we'd just have a block of code in `{}`s. 48 | 49 | In other words, a closure has access to variables in the scope where it's 50 | defined. The closure borrows any variables it uses, so this will error: 51 | 52 | ```{rust,ignore} 53 | fn main() { 54 | let mut x: i32 = 5; 55 | 56 | let printer = || { println!("x is: {}", x); }; 57 | 58 | x = 6; // error: cannot assign to `x` because it is borrowed 59 | } 60 | ``` 61 | 62 | ## Moving closures 63 | 64 | Rust has a second type of closure, called a *moving closure*. Moving 65 | closures are indicated using the `move` keyword (e.g., `move || x * 66 | x`). The difference between a moving closure and an ordinary closure 67 | is that a moving closure always takes ownership of all variables that 68 | it uses. Ordinary closures, in contrast, just create a reference into 69 | the enclosing stack frame. Moving closures are most useful with Rust's 70 | concurrency features, and so we'll just leave it at this for 71 | now. We'll talk about them more in the "Concurrency" chapter of the book. 72 | 73 | ## Accepting closures as arguments 74 | 75 | Closures are most useful as an argument to another function. Here's an example: 76 | 77 | ```{rust} 78 | fn twice i32>(x: i32, f: F) -> i32 { 79 | f(x) + f(x) 80 | } 81 | 82 | fn main() { 83 | let square = |x: i32| { x * x }; 84 | 85 | twice(5, square); // evaluates to 50 86 | } 87 | ``` 88 | 89 | Let's break the example down, starting with `main`: 90 | 91 | ```{rust} 92 | let square = |x: i32| { x * x }; 93 | ``` 94 | 95 | We've seen this before. We make a closure that takes an integer, and returns 96 | its square. 97 | 98 | ```{rust} 99 | # fn twice i32>(x: i32, f: F) -> i32 { f(x) + f(x) } 100 | # let square = |x: i32| { x * x }; 101 | twice(5, square); // evaluates to 50 102 | ``` 103 | 104 | This line is more interesting. Here, we call our function, `twice`, and we pass 105 | it two arguments: an integer, `5`, and our closure, `square`. This is just like 106 | passing any other two variable bindings to a function, but if you've never 107 | worked with closures before, it can seem a little complex. Just think: "I'm 108 | passing two variables: one is an i32, and one is a function." 109 | 110 | Next, let's look at how `twice` is defined: 111 | 112 | ```{rust,ignore} 113 | fn twice i32>(x: i32, f: F) -> i32 { 114 | ``` 115 | 116 | `twice` takes two arguments, `x` and `f`. That's why we called it with two 117 | arguments. `x` is an `i32`, we've done that a ton of times. `f` is a function, 118 | though, and that function takes an `i32` and returns an `i32`. This is 119 | what the requirement `Fn(i32) -> i32` for the type parameter `F` says. 120 | Now `F` represents *any* function that takes an `i32` and returns an `i32`. 121 | 122 | This is the most complicated function signature we've seen yet! Give it a read 123 | a few times until you can see how it works. It takes a teeny bit of practice, and 124 | then it's easy. The good news is that this kind of passing a closure around 125 | can be very efficient. With all the type information available at compile-time 126 | the compiler can do wonders. 127 | 128 | Finally, `twice` returns an `i32` as well. 129 | 130 | Okay, let's look at the body of `twice`: 131 | 132 | ```{rust} 133 | fn twice i32>(x: i32, f: F) -> i32 { 134 | f(x) + f(x) 135 | } 136 | ``` 137 | 138 | Since our closure is named `f`, we can call it just like we called our closures 139 | before, and we pass in our `x` argument to each one, hence the name `twice`. 140 | 141 | If you do the math, `(5 * 5) + (5 * 5) == 50`, so that's the output we get. 142 | 143 | Play around with this concept until you're comfortable with it. Rust's standard 144 | library uses lots of closures where appropriate, so you'll be using 145 | this technique a lot. 146 | 147 | If we didn't want to give `square` a name, we could just define it inline. 148 | This example is the same as the previous one: 149 | 150 | ```{rust} 151 | fn twice i32>(x: i32, f: F) -> i32 { 152 | f(x) + f(x) 153 | } 154 | 155 | fn main() { 156 | twice(5, |x: i32| { x * x }); // evaluates to 50 157 | } 158 | ``` 159 | 160 | A named function's name can be used wherever you'd use a closure. Another 161 | way of writing the previous example: 162 | 163 | ```{rust} 164 | fn twice i32>(x: i32, f: F) -> i32 { 165 | f(x) + f(x) 166 | } 167 | 168 | fn square(x: i32) -> i32 { x * x } 169 | 170 | fn main() { 171 | twice(5, square); // evaluates to 50 172 | } 173 | ``` 174 | 175 | Doing this is not particularly common, but it's useful every once in a while. 176 | 177 | Before we move on, let us look at a function that accepts two closures. 178 | 179 | ```{rust} 180 | fn compose(x: i32, f: F, g: G) -> i32 181 | where F: Fn(i32) -> i32, G: Fn(i32) -> i32 { 182 | g(f(x)) 183 | } 184 | 185 | fn main() { 186 | compose(5, 187 | |n: i32| { n + 42 }, 188 | |n: i32| { n * 2 }); // evaluates to 94 189 | } 190 | ``` 191 | 192 | You might ask yourself: why do we need to introduce two type 193 | parameters `F` and `G` here? Evidently, both `f` and `g` have the 194 | same signature: `Fn(i32) -> i32`. 195 | 196 | That is because in Rust each closure has its own unique type. 197 | So, not only do closures with different signatures have different types, 198 | but different closures with the *same* signature have *different* 199 | types, as well! 200 | 201 | You can think of it this way: the behavior of a closure is part of its 202 | type. Therefore, using a single type parameter for both closures 203 | will accept the first of them, rejecting the second. The distinct 204 | type of the second closure does not allow it to be represented by the 205 | same type parameter as that of the first. We acknowledge this, and 206 | use two different type parameters `F` and `G`. 207 | 208 | This also introduces the `where` clause, which lets us describe type 209 | parameters in a more flexible manner. 210 | 211 | That's all you need to get the hang of closures! Closures are a little bit 212 | strange at first, but once you're used to them, you'll miss them 213 | in other languages. Passing functions to other functions is 214 | incredibly powerful, as you will see in the following chapter about iterators. 215 | -------------------------------------------------------------------------------- /advanced-macros.md: -------------------------------------------------------------------------------- 1 | % Advanced macros 2 | 3 | This chapter picks up where the [introductory macro chapter](macros.html) left 4 | off. 5 | 6 | # Syntactic requirements 7 | 8 | Even when Rust code contains un-expanded macros, it can be parsed as a full 9 | [syntax tree][ast]. This property can be very useful for editors and other 10 | tools that process code. It also has a few consequences for the design of 11 | Rust's macro system. 12 | 13 | [ast]: glossary.html#abstract-syntax-tree 14 | 15 | One consequence is that Rust must determine, when it parses a macro invocation, 16 | whether the macro stands in for 17 | 18 | * zero or more items, 19 | * zero or more methods, 20 | * an expression, 21 | * a statement, or 22 | * a pattern. 23 | 24 | A macro invocation within a block could stand for some items, or for an 25 | expression / statement. Rust uses a simple rule to resolve this ambiguity. A 26 | macro invocation that stands for items must be either 27 | 28 | * delimited by curly braces, e.g. `foo! { ... }`, or 29 | * terminated by a semicolon, e.g. `foo!(...);` 30 | 31 | Another consequence of pre-expansion parsing is that the macro invocation must 32 | consist of valid Rust tokens. Furthermore, parentheses, brackets, and braces 33 | must be balanced within a macro invocation. For example, `foo!([)` is 34 | forbidden. This allows Rust to know where the macro invocation ends. 35 | 36 | More formally, the macro invocation body must be a sequence of *token trees*. 37 | A token tree is defined recursively as either 38 | 39 | * a sequence of token trees surrounded by matching `()`, `[]`, or `{}`, or 40 | * any other single token. 41 | 42 | Within a matcher, each metavariable has a *fragment specifier*, identifying 43 | which syntactic form it matches. 44 | 45 | * `ident`: an identifier. Examples: `x`; `foo`. 46 | * `path`: a qualified name. Example: `T::SpecialA`. 47 | * `expr`: an expression. Examples: `2 + 2`; `if true then { 1 } else { 2 }`; `f(42)`. 48 | * `ty`: a type. Examples: `i32`; `Vec<(char, String)>`; `&T`. 49 | * `pat`: a pattern. Examples: `Some(t)`; `(17, 'a')`; `_`. 50 | * `stmt`: a single statement. Example: `let x = 3`. 51 | * `block`: a brace-delimited sequence of statements. Example: 52 | `{ log(error, "hi"); return 12; }`. 53 | * `item`: an [item][]. Examples: `fn foo() { }`; `struct Bar;`. 54 | * `meta`: a "meta item", as found in attributes. Example: `cfg(target_os = "windows")`. 55 | * `tt`: a single token tree. 56 | 57 | There are additional rules regarding the next token after a metavariable: 58 | 59 | * `expr` variables must be followed by one of: `=> , ;` 60 | * `ty` and `path` variables must be followed by one of: `=> , : = > as` 61 | * `pat` variables must be followed by one of: `=> , =` 62 | * Other variables may be followed by any token. 63 | 64 | These rules provide some flexibility for Rust's syntax to evolve without 65 | breaking existing macros. 66 | 67 | The macro system does not deal with parse ambiguity at all. For example, the 68 | grammar `$($t:ty)* $e:expr` will always fail to parse, because the parser would 69 | be forced to choose between parsing `$t` and parsing `$e`. Changing the 70 | invocation syntax to put a distinctive token in front can solve the problem. In 71 | this case, you can write `$(T $t:ty)* E $e:exp`. 72 | 73 | [item]: ../reference.html#items 74 | 75 | # Scoping and macro import/export 76 | 77 | Macros are expanded at an early stage in compilation, before name resolution. 78 | One downside is that scoping works differently for macros, compared to other 79 | constructs in the language. 80 | 81 | Definition and expansion of macros both happen in a single depth-first, 82 | lexical-order traversal of a crate's source. So a macro defined at module scope 83 | is visible to any subsequent code in the same module, which includes the body 84 | of any subsequent child `mod` items. 85 | 86 | A macro defined within the body of a single `fn`, or anywhere else not at 87 | module scope, is visible only within that item. 88 | 89 | If a module has the `macro_use` attribute, its macros are also visible in its 90 | parent module after the child's `mod` item. If the parent also has `macro_use` 91 | then the macros will be visible in the grandparent after the parent's `mod` 92 | item, and so forth. 93 | 94 | The `macro_use` attribute can also appear on `extern crate`. In this context 95 | it controls which macros are loaded from the external crate, e.g. 96 | 97 | ```rust,ignore 98 | #[macro_use(foo, bar)] 99 | extern crate baz; 100 | ``` 101 | 102 | If the attribute is given simply as `#[macro_use]`, all macros are loaded. If 103 | there is no `#[macro_use]` attribute then no macros are loaded. Only macros 104 | defined with the `#[macro_export]` attribute may be loaded. 105 | 106 | To load a crate's macros *without* linking it into the output, use `#[no_link]` 107 | as well. 108 | 109 | An example: 110 | 111 | ```rust 112 | macro_rules! m1 { () => (()) } 113 | 114 | // visible here: m1 115 | 116 | mod foo { 117 | // visible here: m1 118 | 119 | #[macro_export] 120 | macro_rules! m2 { () => (()) } 121 | 122 | // visible here: m1, m2 123 | } 124 | 125 | // visible here: m1 126 | 127 | macro_rules! m3 { () => (()) } 128 | 129 | // visible here: m1, m3 130 | 131 | #[macro_use] 132 | mod bar { 133 | // visible here: m1, m3 134 | 135 | macro_rules! m4 { () => (()) } 136 | 137 | // visible here: m1, m3, m4 138 | } 139 | 140 | // visible here: m1, m3, m4 141 | # fn main() { } 142 | ``` 143 | 144 | When this library is loaded with `#[macro_use] extern crate`, only `m2` will 145 | be imported. 146 | 147 | The Rust Reference has a [listing of macro-related 148 | attributes](../reference.html#macro--and-plugin-related-attributes). 149 | 150 | # The variable `$crate` 151 | 152 | A further difficulty occurs when a macro is used in multiple crates. Say that 153 | `mylib` defines 154 | 155 | ```rust 156 | pub fn increment(x: u32) -> u32 { 157 | x + 1 158 | } 159 | 160 | #[macro_export] 161 | macro_rules! inc_a { 162 | ($x:expr) => ( ::increment($x) ) 163 | } 164 | 165 | #[macro_export] 166 | macro_rules! inc_b { 167 | ($x:expr) => ( ::mylib::increment($x) ) 168 | } 169 | # fn main() { } 170 | ``` 171 | 172 | `inc_a` only works within `mylib`, while `inc_b` only works outside the 173 | library. Furthermore, `inc_b` will break if the user imports `mylib` under 174 | another name. 175 | 176 | Rust does not (yet) have a hygiene system for crate references, but it does 177 | provide a simple workaround for this problem. Within a macro imported from a 178 | crate named `foo`, the special macro variable `$crate` will expand to `::foo`. 179 | By contrast, when a macro is defined and then used in the same crate, `$crate` 180 | will expand to nothing. This means we can write 181 | 182 | ```rust 183 | #[macro_export] 184 | macro_rules! inc { 185 | ($x:expr) => ( $crate::increment($x) ) 186 | } 187 | # fn main() { } 188 | ``` 189 | 190 | to define a single macro that works both inside and outside our library. The 191 | function name will expand to either `::increment` or `::mylib::increment`. 192 | 193 | To keep this system simple and correct, `#[macro_use] extern crate ...` may 194 | only appear at the root of your crate, not inside `mod`. This ensures that 195 | `$crate` is a single identifier. 196 | 197 | # The deep end 198 | 199 | The introductory chapter mentioned recursive macros, but it did not give the 200 | full story. Recursive macros are useful for another reason: Each recursive 201 | invocation gives you another opportunity to pattern-match the macro's 202 | arguments. 203 | 204 | As an extreme example, it is possible, though hardly advisable, to implement 205 | the [Bitwise Cyclic Tag](http://esolangs.org/wiki/Bitwise_Cyclic_Tag) automaton 206 | within Rust's macro system. 207 | 208 | ```rust 209 | #![feature(trace_macros)] 210 | 211 | macro_rules! bct { 212 | // cmd 0: d ... => ... 213 | (0, $($ps:tt),* ; $_d:tt) 214 | => (bct!($($ps),*, 0 ; )); 215 | (0, $($ps:tt),* ; $_d:tt, $($ds:tt),*) 216 | => (bct!($($ps),*, 0 ; $($ds),*)); 217 | 218 | // cmd 1p: 1 ... => 1 ... p 219 | (1, $p:tt, $($ps:tt),* ; 1) 220 | => (bct!($($ps),*, 1, $p ; 1, $p)); 221 | (1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*) 222 | => (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p)); 223 | 224 | // cmd 1p: 0 ... => 0 ... 225 | (1, $p:tt, $($ps:tt),* ; $($ds:tt),*) 226 | => (bct!($($ps),*, 1, $p ; $($ds),*)); 227 | 228 | // halt on empty data string 229 | ( $($ps:tt),* ; ) 230 | => (()); 231 | } 232 | 233 | fn main() { 234 | trace_macros!(true); 235 | # /* just check the definition 236 | bct!(0, 0, 1, 1, 1 ; 1, 0, 1); 237 | # */ 238 | } 239 | ``` 240 | 241 | Exercise: use macros to reduce duplication in the above definition of the 242 | `bct!` macro. 243 | 244 | # Procedural macros 245 | 246 | If Rust's macro system can't do what you need, you may want to write a 247 | [compiler plugin](plugins.html) instead. Compared to `macro_rules!` 248 | macros, this is significantly more work, the interfaces are much less stable, 249 | and bugs can be much harder to track down. In exchange you get the 250 | flexibility of running arbitrary Rust code within the compiler. Syntax 251 | extension plugins are sometimes called *procedural macros* for this reason. 252 | -------------------------------------------------------------------------------- /error-handling.md: -------------------------------------------------------------------------------- 1 | % Error Handling 2 | 3 | > The best-laid plans of mice and men 4 | > Often go awry 5 | > 6 | > "Tae a Moose", Robert Burns 7 | 8 | Sometimes, things just go wrong. It's important to have a plan for when the 9 | inevitable happens. Rust has rich support for handling errors that may (let's 10 | be honest: will) occur in your programs. 11 | 12 | There are two main kinds of errors that can occur in your programs: failures, 13 | and panics. Let's talk about the difference between the two, and then discuss 14 | how to handle each. Then, we'll discuss upgrading failures to panics. 15 | 16 | # Failure vs. Panic 17 | 18 | Rust uses two terms to differentiate between two forms of error: failure, and 19 | panic. A *failure* is an error that can be recovered from in some way. A 20 | *panic* is an error that cannot be recovered from. 21 | 22 | What do we mean by "recover"? Well, in most cases, the possibility of an error 23 | is expected. For example, consider the `from_str` function: 24 | 25 | ```{rust,ignore} 26 | from_str("5"); 27 | ``` 28 | 29 | This function takes a string argument and converts it into another type. But 30 | because it's a string, you can't be sure that the conversion actually works. 31 | For example, what should this convert to? 32 | 33 | ```{rust,ignore} 34 | from_str("hello5world"); 35 | ``` 36 | 37 | This won't work. So we know that this function will only work properly for some 38 | inputs. It's expected behavior. We call this kind of error a *failure*. 39 | 40 | On the other hand, sometimes, there are errors that are unexpected, or which 41 | we cannot recover from. A classic example is an `assert!`: 42 | 43 | ```{rust,ignore} 44 | assert!(x == 5); 45 | ``` 46 | 47 | We use `assert!` to declare that something is true. If it's not true, something 48 | is very wrong. Wrong enough that we can't continue with things in the current 49 | state. Another example is using the `unreachable!()` macro: 50 | 51 | ```{rust,ignore} 52 | enum Event { 53 | NewRelease, 54 | } 55 | 56 | fn probability(_: &Event) -> f64 { 57 | // real implementation would be more complex, of course 58 | 0.95 59 | } 60 | 61 | fn descriptive_probability(event: Event) -> &'static str { 62 | match probability(&event) { 63 | 1.00 => "certain", 64 | 0.00 => "impossible", 65 | 0.00 ... 0.25 => "very unlikely", 66 | 0.25 ... 0.50 => "unlikely", 67 | 0.50 ... 0.75 => "likely", 68 | 0.75 ... 1.00 => "very likely", 69 | } 70 | } 71 | 72 | fn main() { 73 | std::io::println(descriptive_probability(NewRelease)); 74 | } 75 | ``` 76 | 77 | This will give us an error: 78 | 79 | ```text 80 | error: non-exhaustive patterns: `_` not covered [E0004] 81 | ``` 82 | 83 | While we know that we've covered all possible cases, Rust can't tell. It 84 | doesn't know that probability is between 0.0 and 1.0. So we add another case: 85 | 86 | ```rust 87 | use Event::NewRelease; 88 | 89 | enum Event { 90 | NewRelease, 91 | } 92 | 93 | fn probability(_: &Event) -> f64 { 94 | // real implementation would be more complex, of course 95 | 0.95 96 | } 97 | 98 | fn descriptive_probability(event: Event) -> &'static str { 99 | match probability(&event) { 100 | 1.00 => "certain", 101 | 0.00 => "impossible", 102 | 0.00 ... 0.25 => "very unlikely", 103 | 0.25 ... 0.50 => "unlikely", 104 | 0.50 ... 0.75 => "likely", 105 | 0.75 ... 1.00 => "very likely", 106 | _ => unreachable!() 107 | } 108 | } 109 | 110 | fn main() { 111 | println!("{}", descriptive_probability(NewRelease)); 112 | } 113 | ``` 114 | 115 | We shouldn't ever hit the `_` case, so we use the `unreachable!()` macro to 116 | indicate this. `unreachable!()` gives a different kind of error than `Result`. 117 | Rust calls these sorts of errors *panics*. 118 | 119 | # Handling errors with `Option` and `Result` 120 | 121 | The simplest way to indicate that a function may fail is to use the `Option` 122 | type. Remember our `from_str()` example? Here's its type signature: 123 | 124 | ```{rust,ignore} 125 | pub fn from_str(s: &str) -> Option 126 | ``` 127 | 128 | `from_str()` returns an `Option`. If the conversion succeeds, it will return 129 | `Some(value)`, and if it fails, it will return `None`. 130 | 131 | This is appropriate for the simplest of cases, but doesn't give us a lot of 132 | information in the failure case. What if we wanted to know _why_ the conversion 133 | failed? For this, we can use the `Result` type. It looks like this: 134 | 135 | ```rust 136 | enum Result { 137 | Ok(T), 138 | Err(E) 139 | } 140 | ``` 141 | 142 | This enum is provided by Rust itself, so you don't need to define it to use it 143 | in your code. The `Ok(T)` variant represents a success, and the `Err(E)` variant 144 | represents a failure. Returning a `Result` instead of an `Option` is recommended 145 | for all but the most trivial of situations. 146 | 147 | Here's an example of using `Result`: 148 | 149 | ```rust 150 | #[derive(Debug)] 151 | enum Version { Version1, Version2 } 152 | 153 | #[derive(Debug)] 154 | enum ParseError { InvalidHeaderLength, InvalidVersion } 155 | 156 | fn parse_version(header: &[u8]) -> Result { 157 | if header.len() < 1 { 158 | return Err(ParseError::InvalidHeaderLength); 159 | } 160 | match header[0] { 161 | 1 => Ok(Version::Version1), 162 | 2 => Ok(Version::Version2), 163 | _ => Err(ParseError::InvalidVersion) 164 | } 165 | } 166 | 167 | let version = parse_version(&[1, 2, 3, 4]); 168 | match version { 169 | Ok(v) => { 170 | println!("working with version: {:?}", v); 171 | } 172 | Err(e) => { 173 | println!("error parsing header: {:?}", e); 174 | } 175 | } 176 | ``` 177 | 178 | This function makes use of an enum, `ParseError`, to enumerate the various 179 | errors that can occur. 180 | 181 | # Non-recoverable errors with `panic!` 182 | 183 | In the case of an error that is unexpected and not recoverable, the `panic!` 184 | macro will induce a panic. This will crash the current thread, and give an error: 185 | 186 | ```{rust,ignore} 187 | panic!("boom"); 188 | ``` 189 | 190 | gives 191 | 192 | ```text 193 | thread '
' panicked at 'boom', hello.rs:2 194 | ``` 195 | 196 | when you run it. 197 | 198 | Because these kinds of situations are relatively rare, use panics sparingly. 199 | 200 | # Upgrading failures to panics 201 | 202 | In certain circumstances, even though a function may fail, we may want to treat 203 | it as a panic instead. For example, `io::stdin().read_line()` returns an 204 | `IoResult`, a form of `Result`, when there is an error reading the 205 | line. This allows us to handle and possibly recover from this sort of error. 206 | 207 | If we don't want to handle this error, and would rather just abort the program, 208 | we can use the `unwrap()` method: 209 | 210 | ```{rust,ignore} 211 | io::stdin().read_line().unwrap(); 212 | ``` 213 | 214 | `unwrap()` will `panic!` if the `Option` is `None`. This basically says "Give 215 | me the value, and if something goes wrong, just crash." This is less reliable 216 | than matching the error and attempting to recover, but is also significantly 217 | shorter. Sometimes, just crashing is appropriate. 218 | 219 | There's another way of doing this that's a bit nicer than `unwrap()`: 220 | 221 | ```{rust,ignore} 222 | let input = io::stdin().read_line() 223 | .ok() 224 | .expect("Failed to read line"); 225 | ``` 226 | 227 | `ok()` converts the `IoResult` into an `Option`, and `expect()` does the same 228 | thing as `unwrap()`, but takes a message. This message is passed along to the 229 | underlying `panic!`, providing a better error message if the code errors. 230 | 231 | # Using `try!` 232 | 233 | When writing code that calls many functions that return the `Result` type, the 234 | error handling can be tedious. The `try!` macro hides some of the boilerplate 235 | of propagating errors up the call stack. 236 | 237 | It replaces this: 238 | 239 | ```rust 240 | use std::fs::File; 241 | use std::io; 242 | use std::io::prelude::*; 243 | 244 | struct Info { 245 | name: String, 246 | age: i32, 247 | rating: i32, 248 | } 249 | 250 | fn write_info(info: &Info) -> io::Result<()> { 251 | let mut file = File::open("my_best_friends.txt").unwrap(); 252 | 253 | if let Err(e) = writeln!(&mut file, "name: {}", info.name) { 254 | return Err(e) 255 | } 256 | if let Err(e) = writeln!(&mut file, "age: {}", info.age) { 257 | return Err(e) 258 | } 259 | if let Err(e) = writeln!(&mut file, "rating: {}", info.rating) { 260 | return Err(e) 261 | } 262 | 263 | return Ok(()); 264 | } 265 | ``` 266 | 267 | With this: 268 | 269 | ```rust 270 | use std::fs::File; 271 | use std::io; 272 | use std::io::prelude::*; 273 | 274 | struct Info { 275 | name: String, 276 | age: i32, 277 | rating: i32, 278 | } 279 | 280 | fn write_info(info: &Info) -> io::Result<()> { 281 | let mut file = try!(File::open("my_best_friends.txt")); 282 | 283 | try!(writeln!(&mut file, "name: {}", info.name)); 284 | try!(writeln!(&mut file, "age: {}", info.age)); 285 | try!(writeln!(&mut file, "rating: {}", info.rating)); 286 | 287 | return Ok(()); 288 | } 289 | ``` 290 | 291 | Wrapping an expression in `try!` will result in the unwrapped success (`Ok`) 292 | value, unless the result is `Err`, in which case `Err` is returned early from 293 | the enclosing function. 294 | 295 | It's worth noting that you can only use `try!` from a function that returns a 296 | `Result`, which means that you cannot use `try!` inside of `main()`, because 297 | `main()` doesn't return anything. 298 | 299 | `try!` makes use of [`FromError`](../std/error/#the-fromerror-trait) to determine 300 | what to return in the error case. 301 | -------------------------------------------------------------------------------- /plugins.md: -------------------------------------------------------------------------------- 1 | % Compiler Plugins 2 | 3 |
4 | 5 |

6 | Warning: Plugins are an advanced, unstable feature! For many details, 7 | the only available documentation is the libsyntax and librustc API docs, or even the source 10 | code itself. These internal compiler APIs are also subject to change at any 11 | time. 12 |

13 | 14 |

15 | For defining new syntax it is often much easier to use Rust's built-in macro system. 17 |

18 | 19 |

20 | The code in this document uses language features not covered in the Rust 21 | Guide. See the Reference Manual for more 22 | information. 23 |

24 | 25 |
26 | 27 | # Introduction 28 | 29 | `rustc` can load compiler plugins, which are user-provided libraries that 30 | extend the compiler's behavior with new syntax extensions, lint checks, etc. 31 | 32 | A plugin is a dynamic library crate with a designated *registrar* function that 33 | registers extensions with `rustc`. Other crates can load these extensions using 34 | the crate attribute `#![plugin(...)]`. See the 35 | [`rustc::plugin`](../rustc/plugin/index.html) documentation for more about the 36 | mechanics of defining and loading a plugin. 37 | 38 | If present, arguments passed as `#![plugin(foo(... args ...))]` are not 39 | interpreted by rustc itself. They are provided to the plugin through the 40 | `Registry`'s [`args` method](../rustc/plugin/registry/struct.Registry.html#method.args). 41 | 42 | In the vast majority of cases, a plugin should *only* be used through 43 | `#![plugin]` and not through an `extern crate` item. Linking a plugin would 44 | pull in all of libsyntax and librustc as dependencies of your crate. This is 45 | generally unwanted unless you are building another plugin. The 46 | `plugin_as_library` lint checks these guidelines. 47 | 48 | The usual practice is to put compiler plugins in their own crate, separate from 49 | any `macro_rules!` macros or ordinary Rust code meant to be used by consumers 50 | of a library. 51 | 52 | # Syntax extensions 53 | 54 | Plugins can extend Rust's syntax in various ways. One kind of syntax extension 55 | is the procedural macro. These are invoked the same way as [ordinary 56 | macros](macros.html), but the expansion is performed by arbitrary Rust 57 | code that manipulates [syntax trees](../syntax/ast/index.html) at 58 | compile time. 59 | 60 | Let's write a plugin 61 | [`roman_numerals.rs`](https://github.com/rust-lang/rust/tree/master/src/test/auxiliary/roman_numerals.rs) 62 | that implements Roman numeral integer literals. 63 | 64 | ```ignore 65 | #![crate_type="dylib"] 66 | #![feature(plugin_registrar, rustc_private)] 67 | 68 | extern crate syntax; 69 | extern crate rustc; 70 | 71 | use syntax::codemap::Span; 72 | use syntax::parse::token; 73 | use syntax::ast::{TokenTree, TtToken}; 74 | use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}; 75 | use syntax::ext::build::AstBuilder; // trait for expr_usize 76 | use rustc::plugin::Registry; 77 | 78 | fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) 79 | -> Box { 80 | 81 | static NUMERALS: &'static [(&'static str, u32)] = &[ 82 | ("M", 1000), ("CM", 900), ("D", 500), ("CD", 400), 83 | ("C", 100), ("XC", 90), ("L", 50), ("XL", 40), 84 | ("X", 10), ("IX", 9), ("V", 5), ("IV", 4), 85 | ("I", 1)]; 86 | 87 | let text = match args { 88 | [TtToken(_, token::Ident(s, _))] => token::get_ident(s).to_string(), 89 | _ => { 90 | cx.span_err(sp, "argument should be a single identifier"); 91 | return DummyResult::any(sp); 92 | } 93 | }; 94 | 95 | let mut text = &*text; 96 | let mut total = 0; 97 | while !text.is_empty() { 98 | match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) { 99 | Some(&(rn, val)) => { 100 | total += val; 101 | text = &text[rn.len()..]; 102 | } 103 | None => { 104 | cx.span_err(sp, "invalid Roman numeral"); 105 | return DummyResult::any(sp); 106 | } 107 | } 108 | } 109 | 110 | MacEager::expr(cx.expr_u32(sp, total)) 111 | } 112 | 113 | #[plugin_registrar] 114 | pub fn plugin_registrar(reg: &mut Registry) { 115 | reg.register_macro("rn", expand_rn); 116 | } 117 | ``` 118 | 119 | Then we can use `rn!()` like any other macro: 120 | 121 | ```ignore 122 | #![feature(plugin)] 123 | #![plugin(roman_numerals)] 124 | 125 | fn main() { 126 | assert_eq!(rn!(MMXV), 2015); 127 | } 128 | ``` 129 | 130 | The advantages over a simple `fn(&str) -> u32` are: 131 | 132 | * The (arbitrarily complex) conversion is done at compile time. 133 | * Input validation is also performed at compile time. 134 | * It can be extended to allow use in patterns, which effectively gives 135 | a way to define new literal syntax for any data type. 136 | 137 | In addition to procedural macros, you can define new 138 | [`derive`](../reference.html#derive)-like attributes and other kinds of 139 | extensions. See 140 | [`Registry::register_syntax_extension`](../rustc/plugin/registry/struct.Registry.html#method.register_syntax_extension) 141 | and the [`SyntaxExtension` 142 | enum](http://doc.rust-lang.org/syntax/ext/base/enum.SyntaxExtension.html). For 143 | a more involved macro example, see 144 | [`regex_macros`](https://github.com/rust-lang/regex/blob/master/regex_macros/src/lib.rs). 145 | 146 | 147 | ## Tips and tricks 148 | 149 | Some of the [macro debugging tips](macros.html#debugging-macro-code) are applicable. 150 | 151 | You can use [`syntax::parse`](../syntax/parse/index.html) to turn token trees into 152 | higher-level syntax elements like expressions: 153 | 154 | ```ignore 155 | fn expand_foo(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) 156 | -> Box { 157 | 158 | let mut parser = cx.new_parser_from_tts(args); 159 | 160 | let expr: P = parser.parse_expr(); 161 | ``` 162 | 163 | Looking through [`libsyntax` parser 164 | code](https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/parser.rs) 165 | will give you a feel for how the parsing infrastructure works. 166 | 167 | Keep the [`Span`s](../syntax/codemap/struct.Span.html) of 168 | everything you parse, for better error reporting. You can wrap 169 | [`Spanned`](../syntax/codemap/struct.Spanned.html) around 170 | your custom data structures. 171 | 172 | Calling 173 | [`ExtCtxt::span_fatal`](../syntax/ext/base/struct.ExtCtxt.html#method.span_fatal) 174 | will immediately abort compilation. It's better to instead call 175 | [`ExtCtxt::span_err`](../syntax/ext/base/struct.ExtCtxt.html#method.span_err) 176 | and return 177 | [`DummyResult`](../syntax/ext/base/struct.DummyResult.html), 178 | so that the compiler can continue and find further errors. 179 | 180 | To print syntax fragments for debugging, you can use 181 | [`span_note`](../syntax/ext/base/struct.ExtCtxt.html#method.span_note) together 182 | with 183 | [`syntax::print::pprust::*_to_string`](http://doc.rust-lang.org/syntax/print/pprust/index.html#functions). 184 | 185 | The example above produced an integer literal using 186 | [`AstBuilder::expr_usize`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_usize). 187 | As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of 188 | [quasiquote macros](../syntax/ext/quote/index.html). They are undocumented and 189 | very rough around the edges. However, the implementation may be a good 190 | starting point for an improved quasiquote as an ordinary plugin library. 191 | 192 | 193 | # Lint plugins 194 | 195 | Plugins can extend [Rust's lint 196 | infrastructure](../reference.html#lint-check-attributes) with additional checks for 197 | code style, safety, etc. You can see 198 | [`src/test/auxiliary/lint_plugin_test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/auxiliary/lint_plugin_test.rs) 199 | for a full example, the core of which is reproduced here: 200 | 201 | ```ignore 202 | declare_lint!(TEST_LINT, Warn, 203 | "Warn about items named 'lintme'") 204 | 205 | struct Pass; 206 | 207 | impl LintPass for Pass { 208 | fn get_lints(&self) -> LintArray { 209 | lint_array!(TEST_LINT) 210 | } 211 | 212 | fn check_item(&mut self, cx: &Context, it: &ast::Item) { 213 | let name = token::get_ident(it.ident); 214 | if name.get() == "lintme" { 215 | cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"); 216 | } 217 | } 218 | } 219 | 220 | #[plugin_registrar] 221 | pub fn plugin_registrar(reg: &mut Registry) { 222 | reg.register_lint_pass(box Pass as LintPassObject); 223 | } 224 | ``` 225 | 226 | Then code like 227 | 228 | ```ignore 229 | #![plugin(lint_plugin_test)] 230 | 231 | fn lintme() { } 232 | ``` 233 | 234 | will produce a compiler warning: 235 | 236 | ```txt 237 | foo.rs:4:1: 4:16 warning: item is named 'lintme', #[warn(test_lint)] on by default 238 | foo.rs:4 fn lintme() { } 239 | ^~~~~~~~~~~~~~~ 240 | ``` 241 | 242 | The components of a lint plugin are: 243 | 244 | * one or more `declare_lint!` invocations, which define static 245 | [`Lint`](../rustc/lint/struct.Lint.html) structs; 246 | 247 | * a struct holding any state needed by the lint pass (here, none); 248 | 249 | * a [`LintPass`](../rustc/lint/trait.LintPass.html) 250 | implementation defining how to check each syntax element. A single 251 | `LintPass` may call `span_lint` for several different `Lint`s, but should 252 | register them all through the `get_lints` method. 253 | 254 | Lint passes are syntax traversals, but they run at a late stage of compilation 255 | where type information is available. `rustc`'s [built-in 256 | lints](https://github.com/rust-lang/rust/blob/master/src/librustc/lint/builtin.rs) 257 | mostly use the same infrastructure as lint plugins, and provide examples of how 258 | to access type information. 259 | 260 | Lints defined by plugins are controlled by the usual [attributes and compiler 261 | flags](../reference.html#lint-check-attributes), e.g. `#[allow(test_lint)]` or 262 | `-A test-lint`. These identifiers are derived from the first argument to 263 | `declare_lint!`, with appropriate case and punctuation conversion. 264 | 265 | You can run `rustc -W help foo.rs` to see a list of lints known to `rustc`, 266 | including those provided by plugins loaded by `foo.rs`. 267 | -------------------------------------------------------------------------------- /static-and-dynamic-dispatch.md: -------------------------------------------------------------------------------- 1 | % Static and Dynamic Dispatch 2 | 3 | When code involves polymorphism, there needs to be a mechanism to determine 4 | which specific version is actually run. This is called 'dispatch.' There are 5 | two major forms of dispatch: static dispatch and dynamic dispatch. While Rust 6 | favors static dispatch, it also supports dynamic dispatch through a mechanism 7 | called 'trait objects.' 8 | 9 | ## Background 10 | 11 | For the rest of this chapter, we'll need a trait and some implementations. 12 | Let's make a simple one, `Foo`. It has one method that is expected to return a 13 | `String`. 14 | 15 | ```rust 16 | trait Foo { 17 | fn method(&self) -> String; 18 | } 19 | ``` 20 | 21 | We'll also implement this trait for `u8` and `String`: 22 | 23 | ```rust 24 | # trait Foo { fn method(&self) -> String; } 25 | impl Foo for u8 { 26 | fn method(&self) -> String { format!("u8: {}", *self) } 27 | } 28 | 29 | impl Foo for String { 30 | fn method(&self) -> String { format!("string: {}", *self) } 31 | } 32 | ``` 33 | 34 | 35 | ## Static dispatch 36 | 37 | We can use this trait to perform static dispatch with trait bounds: 38 | 39 | ```rust 40 | # trait Foo { fn method(&self) -> String; } 41 | # impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } } 42 | # impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } } 43 | fn do_something(x: T) { 44 | x.method(); 45 | } 46 | 47 | fn main() { 48 | let x = 5u8; 49 | let y = "Hello".to_string(); 50 | 51 | do_something(x); 52 | do_something(y); 53 | } 54 | ``` 55 | 56 | Rust uses 'monomorphization' to perform static dispatch here. This means that 57 | Rust will create a special version of `do_something()` for both `u8` and 58 | `String`, and then replace the call sites with calls to these specialized 59 | functions. In other words, Rust generates something like this: 60 | 61 | ```rust 62 | # trait Foo { fn method(&self) -> String; } 63 | # impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } } 64 | # impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } } 65 | fn do_something_u8(x: u8) { 66 | x.method(); 67 | } 68 | 69 | fn do_something_string(x: String) { 70 | x.method(); 71 | } 72 | 73 | fn main() { 74 | let x = 5u8; 75 | let y = "Hello".to_string(); 76 | 77 | do_something_u8(x); 78 | do_something_string(y); 79 | } 80 | ``` 81 | 82 | This has a great upside: static dispatch allows function calls to be 83 | inlined because the callee is known at compile time, and inlining is 84 | the key to good optimization. Static dispatch is fast, but it comes at 85 | a tradeoff: 'code bloat', due to many copies of the same function 86 | existing in the binary, one for each type. 87 | 88 | Furthermore, compilers aren’t perfect and may “optimize” code to become slower. 89 | For example, functions inlined too eagerly will bloat the instruction cache 90 | (cache rules everything around us). This is part of the reason that `#[inline]` 91 | and `#[inline(always)]` should be used carefully, and one reason why using a 92 | dynamic dispatch is sometimes more efficient. 93 | 94 | However, the common case is that it is more efficient to use static dispatch, 95 | and one can always have a thin statically-dispatched wrapper function that does 96 | a dynamic dispatch, but not vice versa, meaning static calls are more flexible. 97 | The standard library tries to be statically dispatched where possible for this 98 | reason. 99 | 100 | ## Dynamic dispatch 101 | 102 | Rust provides dynamic dispatch through a feature called 'trait objects.' Trait 103 | objects, like `&Foo` or `Box`, are normal values that store a value of 104 | *any* type that implements the given trait, where the precise type can only be 105 | known at runtime. 106 | 107 | A trait object can be obtained from a pointer to a concrete type that 108 | implements the trait by *casting* it (e.g. `&x as &Foo`) or *coercing* it 109 | (e.g. using `&x` as an argument to a function that takes `&Foo`). 110 | 111 | These trait object coercions and casts also work for pointers like `&mut T` to 112 | `&mut Foo` and `Box` to `Box`, but that's all at the moment. Coercions 113 | and casts are identical. 114 | 115 | This operation can be seen as "erasing" the compiler's knowledge about the 116 | specific type of the pointer, and hence trait objects are sometimes referred to 117 | as "type erasure". 118 | 119 | Coming back to the example above, we can use the same trait to perform dynamic 120 | dispatch with trait objects by casting: 121 | 122 | ```rust 123 | # trait Foo { fn method(&self) -> String; } 124 | # impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } } 125 | # impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } } 126 | 127 | fn do_something(x: &Foo) { 128 | x.method(); 129 | } 130 | 131 | fn main() { 132 | let x = 5u8; 133 | do_something(&x as &Foo); 134 | } 135 | ``` 136 | 137 | or by coercing: 138 | 139 | ```rust 140 | # trait Foo { fn method(&self) -> String; } 141 | # impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } } 142 | # impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } } 143 | 144 | fn do_something(x: &Foo) { 145 | x.method(); 146 | } 147 | 148 | fn main() { 149 | let x = "Hello".to_string(); 150 | do_something(&x); 151 | } 152 | ``` 153 | 154 | A function that takes a trait object is not specialized to each of the types 155 | that implements `Foo`: only one copy is generated, often (but not always) 156 | resulting in less code bloat. However, this comes at the cost of requiring 157 | slower virtual function calls, and effectively inhibiting any chance of 158 | inlining and related optimisations from occurring. 159 | 160 | ### Why pointers? 161 | 162 | Rust does not put things behind a pointer by default, unlike many managed 163 | languages, so types can have different sizes. Knowing the size of the value at 164 | compile time is important for things like passing it as an argument to a 165 | function, moving it about on the stack and allocating (and deallocating) space 166 | on the heap to store it. 167 | 168 | For `Foo`, we would need to have a value that could be at least either a 169 | `String` (24 bytes) or a `u8` (1 byte), as well as any other type for which 170 | dependent crates may implement `Foo` (any number of bytes at all). There's no 171 | way to guarantee that this last point can work if the values are stored without 172 | a pointer, because those other types can be arbitrarily large. 173 | 174 | Putting the value behind a pointer means the size of the value is not relevant 175 | when we are tossing a trait object around, only the size of the pointer itself. 176 | 177 | ### Representation 178 | 179 | The methods of the trait can be called on a trait object via a special record 180 | of function pointers traditionally called a 'vtable' (created and managed by 181 | the compiler). 182 | 183 | Trait objects are both simple and complicated: their core representation and 184 | layout is quite straight-forward, but there are some curly error messages and 185 | surprising behaviors to discover. 186 | 187 | Let's start simple, with the runtime representation of a trait object. The 188 | `std::raw` module contains structs with layouts that are the same as the 189 | complicated built-in types, [including trait objects][stdraw]: 190 | 191 | ```rust 192 | # mod foo { 193 | pub struct TraitObject { 194 | pub data: *mut (), 195 | pub vtable: *mut (), 196 | } 197 | # } 198 | ``` 199 | 200 | [stdraw]: ../std/raw/struct.TraitObject.html 201 | 202 | That is, a trait object like `&Foo` consists of a "data" pointer and a "vtable" 203 | pointer. 204 | 205 | The data pointer addresses the data (of some unknown type `T`) that the trait 206 | object is storing, and the vtable pointer points to the vtable ("virtual method 207 | table") corresponding to the implementation of `Foo` for `T`. 208 | 209 | 210 | A vtable is essentially a struct of function pointers, pointing to the concrete 211 | piece of machine code for each method in the implementation. A method call like 212 | `trait_object.method()` will retrieve the correct pointer out of the vtable and 213 | then do a dynamic call of it. For example: 214 | 215 | ```{rust,ignore} 216 | struct FooVtable { 217 | destructor: fn(*mut ()), 218 | size: usize, 219 | align: usize, 220 | method: fn(*const ()) -> String, 221 | } 222 | 223 | // u8: 224 | 225 | fn call_method_on_u8(x: *const ()) -> String { 226 | // the compiler guarantees that this function is only called 227 | // with `x` pointing to a u8 228 | let byte: &u8 = unsafe { &*(x as *const u8) }; 229 | 230 | byte.method() 231 | } 232 | 233 | static Foo_for_u8_vtable: FooVtable = FooVtable { 234 | destructor: /* compiler magic */, 235 | size: 1, 236 | align: 1, 237 | 238 | // cast to a function pointer 239 | method: call_method_on_u8 as fn(*const ()) -> String, 240 | }; 241 | 242 | 243 | // String: 244 | 245 | fn call_method_on_String(x: *const ()) -> String { 246 | // the compiler guarantees that this function is only called 247 | // with `x` pointing to a String 248 | let string: &String = unsafe { &*(x as *const String) }; 249 | 250 | string.method() 251 | } 252 | 253 | static Foo_for_String_vtable: FooVtable = FooVtable { 254 | destructor: /* compiler magic */, 255 | // values for a 64-bit computer, halve them for 32-bit ones 256 | size: 24, 257 | align: 8, 258 | 259 | method: call_method_on_String as fn(*const ()) -> String, 260 | }; 261 | ``` 262 | 263 | The `destructor` field in each vtable points to a function that will clean up 264 | any resources of the vtable's type, for `u8` it is trivial, but for `String` it 265 | will free the memory. This is necessary for owning trait objects like 266 | `Box`, which need to clean-up both the `Box` allocation as well as the 267 | internal type when they go out of scope. The `size` and `align` fields store 268 | the size of the erased type, and its alignment requirements; these are 269 | essentially unused at the moment since the information is embedded in the 270 | destructor, but will be used in the future, as trait objects are progressively 271 | made more flexible. 272 | 273 | Suppose we've got some values that implement `Foo`, then the explicit form of 274 | construction and use of `Foo` trait objects might look a bit like (ignoring the 275 | type mismatches: they're all just pointers anyway): 276 | 277 | ```{rust,ignore} 278 | let a: String = "foo".to_string(); 279 | let x: u8 = 1; 280 | 281 | // let b: &Foo = &a; 282 | let b = TraitObject { 283 | // store the data 284 | data: &a, 285 | // store the methods 286 | vtable: &Foo_for_String_vtable 287 | }; 288 | 289 | // let y: &Foo = x; 290 | let y = TraitObject { 291 | // store the data 292 | data: &x, 293 | // store the methods 294 | vtable: &Foo_for_u8_vtable 295 | }; 296 | 297 | // b.method(); 298 | (b.vtable.method)(b.data); 299 | 300 | // y.method(); 301 | (y.vtable.method)(y.data); 302 | ``` 303 | 304 | If `b` or `y` were owning trait objects (`Box`), there would be a 305 | `(b.vtable.destructor)(b.data)` (respectively `y`) call when they went out of 306 | scope. 307 | -------------------------------------------------------------------------------- /compound-data-types.md: -------------------------------------------------------------------------------- 1 | % Compound Data Types 2 | 3 | Rust, like many programming languages, has a number of different data types 4 | that are built-in. You've already done some simple work with integers and 5 | strings, but next, let's talk about some more complicated ways of storing data. 6 | 7 | ## Tuples 8 | 9 | The first compound data type we're going to talk about is called the *tuple*. 10 | A tuple is an ordered list of fixed size. Like this: 11 | 12 | ```rust 13 | let x = (1, "hello"); 14 | ``` 15 | 16 | The parentheses and commas form this two-length tuple. Here's the same code, but 17 | with the type annotated: 18 | 19 | ```rust 20 | let x: (i32, &str) = (1, "hello"); 21 | ``` 22 | 23 | As you can see, the type of a tuple looks just like the tuple, but with each 24 | position having a type name rather than the value. Careful readers will also 25 | note that tuples are heterogeneous: we have an `i32` and a `&str` in this tuple. 26 | You have briefly seen `&str` used as a type before, and we'll discuss the 27 | details of strings later. In systems programming languages, strings are a bit 28 | more complex than in other languages. For now, just read `&str` as a *string 29 | slice*, and we'll learn more soon. 30 | 31 | You can access the fields in a tuple through a *destructuring let*. Here's 32 | an example: 33 | 34 | ```rust 35 | let (x, y, z) = (1, 2, 3); 36 | 37 | println!("x is {}", x); 38 | ``` 39 | 40 | Remember before when I said the left-hand side of a `let` statement was more 41 | powerful than just assigning a binding? Here we are. We can put a pattern on 42 | the left-hand side of the `let`, and if it matches up to the right-hand side, 43 | we can assign multiple bindings at once. In this case, `let` "destructures," 44 | or "breaks up," the tuple, and assigns the bits to three bindings. 45 | 46 | This pattern is very powerful, and we'll see it repeated more later. 47 | 48 | There are also a few things you can do with a tuple as a whole, without 49 | destructuring. You can assign one tuple into another, if they have the same 50 | contained types and [arity]. Tuples have the same arity when they have the same 51 | length. 52 | 53 | ```rust 54 | let mut x = (1, 2); // x: (i32, i32) 55 | let y = (2, 3); // y: (i32, i32) 56 | 57 | x = y; 58 | ``` 59 | 60 | You can also check for equality with `==`. Again, this will only compile if the 61 | tuples have the same type. 62 | 63 | ```rust 64 | let x = (1, 2, 3); 65 | let y = (2, 2, 4); 66 | 67 | if x == y { 68 | println!("yes"); 69 | } else { 70 | println!("no"); 71 | } 72 | ``` 73 | 74 | This will print `no`, because some of the values aren't equal. 75 | 76 | Note that the order of the values is considered when checking for equality, 77 | so the following example will also print `no`. 78 | 79 | ```rust 80 | let x = (1, 2, 3); 81 | let y = (2, 1, 3); 82 | 83 | if x == y { 84 | println!("yes"); 85 | } else { 86 | println!("no"); 87 | } 88 | ``` 89 | 90 | One other use of tuples is to return multiple values from a function: 91 | 92 | ```rust 93 | fn next_two(x: i32) -> (i32, i32) { (x + 1, x + 2) } 94 | 95 | fn main() { 96 | let (x, y) = next_two(5); 97 | println!("x, y = {}, {}", x, y); 98 | } 99 | ``` 100 | 101 | Even though Rust functions can only return one value, a tuple *is* one value, 102 | that happens to be made up of more than one value. You can also see in this 103 | example how you can destructure a pattern returned by a function, as well. 104 | 105 | Tuples are a very simple data structure, and so are not often what you want. 106 | Let's move on to their bigger sibling, structs. 107 | 108 | ## Structs 109 | 110 | A struct is another form of a *record type*, just like a tuple. There's a 111 | difference: structs give each element that they contain a name, called a 112 | *field* or a *member*. Check it out: 113 | 114 | ```rust 115 | struct Point { 116 | x: i32, 117 | y: i32, 118 | } 119 | 120 | fn main() { 121 | let origin = Point { x: 0, y: 0 }; // origin: Point 122 | 123 | println!("The origin is at ({}, {})", origin.x, origin.y); 124 | } 125 | ``` 126 | 127 | There's a lot going on here, so let's break it down. We declare a struct with 128 | the `struct` keyword, and then with a name. By convention, structs begin with a 129 | capital letter and are also camel cased: `PointInSpace`, not `Point_In_Space`. 130 | 131 | We can create an instance of our struct via `let`, as usual, but we use a `key: 132 | value` style syntax to set each field. The order doesn't need to be the same as 133 | in the original declaration. 134 | 135 | Finally, because fields have names, we can access the field through dot 136 | notation: `origin.x`. 137 | 138 | The values in structs are immutable by default, like other bindings in Rust. 139 | Use `mut` to make them mutable: 140 | 141 | ```{rust} 142 | struct Point { 143 | x: i32, 144 | y: i32, 145 | } 146 | 147 | fn main() { 148 | let mut point = Point { x: 0, y: 0 }; 149 | 150 | point.x = 5; 151 | 152 | println!("The point is at ({}, {})", point.x, point.y); 153 | } 154 | ``` 155 | 156 | This will print `The point is at (5, 0)`. 157 | 158 | ## Tuple Structs and Newtypes 159 | 160 | Rust has another data type that's like a hybrid between a tuple and a struct, 161 | called a *tuple struct*. Tuple structs do have a name, but their fields don't: 162 | 163 | 164 | ```{rust} 165 | struct Color(i32, i32, i32); 166 | struct Point(i32, i32, i32); 167 | ``` 168 | 169 | These two will not be equal, even if they have the same values: 170 | 171 | ```{rust} 172 | # struct Color(i32, i32, i32); 173 | # struct Point(i32, i32, i32); 174 | let black = Color(0, 0, 0); 175 | let origin = Point(0, 0, 0); 176 | ``` 177 | 178 | It is almost always better to use a struct than a tuple struct. We would write 179 | `Color` and `Point` like this instead: 180 | 181 | ```{rust} 182 | struct Color { 183 | red: i32, 184 | blue: i32, 185 | green: i32, 186 | } 187 | 188 | struct Point { 189 | x: i32, 190 | y: i32, 191 | z: i32, 192 | } 193 | ``` 194 | 195 | Now, we have actual names, rather than positions. Good names are important, 196 | and with a struct, we have actual names. 197 | 198 | There _is_ one case when a tuple struct is very useful, though, and that's a 199 | tuple struct with only one element. We call this the *newtype* pattern, because 200 | it allows you to create a new type, distinct from that of its contained value 201 | and expressing its own semantic meaning: 202 | 203 | ```{rust} 204 | struct Inches(i32); 205 | 206 | let length = Inches(10); 207 | 208 | let Inches(integer_length) = length; 209 | println!("length is {} inches", integer_length); 210 | ``` 211 | 212 | As you can see here, you can extract the inner integer type through a 213 | destructuring `let`, as we discussed previously in 'tuples.' In this case, the 214 | `let Inches(integer_length)` assigns `10` to `integer_length`. 215 | 216 | ## Enums 217 | 218 | Finally, Rust has a "sum type", an *enum*. Enums are an incredibly useful 219 | feature of Rust, and are used throughout the standard library. An `enum` is 220 | a type which relates a set of alternates to a specific name. For example, below 221 | we define `Character` to be either a `Digit` or something else. These 222 | can be used via their fully scoped names: `Character::Other` (more about `::` 223 | below). 224 | 225 | ```rust 226 | enum Character { 227 | Digit(i32), 228 | Other, 229 | } 230 | ``` 231 | 232 | Most normal types are allowed as the variant components of an `enum`. Here are 233 | some examples: 234 | 235 | ```rust 236 | struct Empty; 237 | struct Color(i32, i32, i32); 238 | struct Length(i32); 239 | struct Status { Health: i32, Mana: i32, Attack: i32, Defense: i32 } 240 | struct HeightDatabase(Vec); 241 | ``` 242 | 243 | You see that, depending on its type, an `enum` variant may or may not hold data. 244 | In `Character`, for instance, `Digit` gives a meaningful name for an `i32` 245 | value, where `Other` is only a name. However, the fact that they represent 246 | distinct categories of `Character` is a very useful property. 247 | 248 | As with structures, the variants of an enum by default are not comparable with 249 | equality operators (`==`, `!=`), have no ordering (`<`, `>=`, etc.), and do not 250 | support other binary operations such as `*` and `+`. As such, the following code 251 | is invalid for the example `Character` type: 252 | 253 | ```{rust,ignore} 254 | // These assignments both succeed 255 | let ten = Character::Digit(10); 256 | let four = Character::Digit(4); 257 | 258 | // Error: `*` is not implemented for type `Character` 259 | let forty = ten * four; 260 | 261 | // Error: `<=` is not implemented for type `Character` 262 | let four_is_smaller = four <= ten; 263 | 264 | // Error: `==` is not implemented for type `Character` 265 | let four_equals_ten = four == ten; 266 | ``` 267 | 268 | This may seem rather limiting, but it's a limitation which we can overcome. 269 | There are two ways: by implementing equality ourselves, or by pattern matching 270 | variants with [`match`][match] expressions, which you'll learn in the next 271 | chapter. We don't know enough about Rust to implement equality yet, but we can 272 | use the `Ordering` enum from the standard library, which does: 273 | 274 | ``` 275 | enum Ordering { 276 | Less, 277 | Equal, 278 | Greater, 279 | } 280 | ``` 281 | 282 | Because `Ordering` has already been defined for us, we will import it with the 283 | `use` keyword. Here's an example of how it is used: 284 | 285 | ```{rust} 286 | use std::cmp::Ordering; 287 | 288 | fn cmp(a: i32, b: i32) -> Ordering { 289 | if a < b { Ordering::Less } 290 | else if a > b { Ordering::Greater } 291 | else { Ordering::Equal } 292 | } 293 | 294 | fn main() { 295 | let x = 5; 296 | let y = 10; 297 | 298 | let ordering = cmp(x, y); // ordering: Ordering 299 | 300 | if ordering == Ordering::Less { 301 | println!("less"); 302 | } else if ordering == Ordering::Greater { 303 | println!("greater"); 304 | } else if ordering == Ordering::Equal { 305 | println!("equal"); 306 | } 307 | } 308 | ``` 309 | 310 | The `::` symbol is used to indicate a namespace. In this case, `Ordering` lives 311 | in the `cmp` submodule of the `std` module. We'll talk more about modules later 312 | in the guide. For now, all you need to know is that you can `use` things from 313 | the standard library if you need them. 314 | 315 | Okay, let's talk about the actual code in the example. `cmp` is a function that 316 | compares two things, and returns an `Ordering`. We return either 317 | `Ordering::Less`, `Ordering::Greater`, or `Ordering::Equal`, depending on 318 | whether the first value is less than, greater than, or equal to the second. Note 319 | that each variant of the `enum` is namespaced under the `enum` itself: it's 320 | `Ordering::Greater`, not `Greater`. 321 | 322 | The `ordering` variable has the type `Ordering`, and so contains one of the 323 | three values. We then do a bunch of `if`/`else` comparisons to check which 324 | one it is. 325 | 326 | This `Ordering::Greater` notation is too long. Let's use another form of `use` 327 | to import the `enum` variants instead. This will avoid full scoping: 328 | 329 | ```{rust} 330 | use std::cmp::Ordering::{self, Equal, Less, Greater}; 331 | 332 | fn cmp(a: i32, b: i32) -> Ordering { 333 | if a < b { Less } 334 | else if a > b { Greater } 335 | else { Equal } 336 | } 337 | 338 | fn main() { 339 | let x = 5; 340 | let y = 10; 341 | 342 | let ordering = cmp(x, y); // ordering: Ordering 343 | 344 | if ordering == Less { println!("less"); } 345 | else if ordering == Greater { println!("greater"); } 346 | else if ordering == Equal { println!("equal"); } 347 | } 348 | ``` 349 | 350 | Importing variants is convenient and compact, but can also cause name conflicts, 351 | so do this with caution. For this reason, it's normally considered better style 352 | to `use` an enum rather than its variants directly. 353 | 354 | As you can see, `enum`s are quite a powerful tool for data representation, and 355 | are even more useful when they're [generic][generics] across types. Before we 356 | get to generics, though, let's talk about how to use enums with pattern 357 | matching, a tool that will let us deconstruct sum types (the type theory term 358 | for enums) like `Ordering` in a very elegant way that avoids all these messy 359 | and brittle `if`/`else`s. 360 | 361 | 362 | [arity]: ./glossary.html#arity 363 | [match]: ./match.html 364 | [game]: ./guessing-game.html#comparing-guesses 365 | [generics]: ./generics.html 366 | -------------------------------------------------------------------------------- /concurrency.md: -------------------------------------------------------------------------------- 1 | % Concurrency 2 | 3 | Concurrency and parallelism are incredibly important topics in computer 4 | science, and are also a hot topic in industry today. Computers are gaining more 5 | and more cores, yet many programmers aren't prepared to fully utilize them. 6 | 7 | Rust's memory safety features also apply to its concurrency story too. Even 8 | concurrent Rust programs must be memory safe, having no data races. Rust's type 9 | system is up to the task, and gives you powerful ways to reason about 10 | concurrent code at compile time. 11 | 12 | Before we talk about the concurrency features that come with Rust, it's important 13 | to understand something: Rust is low-level enough that all of this is provided 14 | by the standard library, not by the language. This means that if you don't like 15 | some aspect of the way Rust handles concurrency, you can implement an alternative 16 | way of doing things. [mio](https://github.com/carllerche/mio) is a real-world 17 | example of this principle in action. 18 | 19 | ## Background: `Send` and `Sync` 20 | 21 | Concurrency is difficult to reason about. In Rust, we have a strong, static 22 | type system to help us reason about our code. As such, Rust gives us two traits 23 | to help us make sense of code that can possibly be concurrent. 24 | 25 | ### `Send` 26 | 27 | The first trait we're going to talk about is 28 | [`Send`](../std/marker/trait.Send.html). When a type `T` implements `Send`, it indicates 29 | to the compiler that something of this type is able to have ownership transferred 30 | safely between threads. 31 | 32 | This is important to enforce certain restrictions. For example, if we have a 33 | channel connecting two threads, we would want to be able to send some data 34 | down the channel and to the other thread. Therefore, we'd ensure that `Send` was 35 | implemented for that type. 36 | 37 | In the opposite way, if we were wrapping a library with FFI that isn't 38 | threadsafe, we wouldn't want to implement `Send`, and so the compiler will help 39 | us enforce that it can't leave the current thread. 40 | 41 | ### `Sync` 42 | 43 | The second of these traits is called [`Sync`](../std/marker/trait.Sync.html). 44 | When a type `T` implements `Sync`, it indicates to the compiler that something 45 | of this type has no possibility of introducing memory unsafety when used from 46 | multiple threads concurrently. 47 | 48 | For example, sharing immutable data with an atomic reference count is 49 | threadsafe. Rust provides a type like this, `Arc`, and it implements `Sync`, 50 | so it is safe to share between threads. 51 | 52 | These two traits allow you to use the type system to make strong guarantees 53 | about the properties of your code under concurrency. Before we demonstrate 54 | why, we need to learn how to create a concurrent Rust program in the first 55 | place! 56 | 57 | ## Threads 58 | 59 | Rust's standard library provides a library for 'threads', which allow you to 60 | run Rust code in parallel. Here's a basic example of using `std::thread`: 61 | 62 | ``` 63 | use std::thread; 64 | 65 | fn main() { 66 | thread::scoped(|| { 67 | println!("Hello from a thread!"); 68 | }); 69 | } 70 | ``` 71 | 72 | The `thread::scoped()` method accepts a closure, which is executed in a new 73 | thread. It's called `scoped` because this thread returns a join guard: 74 | 75 | ``` 76 | use std::thread; 77 | 78 | fn main() { 79 | let guard = thread::scoped(|| { 80 | println!("Hello from a thread!"); 81 | }); 82 | 83 | // guard goes out of scope here 84 | } 85 | ``` 86 | 87 | When `guard` goes out of scope, it will block execution until the thread is 88 | finished. If we didn't want this behaviour, we could use `thread::spawn()`: 89 | 90 | ``` 91 | # #![feature(old_io, std_misc)] 92 | use std::thread; 93 | use std::old_io::timer; 94 | use std::time::Duration; 95 | 96 | fn main() { 97 | thread::spawn(|| { 98 | println!("Hello from a thread!"); 99 | }); 100 | 101 | timer::sleep(Duration::milliseconds(50)); 102 | } 103 | ``` 104 | 105 | We need to `sleep` here because when `main()` ends, it kills all of the 106 | running threads. 107 | 108 | [`scoped`](std/thread/struct.Builder.html#method.scoped) has an interesting 109 | type signature: 110 | 111 | ```text 112 | fn scoped<'a, T, F>(self, f: F) -> JoinGuard<'a, T> 113 | where T: Send + 'a, 114 | F: FnOnce() -> T, 115 | F: Send + 'a 116 | ``` 117 | 118 | Specifically, `F`, the closure that we pass to execute in the new thread. It 119 | has two restrictions: It must be a `FnOnce` from `()` to `T`. Using `FnOnce` 120 | allows the closure to take ownership of any data it mentions from the parent 121 | thread. The other restriction is that `F` must be `Send`. We aren't allowed to 122 | transfer this ownership unless the type thinks that's okay. 123 | 124 | Many languages have the ability to execute threads, but it's wildly unsafe. 125 | There are entire books about how to prevent errors that occur from shared 126 | mutable state. Rust helps out with its type system here as well, by preventing 127 | data races at compile time. Let's talk about how you actually share things 128 | between threads. 129 | 130 | ## Safe Shared Mutable State 131 | 132 | Due to Rust's type system, we have a concept that sounds like a lie: "safe 133 | shared mutable state." Many programmers agree that shared mutable state is 134 | very, very bad. 135 | 136 | Someone once said this: 137 | 138 | > Shared mutable state is the root of all evil. Most languages attempt to deal 139 | > with this problem through the 'mutable' part, but Rust deals with it by 140 | > solving the 'shared' part. 141 | 142 | The same [ownership system](ownership.html) that helps prevent using pointers 143 | incorrectly also helps rule out data races, one of the worst kinds of 144 | concurrency bugs. 145 | 146 | As an example, here is a Rust program that would have a data race in many 147 | languages. It will not compile: 148 | 149 | ```ignore 150 | # #![feature(old_io, std_misc)] 151 | use std::thread; 152 | use std::old_io::timer; 153 | use std::time::Duration; 154 | 155 | fn main() { 156 | let mut data = vec![1u32, 2, 3]; 157 | 158 | for i in 0..2 { 159 | thread::spawn(move || { 160 | data[i] += 1; 161 | }); 162 | } 163 | 164 | timer::sleep(Duration::milliseconds(50)); 165 | } 166 | ``` 167 | 168 | This gives us an error: 169 | 170 | ```text 171 | 12:17 error: capture of moved value: `data` 172 | data[i] += 1; 173 | ^~~~ 174 | ``` 175 | 176 | In this case, we know that our code _should_ be safe, but Rust isn't sure. And 177 | it's actually not safe: if we had a reference to `data` in each thread, and the 178 | thread takes ownership of the reference, we have three owners! That's bad. We 179 | can fix this by using the `Arc` type, which is an atomic reference counted 180 | pointer. The 'atomic' part means that it's safe to share across threads. 181 | 182 | `Arc` assumes one more property about its contents to ensure that it is safe 183 | to share across threads: it assumes its contents are `Sync`. But in our 184 | case, we want to be able to mutate the value. We need a type that can ensure 185 | only one person at a time can mutate what's inside. For that, we can use the 186 | `Mutex` type. Here's the second version of our code. It still doesn't work, 187 | but for a different reason: 188 | 189 | ```ignore 190 | # #![feature(old_io, std_misc)] 191 | use std::thread; 192 | use std::old_io::timer; 193 | use std::time::Duration; 194 | use std::sync::Mutex; 195 | 196 | fn main() { 197 | let mut data = Mutex::new(vec![1u32, 2, 3]); 198 | 199 | for i in 0..2 { 200 | let data = data.lock().unwrap(); 201 | thread::spawn(move || { 202 | data[i] += 1; 203 | }); 204 | } 205 | 206 | timer::sleep(Duration::milliseconds(50)); 207 | } 208 | ``` 209 | 210 | Here's the error: 211 | 212 | ```text 213 | :11:9: 11:22 error: the trait `core::marker::Send` is not implemented for the type `std::sync::mutex::MutexGuard<'_, collections::vec::Vec>` [E0277] 214 | :11 thread::spawn(move || { 215 | ^~~~~~~~~~~~~ 216 | :11:9: 11:22 note: `std::sync::mutex::MutexGuard<'_, collections::vec::Vec>` cannot be sent between threads safely 217 | :11 thread::spawn(move || { 218 | ^~~~~~~~~~~~~ 219 | ``` 220 | 221 | You see, [`Mutex`](std/sync/struct.Mutex.html) has a 222 | [`lock`](http://doc.rust-lang.org/nightly/std/sync/struct.Mutex.html#method.lock) 223 | method which has this signature: 224 | 225 | ```ignore 226 | fn lock(&self) -> LockResult> 227 | ``` 228 | 229 | Because `Send` is not implemented for `MutexGuard`, we can't transfer the 230 | guard across thread boundaries, which gives us our error. 231 | 232 | We can use `Arc` to fix this. Here's the working version: 233 | 234 | ``` 235 | # #![feature(old_io, std_misc)] 236 | use std::sync::{Arc, Mutex}; 237 | use std::thread; 238 | use std::old_io::timer; 239 | use std::time::Duration; 240 | 241 | fn main() { 242 | let data = Arc::new(Mutex::new(vec![1u32, 2, 3])); 243 | 244 | for i in 0..2 { 245 | let data = data.clone(); 246 | thread::spawn(move || { 247 | let mut data = data.lock().unwrap(); 248 | data[i] += 1; 249 | }); 250 | } 251 | 252 | timer::sleep(Duration::milliseconds(50)); 253 | } 254 | ``` 255 | 256 | We now call `clone()` on our `Arc`, which increases the internal count. This 257 | handle is then moved into the new thread. Let's examine the body of the 258 | thread more closely: 259 | 260 | ``` 261 | # #![feature(old_io, std_misc)] 262 | # use std::sync::{Arc, Mutex}; 263 | # use std::thread; 264 | # use std::old_io::timer; 265 | # use std::time::Duration; 266 | # fn main() { 267 | # let data = Arc::new(Mutex::new(vec![1u32, 2, 3])); 268 | # for i in 0..2 { 269 | # let data = data.clone(); 270 | thread::spawn(move || { 271 | let mut data = data.lock().unwrap(); 272 | data[i] += 1; 273 | }); 274 | # } 275 | # } 276 | ``` 277 | 278 | First, we call `lock()`, which acquires the mutex's lock. Because this may fail, 279 | it returns an `Result`, and because this is just an example, we `unwrap()` 280 | it to get a reference to the data. Real code would have more robust error handling 281 | here. We're then free to mutate it, since we have the lock. 282 | 283 | This timer bit is a bit awkward, however. We have picked a reasonable amount of 284 | time to wait, but it's entirely possible that we've picked too high, and that 285 | we could be taking less time. It's also possible that we've picked too low, 286 | and that we aren't actually finishing this computation. 287 | 288 | Rust's standard library provides a few more mechanisms for two threads to 289 | synchronize with each other. Let's talk about one: channels. 290 | 291 | ## Channels 292 | 293 | Here's a version of our code that uses channels for synchronization, rather 294 | than waiting for a specific time: 295 | 296 | ``` 297 | use std::sync::{Arc, Mutex}; 298 | use std::thread; 299 | use std::sync::mpsc; 300 | 301 | fn main() { 302 | let data = Arc::new(Mutex::new(0u32)); 303 | 304 | let (tx, rx) = mpsc::channel(); 305 | 306 | for _ in 0..10 { 307 | let (data, tx) = (data.clone(), tx.clone()); 308 | 309 | thread::spawn(move || { 310 | let mut data = data.lock().unwrap(); 311 | *data += 1; 312 | 313 | tx.send(()); 314 | }); 315 | } 316 | 317 | for _ in 0..10 { 318 | rx.recv(); 319 | } 320 | } 321 | ``` 322 | 323 | We use the `mpsc::channel()` method to construct a new channel. We just `send` 324 | a simple `()` down the channel, and then wait for ten of them to come back. 325 | 326 | While this channel is just sending a generic signal, we can send any data that 327 | is `Send` over the channel! 328 | 329 | ``` 330 | use std::thread; 331 | use std::sync::mpsc; 332 | 333 | fn main() { 334 | let (tx, rx) = mpsc::channel(); 335 | 336 | for _ in 0..10 { 337 | let tx = tx.clone(); 338 | 339 | thread::spawn(move || { 340 | let answer = 42u32; 341 | 342 | tx.send(answer); 343 | }); 344 | } 345 | 346 | rx.recv().ok().expect("Could not receive answer"); 347 | } 348 | ``` 349 | 350 | A `u32` is `Send` because we can make a copy. So we create a thread, ask it to calculate 351 | the answer, and then it `send()`s us the answer over the channel. 352 | 353 | 354 | ## Panics 355 | 356 | A `panic!` will crash the currently executing thread. You can use Rust's 357 | threads as a simple isolation mechanism: 358 | 359 | ``` 360 | use std::thread; 361 | 362 | let result = thread::spawn(move || { 363 | panic!("oops!"); 364 | }).join(); 365 | 366 | assert!(result.is_err()); 367 | ``` 368 | 369 | Our `Thread` gives us a `Result` back, which allows us to check if the thread 370 | has panicked or not. 371 | -------------------------------------------------------------------------------- /traits.md: -------------------------------------------------------------------------------- 1 | % Traits 2 | 3 | Do you remember the `impl` keyword, used to call a function with method 4 | syntax? 5 | 6 | ```{rust} 7 | # #![feature(core)] 8 | struct Circle { 9 | x: f64, 10 | y: f64, 11 | radius: f64, 12 | } 13 | 14 | impl Circle { 15 | fn area(&self) -> f64 { 16 | std::f64::consts::PI * (self.radius * self.radius) 17 | } 18 | } 19 | ``` 20 | 21 | Traits are similar, except that we define a trait with just the method 22 | signature, then implement the trait for that struct. Like this: 23 | 24 | ```{rust} 25 | # #![feature(core)] 26 | struct Circle { 27 | x: f64, 28 | y: f64, 29 | radius: f64, 30 | } 31 | 32 | trait HasArea { 33 | fn area(&self) -> f64; 34 | } 35 | 36 | impl HasArea for Circle { 37 | fn area(&self) -> f64 { 38 | std::f64::consts::PI * (self.radius * self.radius) 39 | } 40 | } 41 | ``` 42 | 43 | As you can see, the `trait` block looks very similar to the `impl` block, 44 | but we don't define a body, just a type signature. When we `impl` a trait, 45 | we use `impl Trait for Item`, rather than just `impl Item`. 46 | 47 | So what's the big deal? Remember the error we were getting with our generic 48 | `inverse` function? 49 | 50 | ```text 51 | error: binary operation `==` cannot be applied to type `T` 52 | ``` 53 | 54 | We can use traits to constrain our generics. Consider this function, which 55 | does not compile, and gives us a similar error: 56 | 57 | ```{rust,ignore} 58 | fn print_area(shape: T) { 59 | println!("This shape has an area of {}", shape.area()); 60 | } 61 | ``` 62 | 63 | Rust complains: 64 | 65 | ```text 66 | error: type `T` does not implement any method in scope named `area` 67 | ``` 68 | 69 | Because `T` can be any type, we can't be sure that it implements the `area` 70 | method. But we can add a *trait constraint* to our generic `T`, ensuring 71 | that it does: 72 | 73 | ```{rust} 74 | # trait HasArea { 75 | # fn area(&self) -> f64; 76 | # } 77 | fn print_area(shape: T) { 78 | println!("This shape has an area of {}", shape.area()); 79 | } 80 | ``` 81 | 82 | The syntax `` means `any type that implements the HasArea trait`. 83 | Because traits define function type signatures, we can be sure that any type 84 | which implements `HasArea` will have an `.area()` method. 85 | 86 | Here's an extended example of how this works: 87 | 88 | ```{rust} 89 | # #![feature(core)] 90 | trait HasArea { 91 | fn area(&self) -> f64; 92 | } 93 | 94 | struct Circle { 95 | x: f64, 96 | y: f64, 97 | radius: f64, 98 | } 99 | 100 | impl HasArea for Circle { 101 | fn area(&self) -> f64 { 102 | std::f64::consts::PI * (self.radius * self.radius) 103 | } 104 | } 105 | 106 | struct Square { 107 | x: f64, 108 | y: f64, 109 | side: f64, 110 | } 111 | 112 | impl HasArea for Square { 113 | fn area(&self) -> f64 { 114 | self.side * self.side 115 | } 116 | } 117 | 118 | fn print_area(shape: T) { 119 | println!("This shape has an area of {}", shape.area()); 120 | } 121 | 122 | fn main() { 123 | let c = Circle { 124 | x: 0.0f64, 125 | y: 0.0f64, 126 | radius: 1.0f64, 127 | }; 128 | 129 | let s = Square { 130 | x: 0.0f64, 131 | y: 0.0f64, 132 | side: 1.0f64, 133 | }; 134 | 135 | print_area(c); 136 | print_area(s); 137 | } 138 | ``` 139 | 140 | This program outputs: 141 | 142 | ```text 143 | This shape has an area of 3.141593 144 | This shape has an area of 1 145 | ``` 146 | 147 | As you can see, `print_area` is now generic, but also ensures that we 148 | have passed in the correct types. If we pass in an incorrect type: 149 | 150 | ```{rust,ignore} 151 | print_area(5); 152 | ``` 153 | 154 | We get a compile-time error: 155 | 156 | ```text 157 | error: failed to find an implementation of trait main::HasArea for int 158 | ``` 159 | 160 | So far, we've only added trait implementations to structs, but you can 161 | implement a trait for any type. So technically, we _could_ implement 162 | `HasArea` for `i32`: 163 | 164 | ```{rust} 165 | trait HasArea { 166 | fn area(&self) -> f64; 167 | } 168 | 169 | impl HasArea for i32 { 170 | fn area(&self) -> f64 { 171 | println!("this is silly"); 172 | 173 | *self as f64 174 | } 175 | } 176 | 177 | 5.area(); 178 | ``` 179 | 180 | It is considered poor style to implement methods on such primitive types, even 181 | though it is possible. 182 | 183 | This may seem like the Wild West, but there are two other restrictions around 184 | implementing traits that prevent this from getting out of hand. First, traits 185 | must be `use`d in any scope where you wish to use the trait's method. So for 186 | example, this does not work: 187 | 188 | ```{rust,ignore} 189 | mod shapes { 190 | use std::f64::consts; 191 | 192 | trait HasArea { 193 | fn area(&self) -> f64; 194 | } 195 | 196 | struct Circle { 197 | x: f64, 198 | y: f64, 199 | radius: f64, 200 | } 201 | 202 | impl HasArea for Circle { 203 | fn area(&self) -> f64 { 204 | consts::PI * (self.radius * self.radius) 205 | } 206 | } 207 | } 208 | 209 | fn main() { 210 | let c = shapes::Circle { 211 | x: 0.0f64, 212 | y: 0.0f64, 213 | radius: 1.0f64, 214 | }; 215 | 216 | println!("{}", c.area()); 217 | } 218 | ``` 219 | 220 | Now that we've moved the structs and traits into their own module, we get an 221 | error: 222 | 223 | ```text 224 | error: type `shapes::Circle` does not implement any method in scope named `area` 225 | ``` 226 | 227 | If we add a `use` line right above `main` and make the right things public, 228 | everything is fine: 229 | 230 | ```{rust} 231 | # #![feature(core)] 232 | use shapes::HasArea; 233 | 234 | mod shapes { 235 | use std::f64::consts; 236 | 237 | pub trait HasArea { 238 | fn area(&self) -> f64; 239 | } 240 | 241 | pub struct Circle { 242 | pub x: f64, 243 | pub y: f64, 244 | pub radius: f64, 245 | } 246 | 247 | impl HasArea for Circle { 248 | fn area(&self) -> f64 { 249 | consts::PI * (self.radius * self.radius) 250 | } 251 | } 252 | } 253 | 254 | 255 | fn main() { 256 | let c = shapes::Circle { 257 | x: 0.0f64, 258 | y: 0.0f64, 259 | radius: 1.0f64, 260 | }; 261 | 262 | println!("{}", c.area()); 263 | } 264 | ``` 265 | 266 | This means that even if someone does something bad like add methods to `int`, 267 | it won't affect you, unless you `use` that trait. 268 | 269 | There's one more restriction on implementing traits. Either the trait or the 270 | type you're writing the `impl` for must be inside your crate. So, we could 271 | implement the `HasArea` type for `i32`, because `HasArea` is in our crate. But 272 | if we tried to implement `Float`, a trait provided by Rust, for `i32`, we could 273 | not, because both the trait and the type aren't in our crate. 274 | 275 | One last thing about traits: generic functions with a trait bound use 276 | *monomorphization* (*mono*: one, *morph*: form), so they are statically 277 | dispatched. What's that mean? Check out the chapter on [static and dynamic 278 | dispatch](static-and-dynamic-dispatch.html) for more. 279 | 280 | ## Where clause 281 | 282 | Writing functions with only a few generic types and a small number of trait 283 | bounds isn't too bad, but as the number increases, the syntax gets increasingly 284 | awkward: 285 | 286 | ``` 287 | use std::fmt::Debug; 288 | 289 | fn foo(x: T, y: K) { 290 | x.clone(); 291 | y.clone(); 292 | println!("{:?}", y); 293 | } 294 | ``` 295 | 296 | The name of the function is on the far left, and the parameter list is on the 297 | far right. The bounds are getting in the way. 298 | 299 | Rust has a solution, and it's called a '`where` clause': 300 | 301 | ``` 302 | use std::fmt::Debug; 303 | 304 | fn foo(x: T, y: K) { 305 | x.clone(); 306 | y.clone(); 307 | println!("{:?}", y); 308 | } 309 | 310 | fn bar(x: T, y: K) where T: Clone, K: Clone + Debug { 311 | x.clone(); 312 | y.clone(); 313 | println!("{:?}", y); 314 | } 315 | 316 | fn main() { 317 | foo("Hello", "world"); 318 | bar("Hello", "workd"); 319 | } 320 | ``` 321 | 322 | `foo()` uses the syntax we showed earlier, and `bar()` uses a `where` clause. 323 | All you need to do is leave off the bounds when defining your type parameters, 324 | and then add `where` after the parameter list. For longer lists, whitespace can 325 | be added: 326 | 327 | ``` 328 | use std::fmt::Debug; 329 | 330 | fn bar(x: T, y: K) 331 | where T: Clone, 332 | K: Clone + Debug { 333 | 334 | x.clone(); 335 | y.clone(); 336 | println!("{:?}", y); 337 | } 338 | ``` 339 | 340 | This flexibility can add clarity in complex situations. 341 | 342 | `where` is also more powerful than the simpler syntax. For example: 343 | 344 | ``` 345 | trait ConvertTo { 346 | fn convert(&self) -> Output; 347 | } 348 | 349 | impl ConvertTo for i32 { 350 | fn convert(&self) -> i64 { *self as i64 } 351 | } 352 | 353 | // can be called with T == i32 354 | fn normal>(x: &T) -> i64 { 355 | x.convert() 356 | } 357 | 358 | // can be called with T == i64 359 | fn inverse() -> T 360 | // this is using ConvertTo as if it were "ConvertFrom" 361 | where i32: ConvertTo { 362 | 1i32.convert() 363 | } 364 | ``` 365 | 366 | This shows off the additional feature of `where` clauses: they allow bounds 367 | where the left-hand side is an arbitrary type (`i32` in this case), not just a 368 | plain type parameter (like `T`). 369 | 370 | ## Our `inverse` Example 371 | 372 | Back in [Generics](generics.html), we were trying to write code like this: 373 | 374 | ```{rust,ignore} 375 | fn inverse(x: T) -> Result { 376 | if x == 0.0 { return Err("x cannot be zero!".to_string()); } 377 | 378 | Ok(1.0 / x) 379 | } 380 | ``` 381 | 382 | If we try to compile it, we get this error: 383 | 384 | ```text 385 | error: binary operation `==` cannot be applied to type `T` 386 | ``` 387 | 388 | This is because `T` is too generic: we don't know if a random `T` can be 389 | compared. For that, we can use trait bounds. It doesn't quite work, but try 390 | this: 391 | 392 | ```{rust,ignore} 393 | fn inverse(x: T) -> Result { 394 | if x == 0.0 { return Err("x cannot be zero!".to_string()); } 395 | 396 | Ok(1.0 / x) 397 | } 398 | ``` 399 | 400 | You should get this error: 401 | 402 | ```text 403 | error: mismatched types: 404 | expected `T`, 405 | found `_` 406 | (expected type parameter, 407 | found floating-point variable) 408 | ``` 409 | 410 | So this won't work. While our `T` is `PartialEq`, we expected to have another `T`, 411 | but instead, we found a floating-point variable. We need a different bound. `Float` 412 | to the rescue: 413 | 414 | ``` 415 | # #![feature(std_misc)] 416 | use std::num::Float; 417 | 418 | fn inverse(x: T) -> Result { 419 | if x == Float::zero() { return Err("x cannot be zero!".to_string()) } 420 | 421 | let one: T = Float::one(); 422 | Ok(one / x) 423 | } 424 | ``` 425 | 426 | We've had to replace our generic `0.0` and `1.0` with the appropriate methods 427 | from the `Float` trait. Both `f32` and `f64` implement `Float`, so our function 428 | works just fine: 429 | 430 | ``` 431 | # #![feature(std_misc)] 432 | # use std::num::Float; 433 | # fn inverse(x: T) -> Result { 434 | # if x == Float::zero() { return Err("x cannot be zero!".to_string()) } 435 | # let one: T = Float::one(); 436 | # Ok(one / x) 437 | # } 438 | println!("the inverse of {} is {:?}", 2.0f32, inverse(2.0f32)); 439 | println!("the inverse of {} is {:?}", 2.0f64, inverse(2.0f64)); 440 | 441 | println!("the inverse of {} is {:?}", 0.0f32, inverse(0.0f32)); 442 | println!("the inverse of {} is {:?}", 0.0f64, inverse(0.0f64)); 443 | ``` 444 | 445 | ## Default methods 446 | 447 | There's one last feature of traits we should cover: default methods. It's 448 | easiest just to show an example: 449 | 450 | ```rust 451 | trait Foo { 452 | fn bar(&self); 453 | 454 | fn baz(&self) { println!("We called baz."); } 455 | } 456 | ``` 457 | 458 | Implementors of the `Foo` trait need to implement `bar()`, but they don't 459 | need to implement `baz()`. They'll get this default behavior. They can 460 | override the default if they so choose: 461 | 462 | ```rust 463 | # trait Foo { 464 | # fn bar(&self); 465 | # fn baz(&self) { println!("We called baz."); } 466 | # } 467 | struct UseDefault; 468 | 469 | impl Foo for UseDefault { 470 | fn bar(&self) { println!("We called bar."); } 471 | } 472 | 473 | struct OverrideDefault; 474 | 475 | impl Foo for OverrideDefault { 476 | fn bar(&self) { println!("We called bar."); } 477 | 478 | fn baz(&self) { println!("Override baz!"); } 479 | } 480 | 481 | let default = UseDefault; 482 | default.baz(); // prints "We called bar." 483 | 484 | let over = OverrideDefault; 485 | over.baz(); // prints "Override baz!" 486 | ``` 487 | -------------------------------------------------------------------------------- /iterators.md: -------------------------------------------------------------------------------- 1 | % Iterators 2 | 3 | Let's talk about loops. 4 | 5 | Remember Rust's `for` loop? Here's an example: 6 | 7 | ```rust 8 | for x in 0..10 { 9 | println!("{}", x); 10 | } 11 | ``` 12 | 13 | Now that you know more Rust, we can talk in detail about how this works. 14 | Ranges (the `0..10`) are 'iterators'. An iterator is something that we can 15 | call the `.next()` method on repeatedly, and it gives us a sequence of things. 16 | 17 | Like this: 18 | 19 | ```rust 20 | let mut range = 0..10; 21 | 22 | loop { 23 | match range.next() { 24 | Some(x) => { 25 | println!("{}", x); 26 | }, 27 | None => { break } 28 | } 29 | } 30 | ``` 31 | 32 | We make a mutable binding to the range, which is our iterator. We then `loop`, 33 | with an inner `match`. This `match` is used on the result of `range.next()`, 34 | which gives us a reference to the next value of the iterator. `next` returns an 35 | `Option`, in this case, which will be `Some(i32)` when we have a value and 36 | `None` once we run out. If we get `Some(i32)`, we print it out, and if we get 37 | `None`, we `break` out of the loop. 38 | 39 | This code sample is basically the same as our `for` loop version. The `for` 40 | loop is just a handy way to write this `loop`/`match`/`break` construct. 41 | 42 | `for` loops aren't the only thing that uses iterators, however. Writing your 43 | own iterator involves implementing the `Iterator` trait. While doing that is 44 | outside of the scope of this guide, Rust provides a number of useful iterators 45 | to accomplish various tasks. Before we talk about those, we should talk about a 46 | Rust anti-pattern. And that's using ranges like this. 47 | 48 | Yes, we just talked about how ranges are cool. But ranges are also very 49 | primitive. For example, if you needed to iterate over the contents of a vector, 50 | you may be tempted to write this: 51 | 52 | ```rust 53 | let nums = vec![1, 2, 3]; 54 | 55 | for i in 0..nums.len() { 56 | println!("{}", nums[i]); 57 | } 58 | ``` 59 | 60 | This is strictly worse than using an actual iterator. You can iterate over vectors 61 | directly, so write this: 62 | 63 | ```rust 64 | let nums = vec![1, 2, 3]; 65 | 66 | for num in &nums { 67 | println!("{}", num); 68 | } 69 | ``` 70 | 71 | There are two reasons for this. First, this more directly expresses what we 72 | mean. We iterate through the entire vector, rather than iterating through 73 | indexes, and then indexing the vector. Second, this version is more efficient: 74 | the first version will have extra bounds checking because it used indexing, 75 | `nums[i]`. But since we yield a reference to each element of the vector in turn 76 | with the iterator, there's no bounds checking in the second example. This is 77 | very common with iterators: we can ignore unnecessary bounds checks, but still 78 | know that we're safe. 79 | 80 | There's another detail here that's not 100% clear because of how `println!` 81 | works. `num` is actually of type `&i32`. That is, it's a reference to an `i32`, 82 | not an `i32` itself. `println!` handles the dereferencing for us, so we don't 83 | see it. This code works fine too: 84 | 85 | ```rust 86 | let nums = vec![1, 2, 3]; 87 | 88 | for num in &nums { 89 | println!("{}", *num); 90 | } 91 | ``` 92 | 93 | Now we're explicitly dereferencing `num`. Why does `&nums` give us 94 | references? Firstly, because we explicitly asked it to with 95 | `&`. Secondly, if it gave us the data itself, we would have to be its 96 | owner, which would involve making a copy of the data and giving us the 97 | copy. With references, we're just borrowing a reference to the data, 98 | and so it's just passing a reference, without needing to do the move. 99 | 100 | So, now that we've established that ranges are often not what you want, let's 101 | talk about what you do want instead. 102 | 103 | There are three broad classes of things that are relevant here: iterators, 104 | *iterator adapters*, and *consumers*. Here's some definitions: 105 | 106 | * *iterators* give you a sequence of values. 107 | * *iterator adapters* operate on an iterator, producing a new iterator with a 108 | different output sequence. 109 | * *consumers* operate on an iterator, producing some final set of values. 110 | 111 | Let's talk about consumers first, since you've already seen an iterator, ranges. 112 | 113 | ## Consumers 114 | 115 | A *consumer* operates on an iterator, returning some kind of value or values. 116 | The most common consumer is `collect()`. This code doesn't quite compile, 117 | but it shows the intention: 118 | 119 | ```{rust,ignore} 120 | let one_to_one_hundred = (1..101).collect(); 121 | ``` 122 | 123 | As you can see, we call `collect()` on our iterator. `collect()` takes 124 | as many values as the iterator will give it, and returns a collection 125 | of the results. So why won't this compile? Rust can't determine what 126 | type of things you want to collect, and so you need to let it know. 127 | Here's the version that does compile: 128 | 129 | ```rust 130 | let one_to_one_hundred = (1..101).collect::>(); 131 | ``` 132 | 133 | If you remember, the `::<>` syntax allows us to give a type hint, 134 | and so we tell it that we want a vector of integers. You don't always 135 | need to use the whole type, though. Using a `_` will let you provide 136 | a partial hint: 137 | 138 | ```rust 139 | let one_to_one_hundred = (1..101).collect::>(); 140 | ``` 141 | 142 | This says "Collect into a `Vec`, please, but infer what the `T` is for me." 143 | `_` is sometimes called a "type placeholder" for this reason. 144 | 145 | `collect()` is the most common consumer, but there are others too. `find()` 146 | is one: 147 | 148 | ```rust 149 | let greater_than_forty_two = (0..100) 150 | .find(|x| *x > 42); 151 | 152 | match greater_than_forty_two { 153 | Some(_) => println!("We got some numbers!"), 154 | None => println!("No numbers found :("), 155 | } 156 | ``` 157 | 158 | `find` takes a closure, and works on a reference to each element of an 159 | iterator. This closure returns `true` if the element is the element we're 160 | looking for, and `false` otherwise. Because we might not find a matching 161 | element, `find` returns an `Option` rather than the element itself. 162 | 163 | Another important consumer is `fold`. Here's what it looks like: 164 | 165 | ```rust 166 | let sum = (1..4).fold(0, |sum, x| sum + x); 167 | ``` 168 | 169 | `fold()` is a consumer that looks like this: 170 | `fold(base, |accumulator, element| ...)`. It takes two arguments: the first 171 | is an element called the *base*. The second is a closure that itself takes two 172 | arguments: the first is called the *accumulator*, and the second is an 173 | *element*. Upon each iteration, the closure is called, and the result is the 174 | value of the accumulator on the next iteration. On the first iteration, the 175 | base is the value of the accumulator. 176 | 177 | Okay, that's a bit confusing. Let's examine the values of all of these things 178 | in this iterator: 179 | 180 | | base | accumulator | element | closure result | 181 | |------|-------------|---------|----------------| 182 | | 0 | 0 | 1 | 1 | 183 | | 0 | 1 | 2 | 3 | 184 | | 0 | 3 | 3 | 6 | 185 | 186 | We called `fold()` with these arguments: 187 | 188 | ```rust 189 | # (1..4) 190 | .fold(0, |sum, x| sum + x); 191 | ``` 192 | 193 | So, `0` is our base, `sum` is our accumulator, and `x` is our element. On the 194 | first iteration, we set `sum` to `0`, and `x` is the first element of `nums`, 195 | `1`. We then add `sum` and `x`, which gives us `0 + 1 = 1`. On the second 196 | iteration, that value becomes our accumulator, `sum`, and the element is 197 | the second element of the array, `2`. `1 + 2 = 3`, and so that becomes 198 | the value of the accumulator for the last iteration. On that iteration, 199 | `x` is the last element, `3`, and `3 + 3 = 6`, which is our final 200 | result for our sum. `1 + 2 + 3 = 6`, and that's the result we got. 201 | 202 | Whew. `fold` can be a bit strange the first few times you see it, but once it 203 | clicks, you can use it all over the place. Any time you have a list of things, 204 | and you want a single result, `fold` is appropriate. 205 | 206 | Consumers are important due to one additional property of iterators we haven't 207 | talked about yet: laziness. Let's talk some more about iterators, and you'll 208 | see why consumers matter. 209 | 210 | ## Iterators 211 | 212 | As we've said before, an iterator is something that we can call the 213 | `.next()` method on repeatedly, and it gives us a sequence of things. 214 | Because you need to call the method, this means that iterators 215 | are *lazy* and don't need to generate all of the values upfront. 216 | This code, for example, does not actually generate the numbers 217 | `1-100`, and just creates a value that represents the sequence: 218 | 219 | ```rust 220 | let nums = 1..100; 221 | ``` 222 | 223 | Since we didn't do anything with the range, it didn't generate the sequence. 224 | Let's add the consumer: 225 | 226 | ```rust 227 | let nums = (1..100).collect::>(); 228 | ``` 229 | 230 | Now, `collect()` will require that the range gives it some numbers, and so 231 | it will do the work of generating the sequence. 232 | 233 | Ranges are one of two basic iterators that you'll see. The other is `iter()`. 234 | `iter()` can turn a vector into a simple iterator that gives you each element 235 | in turn: 236 | 237 | ```rust 238 | let nums = [1, 2, 3]; 239 | 240 | for num in nums.iter() { 241 | println!("{}", num); 242 | } 243 | ``` 244 | 245 | These two basic iterators should serve you well. There are some more 246 | advanced iterators, including ones that are infinite. Like `count`: 247 | 248 | ```rust 249 | # #![feature(core)] 250 | std::iter::count(1, 5); 251 | ``` 252 | 253 | This iterator counts up from one, adding five each time. It will give 254 | you a new integer every time, forever (well, technically, until it reaches the 255 | maximum number representable by an `i32`). But since iterators are lazy, 256 | that's okay! You probably don't want to use `collect()` on it, though... 257 | 258 | That's enough about iterators. Iterator adapters are the last concept 259 | we need to talk about with regards to iterators. Let's get to it! 260 | 261 | ## Iterator adapters 262 | 263 | *Iterator adapters* take an iterator and modify it somehow, producing 264 | a new iterator. The simplest one is called `map`: 265 | 266 | ```{rust,ignore} 267 | (1..100).map(|x| x + 1); 268 | ``` 269 | 270 | `map` is called upon another iterator, and produces a new iterator where each 271 | element reference has the closure it's been given as an argument called on it. 272 | So this would give us the numbers from `2-100`. Well, almost! If you 273 | compile the example, you'll get a warning: 274 | 275 | ```text 276 | warning: unused result which must be used: iterator adaptors are lazy and 277 | do nothing unless consumed, #[warn(unused_must_use)] on by default 278 | (1..100).map(|x| x + 1); 279 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 280 | ``` 281 | 282 | Laziness strikes again! That closure will never execute. This example 283 | doesn't print any numbers: 284 | 285 | ```{rust,ignore} 286 | (1..100).map(|x| println!("{}", x)); 287 | ``` 288 | 289 | If you are trying to execute a closure on an iterator for its side effects, 290 | just use `for` instead. 291 | 292 | There are tons of interesting iterator adapters. `take(n)` will return an 293 | iterator over the next `n` elements of the original iterator, note that this 294 | has no side effect on the original iterator. Let's try it out with our infinite 295 | iterator from before, `count()`: 296 | 297 | ```rust 298 | # #![feature(core)] 299 | for i in std::iter::count(1, 5).take(5) { 300 | println!("{}", i); 301 | } 302 | ``` 303 | 304 | This will print 305 | 306 | ```text 307 | 1 308 | 6 309 | 11 310 | 16 311 | 21 312 | ``` 313 | 314 | `filter()` is an adapter that takes a closure as an argument. This closure 315 | returns `true` or `false`. The new iterator `filter()` produces 316 | only the elements that that closure returns `true` for: 317 | 318 | ```rust 319 | for i in (1..100).filter(|&x| x % 2 == 0) { 320 | println!("{}", i); 321 | } 322 | ``` 323 | 324 | This will print all of the even numbers between one and a hundred. 325 | (Note that because `filter` doesn't consume the elements that are 326 | being iterated over, it is passed a reference to each element, and 327 | thus the filter predicate uses the `&x` pattern to extract the integer 328 | itself.) 329 | 330 | You can chain all three things together: start with an iterator, adapt it 331 | a few times, and then consume the result. Check it out: 332 | 333 | ```rust 334 | (1..1000) 335 | .filter(|&x| x % 2 == 0) 336 | .filter(|&x| x % 3 == 0) 337 | .take(5) 338 | .collect::>(); 339 | ``` 340 | 341 | This will give you a vector containing `6`, `12`, `18`, `24`, and `30`. 342 | 343 | This is just a small taste of what iterators, iterator adapters, and consumers 344 | can help you with. There are a number of really useful iterators, and you can 345 | write your own as well. Iterators provide a safe, efficient way to manipulate 346 | all kinds of lists. They're a little unusual at first, but if you play with 347 | them, you'll get hooked. For a full list of the different iterators and 348 | consumers, check out the [iterator module documentation](../std/iter/index.html). 349 | -------------------------------------------------------------------------------- /macros.md: -------------------------------------------------------------------------------- 1 | % Macros 2 | 3 | By now you've learned about many of the tools Rust provides for abstracting and 4 | reusing code. These units of code reuse have a rich semantic structure. For 5 | example, functions have a type signature, type parameters have trait bounds, 6 | and overloaded functions must belong to a particular trait. 7 | 8 | This structure means that Rust's core abstractions have powerful compile-time 9 | correctness checking. But this comes at the price of reduced flexibility. If 10 | you visually identify a pattern of repeated code, you may find it's difficult 11 | or cumbersome to express that pattern as a generic function, a trait, or 12 | anything else within Rust's semantics. 13 | 14 | Macros allow us to abstract at a *syntactic* level. A macro invocation is 15 | shorthand for an "expanded" syntactic form. This expansion happens early in 16 | compilation, before any static checking. As a result, macros can capture many 17 | patterns of code reuse that Rust's core abstractions cannot. 18 | 19 | The drawback is that macro-based code can be harder to understand, because 20 | fewer of the built-in rules apply. Like an ordinary function, a well-behaved 21 | macro can be used without understanding its implementation. However, it can be 22 | difficult to design a well-behaved macro! Additionally, compiler errors in 23 | macro code are harder to interpret, because they describe problems in the 24 | expanded code, not the source-level form that developers use. 25 | 26 | These drawbacks make macros something of a "feature of last resort". That's not 27 | to say that macros are bad; they are part of Rust because sometimes they're 28 | needed for truly concise, well-abstracted code. Just keep this tradeoff in 29 | mind. 30 | 31 | # Defining a macro 32 | 33 | You may have seen the `vec!` macro, used to initialize a [vector][] with any 34 | number of elements. 35 | 36 | [vector]: arrays-vectors-and-slices.html 37 | 38 | ```rust 39 | let x: Vec = vec![1, 2, 3]; 40 | # assert_eq!(&[1,2,3], &x); 41 | ``` 42 | 43 | This can't be an ordinary function, because it takes any number of arguments. 44 | But we can imagine it as syntactic shorthand for 45 | 46 | ```rust 47 | let x: Vec = { 48 | let mut temp_vec = Vec::new(); 49 | temp_vec.push(1); 50 | temp_vec.push(2); 51 | temp_vec.push(3); 52 | temp_vec 53 | }; 54 | # assert_eq!(&[1,2,3], &x); 55 | ``` 56 | 57 | We can implement this shorthand, using a macro: [^actual] 58 | 59 | [^actual]: The actual definition of `vec!` in libcollections differs from the 60 | one presented here, for reasons of efficiency and reusability. Some 61 | of these are mentioned in the [advanced macros chapter][]. 62 | 63 | ```rust 64 | macro_rules! vec { 65 | ( $( $x:expr ),* ) => { 66 | { 67 | let mut temp_vec = Vec::new(); 68 | $( 69 | temp_vec.push($x); 70 | )* 71 | temp_vec 72 | } 73 | }; 74 | } 75 | # fn main() { 76 | # assert_eq!([1,2,3], vec![1,2,3]); 77 | # } 78 | ``` 79 | 80 | Whoa, that's a lot of new syntax! Let's break it down. 81 | 82 | ```ignore 83 | macro_rules! vec { ... } 84 | ``` 85 | 86 | This says we're defining a macro named `vec`, much as `fn vec` would define a 87 | function named `vec`. In prose, we informally write a macro's name with an 88 | exclamation point, e.g. `vec!`. The exclamation point is part of the invocation 89 | syntax and serves to distinguish a macro from an ordinary function. 90 | 91 | ## Matching 92 | 93 | The macro is defined through a series of *rules*, which are pattern-matching 94 | cases. Above, we had 95 | 96 | ```ignore 97 | ( $( $x:expr ),* ) => { ... }; 98 | ``` 99 | 100 | This is like a `match` expression arm, but the matching happens on Rust syntax 101 | trees, at compile time. The semicolon is optional on the last (here, only) 102 | case. The "pattern" on the left-hand side of `=>` is known as a *matcher*. 103 | These have [their own little grammar] within the language. 104 | 105 | [their own little grammar]: ../reference.html#macros 106 | 107 | The matcher `$x:expr` will match any Rust expression, binding that syntax tree 108 | to the *metavariable* `$x`. The identifier `expr` is a *fragment specifier*; 109 | the full possibilities are enumerated in the [advanced macros chapter][]. 110 | Surrounding the matcher with `$(...),*` will match zero or more expressions, 111 | separated by commas. 112 | 113 | Aside from the special matcher syntax, any Rust tokens that appear in a matcher 114 | must match exactly. For example, 115 | 116 | ```rust 117 | macro_rules! foo { 118 | (x => $e:expr) => (println!("mode X: {}", $e)); 119 | (y => $e:expr) => (println!("mode Y: {}", $e)); 120 | } 121 | 122 | fn main() { 123 | foo!(y => 3); 124 | } 125 | ``` 126 | 127 | will print 128 | 129 | ```text 130 | mode Y: 3 131 | ``` 132 | 133 | With 134 | 135 | ```rust,ignore 136 | foo!(z => 3); 137 | ``` 138 | 139 | we get the compiler error 140 | 141 | ```text 142 | error: no rules expected the token `z` 143 | ``` 144 | 145 | ## Expansion 146 | 147 | The right-hand side of a macro rule is ordinary Rust syntax, for the most part. 148 | But we can splice in bits of syntax captured by the matcher. From the original 149 | example: 150 | 151 | ```ignore 152 | $( 153 | temp_vec.push($x); 154 | )* 155 | ``` 156 | 157 | Each matched expression `$x` will produce a single `push` statement in the 158 | macro expansion. The repetition in the expansion proceeds in "lockstep" with 159 | repetition in the matcher (more on this in a moment). 160 | 161 | Because `$x` was already declared as matching an expression, we don't repeat 162 | `:expr` on the right-hand side. Also, we don't include a separating comma as 163 | part of the repetition operator. Instead, we have a terminating semicolon 164 | within the repeated block. 165 | 166 | Another detail: the `vec!` macro has *two* pairs of braces on the right-hand 167 | side. They are often combined like so: 168 | 169 | ```ignore 170 | macro_rules! foo { 171 | () => {{ 172 | ... 173 | }} 174 | } 175 | ``` 176 | 177 | The outer braces are part of the syntax of `macro_rules!`. In fact, you can use 178 | `()` or `[]` instead. They simply delimit the right-hand side as a whole. 179 | 180 | The inner braces are part of the expanded syntax. Remember, the `vec!` macro is 181 | used in an expression context. To write an expression with multiple statements, 182 | including `let`-bindings, we use a block. If your macro expands to a single 183 | expression, you don't need this extra layer of braces. 184 | 185 | Note that we never *declared* that the macro produces an expression. In fact, 186 | this is not determined until we use the macro as an expression. With care, you 187 | can write a macro whose expansion works in several contexts. For example, 188 | shorthand for a data type could be valid as either an expression or a pattern. 189 | 190 | ## Repetition 191 | 192 | The repetition operator follows two principal rules: 193 | 194 | 1. `$(...)*` walks through one "layer" of repetitions, for all of the `$name`s 195 | it contains, in lockstep, and 196 | 2. each `$name` must be under at least as many `$(...)*`s as it was matched 197 | against. If it is under more, it'll be duplicated, as appropriate. 198 | 199 | This baroque macro illustrates the duplication of variables from outer 200 | repetition levels. 201 | 202 | ```rust 203 | macro_rules! o_O { 204 | ( 205 | $( 206 | $x:expr; [ $( $y:expr ),* ] 207 | );* 208 | ) => { 209 | &[ $($( $x + $y ),*),* ] 210 | } 211 | } 212 | 213 | fn main() { 214 | let a: &[i32] 215 | = o_O!(10; [1, 2, 3]; 216 | 20; [4, 5, 6]); 217 | 218 | assert_eq!(a, [11, 12, 13, 24, 25, 26]); 219 | } 220 | ``` 221 | 222 | That's most of the matcher syntax. These examples use `$(...)*`, which is a 223 | "zero or more" match. Alternatively you can write `$(...)+` for a "one or 224 | more" match. Both forms optionally include a separator, which can be any token 225 | except `+` or `*`. 226 | 227 | This system is based on 228 | "[Macro-by-Example](http://www.cs.indiana.edu/ftp/techreports/TR206.pdf)" 229 | (PDF link). 230 | 231 | # Hygiene 232 | 233 | Some languages implement macros using simple text substitution, which leads to 234 | various problems. For example, this C program prints `13` instead of the 235 | expected `25`. 236 | 237 | ```text 238 | #define FIVE_TIMES(x) 5 * x 239 | 240 | int main() { 241 | printf("%d\n", FIVE_TIMES(2 + 3)); 242 | return 0; 243 | } 244 | ``` 245 | 246 | After expansion we have `5 * 2 + 3`, and multiplication has greater precedence 247 | than addition. If you've used C macros a lot, you probably know the standard 248 | idioms for avoiding this problem, as well as five or six others. In Rust, we 249 | don't have to worry about it. 250 | 251 | ```rust 252 | macro_rules! five_times { 253 | ($x:expr) => (5 * $x); 254 | } 255 | 256 | fn main() { 257 | assert_eq!(25, five_times!(2 + 3)); 258 | } 259 | ``` 260 | 261 | The metavariable `$x` is parsed as a single expression node, and keeps its 262 | place in the syntax tree even after substitution. 263 | 264 | Another common problem in macro systems is *variable capture*. Here's a C 265 | macro, using [a GNU C extension] to emulate Rust's expression blocks. 266 | 267 | [a GNU C extension]: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html 268 | 269 | ```text 270 | #define LOG(msg) ({ \ 271 | int state = get_log_state(); \ 272 | if (state > 0) { \ 273 | printf("log(%d): %s\n", state, msg); \ 274 | } \ 275 | }) 276 | ``` 277 | 278 | Here's a simple use case that goes terribly wrong: 279 | 280 | ```text 281 | const char *state = "reticulating splines"; 282 | LOG(state) 283 | ``` 284 | 285 | This expands to 286 | 287 | ```text 288 | const char *state = "reticulating splines"; 289 | int state = get_log_state(); 290 | if (state > 0) { 291 | printf("log(%d): %s\n", state, state); 292 | } 293 | ``` 294 | 295 | The second variable named `state` shadows the first one. This is a problem 296 | because the print statement should refer to both of them. 297 | 298 | The equivalent Rust macro has the desired behavior. 299 | 300 | ```rust 301 | # fn get_log_state() -> i32 { 3 } 302 | macro_rules! log { 303 | ($msg:expr) => {{ 304 | let state: i32 = get_log_state(); 305 | if state > 0 { 306 | println!("log({}): {}", state, $msg); 307 | } 308 | }}; 309 | } 310 | 311 | fn main() { 312 | let state: &str = "reticulating splines"; 313 | log!(state); 314 | } 315 | ``` 316 | 317 | This works because Rust has a [hygienic macro system][]. Each macro expansion 318 | happens in a distinct *syntax context*, and each variable is tagged with the 319 | syntax context where it was introduced. It's as though the variable `state` 320 | inside `main` is painted a different "color" from the variable `state` inside 321 | the macro, and therefore they don't conflict. 322 | 323 | [hygienic macro system]: http://en.wikipedia.org/wiki/Hygienic_macro 324 | 325 | This also restricts the ability of macros to introduce new bindings at the 326 | invocation site. Code such as the following will not work: 327 | 328 | ```rust,ignore 329 | macro_rules! foo { 330 | () => (let x = 3); 331 | } 332 | 333 | fn main() { 334 | foo!(); 335 | println!("{}", x); 336 | } 337 | ``` 338 | 339 | Instead you need to pass the variable name into the invocation, so it's tagged 340 | with the right syntax context. 341 | 342 | ```rust 343 | macro_rules! foo { 344 | ($v:ident) => (let $v = 3); 345 | } 346 | 347 | fn main() { 348 | foo!(x); 349 | println!("{}", x); 350 | } 351 | ``` 352 | 353 | This holds for `let` bindings and loop labels, but not for [items][]. 354 | So the following code does compile: 355 | 356 | ```rust 357 | macro_rules! foo { 358 | () => (fn x() { }); 359 | } 360 | 361 | fn main() { 362 | foo!(); 363 | x(); 364 | } 365 | ``` 366 | 367 | [items]: ../reference.html#items 368 | 369 | # Recursive macros 370 | 371 | A macro's expansion can include more macro invocations, including invocations 372 | of the very same macro being expanded. These recursive macros are useful for 373 | processing tree-structured input, as illustrated by this (simplistic) HTML 374 | shorthand: 375 | 376 | ```rust 377 | # #![allow(unused_must_use)] 378 | macro_rules! write_html { 379 | ($w:expr, ) => (()); 380 | 381 | ($w:expr, $e:tt) => (write!($w, "{}", $e)); 382 | 383 | ($w:expr, $tag:ident [ $($inner:tt)* ] $($rest:tt)*) => {{ 384 | write!($w, "<{}>", stringify!($tag)); 385 | write_html!($w, $($inner)*); 386 | write!($w, "", stringify!($tag)); 387 | write_html!($w, $($rest)*); 388 | }}; 389 | } 390 | 391 | fn main() { 392 | # // FIXME(#21826) 393 | use std::fmt::Write; 394 | let mut out = String::new(); 395 | 396 | write_html!(&mut out, 397 | html[ 398 | head[title["Macros guide"]] 399 | body[h1["Macros are the best!"]] 400 | ]); 401 | 402 | assert_eq!(out, 403 | "Macros guide\ 404 |

Macros are the best!

"); 405 | } 406 | ``` 407 | 408 | # Debugging macro code 409 | 410 | To see the results of expanding macros, run `rustc --pretty expanded`. The 411 | output represents a whole crate, so you can also feed it back in to `rustc`, 412 | which will sometimes produce better error messages than the original 413 | compilation. Note that the `--pretty expanded` output may have a different 414 | meaning if multiple variables of the same name (but different syntax contexts) 415 | are in play in the same scope. In this case `--pretty expanded,hygiene` will 416 | tell you about the syntax contexts. 417 | 418 | `rustc` provides two syntax extensions that help with macro debugging. For now, 419 | they are unstable and require feature gates. 420 | 421 | * `log_syntax!(...)` will print its arguments to standard output, at compile 422 | time, and "expand" to nothing. 423 | 424 | * `trace_macros!(true)` will enable a compiler message every time a macro is 425 | expanded. Use `trace_macros!(false)` later in expansion to turn it off. 426 | 427 | # Further reading 428 | 429 | The [advanced macros chapter][] goes into more detail about macro syntax. It 430 | also describes how to share macros between different modules or crates. 431 | 432 | [advanced macros chapter]: advanced-macros.html 433 | -------------------------------------------------------------------------------- /documentation.md: -------------------------------------------------------------------------------- 1 | % Documentation 2 | 3 | Documentation is an important part of any software project, and it's 4 | first-class in Rust. Let's talk about the tooling Rust gives you to 5 | document your project. 6 | 7 | ## About `rustdoc` 8 | 9 | The Rust distribution includes a tool, `rustdoc`, that generates documentation. 10 | `rustdoc` is also used by Cargo through `cargo doc`. 11 | 12 | Documentation can be generated in two ways: from source code, and from 13 | standalone Markdown files. 14 | 15 | ## Documenting source code 16 | 17 | The primary way of documenting a Rust project is through annotating the source 18 | code. You can use documentation comments for this purpose: 19 | 20 | ```rust,ignore 21 | /// Constructs a new `Rc`. 22 | /// 23 | /// # Examples 24 | /// 25 | /// ``` 26 | /// use std::rc::Rc; 27 | /// 28 | /// let five = Rc::new(5); 29 | /// ``` 30 | pub fn new(value: T) -> Rc { 31 | // implementation goes here 32 | } 33 | ``` 34 | 35 | This code generates documentation that looks [like this][rc-new]. I've left the 36 | implementation out, with a regular comment in its place. That's the first thing 37 | to notice about this annotation: it uses `///`, instead of `//`. The triple slash 38 | indicates a documentation comment. 39 | 40 | Documentation comments are written in Markdown. 41 | 42 | Rust keeps track of these comments, and uses them when generating 43 | documentation. This is important when documenting things like enums: 44 | 45 | ``` 46 | /// The `Option` type. See [the module level documentation](../) for more. 47 | enum Option { 48 | /// No value 49 | None, 50 | /// Some value `T` 51 | Some(T), 52 | } 53 | ``` 54 | 55 | The above works, but this does not: 56 | 57 | ```rust,ignore 58 | /// The `Option` type. See [the module level documentation](../) for more. 59 | enum Option { 60 | None, /// No value 61 | Some(T), /// Some value `T` 62 | } 63 | ``` 64 | 65 | You'll get an error: 66 | 67 | ```text 68 | hello.rs:4:1: 4:2 error: expected ident, found `}` 69 | hello.rs:4 } 70 | ^ 71 | ``` 72 | 73 | This [unfortunate error](https://github.com/rust-lang/rust/issues/22547) is 74 | correct: documentation comments apply to the thing after them, and there's no 75 | thing after that last comment. 76 | 77 | [rc-new]: http://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new 78 | 79 | ### Writing documentation comments 80 | 81 | Anyway, let's cover each part of this comment in detail: 82 | 83 | ``` 84 | /// Constructs a new `Rc`. 85 | # fn foo() {} 86 | ``` 87 | 88 | The first line of a documentation comment should be a short summary of its 89 | functionality. One sentence. Just the basics. High level. 90 | 91 | ``` 92 | /// 93 | /// Other details about constructing `Rc`s, maybe describing complicated 94 | /// semantics, maybe additional options, all kinds of stuff. 95 | /// 96 | # fn foo() {} 97 | ``` 98 | 99 | Our original example had just a summary line, but if we had more things to say, 100 | we could have added more explanation in a new paragraph. 101 | 102 | #### Special sections 103 | 104 | ``` 105 | /// # Examples 106 | # fn foo() {} 107 | ``` 108 | 109 | Next, are special sections. These are indicated with a header, `#`. There 110 | are three kinds of headers that are commonly used. They aren't special syntax, 111 | just convention, for now. 112 | 113 | ``` 114 | /// # Panics 115 | # fn foo() {} 116 | ``` 117 | 118 | Unrecoverable misuses of a function (i.e. programming errors) in Rust are 119 | usually indicated by panics, which kill the whole current thread at the very 120 | least. If your function has a non-trivial contract like this, that is 121 | detected/enforced by panics, documenting it is very important. 122 | 123 | ``` 124 | /// # Failures 125 | # fn foo() {} 126 | ``` 127 | 128 | If your function or method returns a `Result`, then describing the 129 | conditions under which it returns `Err(E)` is a nice thing to do. This is 130 | slightly less important than `Panics`, because failure is encoded into the type 131 | system, but it's still a good thing to do. 132 | 133 | ``` 134 | /// # Safety 135 | # fn foo() {} 136 | ``` 137 | 138 | If your function is `unsafe`, you should explain which invariants the caller is 139 | responsible for upholding. 140 | 141 | ``` 142 | /// # Examples 143 | /// 144 | /// ``` 145 | /// use std::rc::Rc; 146 | /// 147 | /// let five = Rc::new(5); 148 | /// ``` 149 | # fn foo() {} 150 | ``` 151 | 152 | Third, `Examples`. Include one or more examples of using your function or 153 | method, and your users will love you for it. These examples go inside of 154 | code block annotations, which we'll talk about in a moment, and can have 155 | more than one section: 156 | 157 | ``` 158 | /// # Examples 159 | /// 160 | /// Simple `&str` patterns: 161 | /// 162 | /// ``` 163 | /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect(); 164 | /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]); 165 | /// ``` 166 | /// 167 | /// More complex patterns with a lambda: 168 | /// 169 | /// ``` 170 | /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect(); 171 | /// assert_eq!(v, vec!["abc", "def", "ghi"]); 172 | /// ``` 173 | # fn foo() {} 174 | ``` 175 | 176 | Let's discuss the details of these code blocks. 177 | 178 | #### Code block annotations 179 | 180 | To write some Rust code in a comment, use the triple graves: 181 | 182 | ``` 183 | /// ``` 184 | /// println!("Hello, world"); 185 | /// ``` 186 | # fn foo() {} 187 | ``` 188 | 189 | If you want something that's not Rust code, you can add an annotation: 190 | 191 | ``` 192 | /// ```c 193 | /// printf("Hello, world\n"); 194 | /// ``` 195 | # fn foo() {} 196 | ``` 197 | 198 | This will highlight according to whatever language you're showing off. 199 | If you're just showing plain text, choose `text`. 200 | 201 | It's important to choose the correct annotation here, because `rustdoc` uses it 202 | in an interesting way: It can be used to actually test your examples, so that 203 | they don't get out of date. If you have some C code but `rustdoc` thinks it's 204 | Rust because you left off the annotation, `rustdoc` will complain when trying to 205 | generate the documentation. 206 | 207 | ## Documentation as tests 208 | 209 | Let's discuss our sample example documentation: 210 | 211 | ``` 212 | /// ``` 213 | /// println!("Hello, world"); 214 | /// ``` 215 | # fn foo() {} 216 | ``` 217 | 218 | You'll notice that you don't need a `fn main()` or anything here. `rustdoc` will 219 | automatically add a main() wrapper around your code, and in the right place. 220 | For example: 221 | 222 | ``` 223 | /// ``` 224 | /// use std::rc::Rc; 225 | /// 226 | /// let five = Rc::new(5); 227 | /// ``` 228 | # fn foo() {} 229 | ``` 230 | 231 | This will end up testing: 232 | 233 | ``` 234 | fn main() { 235 | use std::rc::Rc; 236 | let five = Rc::new(5); 237 | } 238 | ``` 239 | 240 | Here's the full algorithm rustdoc uses to postprocess examples: 241 | 242 | 1. Any leading `#![foo]` attributes are left intact as crate attributes. 243 | 2. Some common `allow` attributes are inserted, including 244 | `unused_variables`, `unused_assignments`, `unused_mut`, 245 | `unused_attributes`, and `dead_code`. Small examples often trigger 246 | these lints. 247 | 3. If the example does not contain `extern crate`, then `extern crate 248 | ;` is inserted. 249 | 2. Finally, if the example does not contain `fn main`, the remainder of the 250 | text is wrapped in `fn main() { your_code }` 251 | 252 | Sometimes, this isn't enough, though. For example, all of these code samples 253 | with `///` we've been talking about? The raw text: 254 | 255 | ```text 256 | /// Some documentation. 257 | # fn foo() {} 258 | ``` 259 | 260 | looks different than the output: 261 | 262 | ``` 263 | /// Some documentation. 264 | # fn foo() {} 265 | ``` 266 | 267 | Yes, that's right: you can add lines that start with `# `, and they will 268 | be hidden from the output, but will be used when compiling your code. You 269 | can use this to your advantage. In this case, documentation comments need 270 | to apply to some kind of function, so if I want to show you just a 271 | documentation comment, I need to add a little function definition below 272 | it. At the same time, it's just there to satisfy the compiler, so hiding 273 | it makes the example more clear. You can use this technique to explain 274 | longer examples in detail, while still preserving the testability of your 275 | documentation. For example, this code: 276 | 277 | ``` 278 | let x = 5; 279 | let y = 6; 280 | println!("{}", x + y); 281 | ``` 282 | 283 | Here's an explanation, rendered: 284 | 285 | First, we set `x` to five: 286 | 287 | ``` 288 | let x = 5; 289 | # let y = 6; 290 | # println!("{}", x + y); 291 | ``` 292 | 293 | Next, we set `y` to six: 294 | 295 | ``` 296 | # let x = 5; 297 | let y = 6; 298 | # println!("{}", x + y); 299 | ``` 300 | 301 | Finally, we print the sum of `x` and `y`: 302 | 303 | ``` 304 | # let x = 5; 305 | # let y = 6; 306 | println!("{}", x + y); 307 | ``` 308 | 309 | Here's the same explanation, in raw text: 310 | 311 | > First, we set `x` to five: 312 | > 313 | > ```text 314 | > let x = 5; 315 | > # let y = 6; 316 | > # println!("{}", x + y); 317 | > ``` 318 | > 319 | > Next, we set `y` to six: 320 | > 321 | > ```text 322 | > # let x = 5; 323 | > let y = 6; 324 | > # println!("{}", x + y); 325 | > ``` 326 | > 327 | > Finally, we print the sum of `x` and `y`: 328 | > 329 | > ```text 330 | > # let x = 5; 331 | > # let y = 6; 332 | > println!("{}", x + y); 333 | > ``` 334 | 335 | By repeating all parts of the example, you can ensure that your example still 336 | compiles, while only showing the parts that are relevant to that part of your 337 | explanation. 338 | 339 | ### Documenting macros 340 | 341 | Here’s an example of documenting a macro: 342 | 343 | ``` 344 | /// Panic with a given message unless an expression evaluates to true. 345 | /// 346 | /// # Examples 347 | /// 348 | /// ``` 349 | /// # #[macro_use] extern crate foo; 350 | /// # fn main() { 351 | /// panic_unless!(1 + 1 == 2, “Math is broken.”); 352 | /// # } 353 | /// ``` 354 | /// 355 | /// ```should_fail 356 | /// # #[macro_use] extern crate foo; 357 | /// # fn main() { 358 | /// panic_unless!(true == false, “I’m broken.”); 359 | /// # } 360 | /// ``` 361 | #[macro_export] 362 | macro_rules! panic_unless { 363 | ($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } }); 364 | } 365 | # fn main() {} 366 | ``` 367 | 368 | You’ll note three things: we need to add our own `extern crate` line, so that 369 | we can add the `#[macro_use]` attribute. Second, we’ll need to add our own 370 | `main()` as well. Finally, a judicious use of `#` to comment out those two 371 | things, so they don’t show up in the output. 372 | 373 | ### Running documentation tests 374 | 375 | To run the tests, either 376 | 377 | ```bash 378 | $ rustdoc --test path/to/my/crate/root.rs 379 | # or 380 | $ cargo test 381 | ``` 382 | 383 | That's right, `cargo test` tests embedded documentation too. 384 | 385 | There are a few more annotations that are useful to help `rustdoc` do the right 386 | thing when testing your code: 387 | 388 | ``` 389 | /// ```ignore 390 | /// fn foo() { 391 | /// ``` 392 | # fn foo() {} 393 | ``` 394 | 395 | The `ignore` directive tells Rust to ignore your code. This is almost never 396 | what you want, as it's the most generic. Instead, consider annotating it 397 | with `text` if it's not code, or using `#`s to get a working example that 398 | only shows the part you care about. 399 | 400 | ``` 401 | /// ```should_panic 402 | /// assert!(false); 403 | /// ``` 404 | # fn foo() {} 405 | ``` 406 | 407 | `should_panic` tells `rustdoc` that the code should compile correctly, but 408 | not actually pass as a test. 409 | 410 | ``` 411 | /// ```no_run 412 | /// loop { 413 | /// println!("Hello, world"); 414 | /// } 415 | /// ``` 416 | # fn foo() {} 417 | ``` 418 | 419 | The `no_run` attribute will compile your code, but not run it. This is 420 | important for examples such as "Here's how to start up a network service," 421 | which you would want to make sure compile, but might run in an infinite loop! 422 | 423 | ### Documenting modules 424 | 425 | Rust has another kind of doc comment, `//!`. This comment doesn't document the next item, but the enclosing item. In other words: 426 | 427 | ``` 428 | mod foo { 429 | //! This is documentation for the `foo` module. 430 | //! 431 | //! # Examples 432 | 433 | // ... 434 | } 435 | ``` 436 | 437 | This is where you'll see `//!` used most often: for module documentation. If 438 | you have a module in `foo.rs`, you'll often open its code and see this: 439 | 440 | ``` 441 | //! A module for using `foo`s. 442 | //! 443 | //! The `foo` module contains a lot of useful functionality blah blah blah 444 | ``` 445 | 446 | ### Documentation comment style 447 | 448 | Check out [RFC 505][rfc505] for full conventions around the style and format of 449 | documentation. 450 | 451 | [rfc505]: https://github.com/rust-lang/rfcs/blob/master/text/0505-api-comment-conventions.md 452 | 453 | ## Other documentation 454 | 455 | All of this behavior works in non-Rust source files too. Because comments 456 | are written in Markdown, they're often `.md` files. 457 | 458 | When you write documentation in Markdown files, you don't need to prefix 459 | the documentation with comments. For example: 460 | 461 | ``` 462 | /// # Examples 463 | /// 464 | /// ``` 465 | /// use std::rc::Rc; 466 | /// 467 | /// let five = Rc::new(5); 468 | /// ``` 469 | # fn foo() {} 470 | ``` 471 | 472 | is just 473 | 474 | ~~~markdown 475 | # Examples 476 | 477 | ``` 478 | use std::rc::Rc; 479 | 480 | let five = Rc::new(5); 481 | ``` 482 | ~~~ 483 | 484 | when it's in a Markdown file. There is one wrinkle though: Markdown files need 485 | to have a title like this: 486 | 487 | ```markdown 488 | % The title 489 | 490 | This is the example documentation. 491 | ``` 492 | 493 | This `%` line needs to be the very first line of the file. 494 | 495 | ## `doc` attributes 496 | 497 | At a deeper level, documentation comments are sugar for documentation attributes: 498 | 499 | ``` 500 | /// this 501 | # fn foo() {} 502 | 503 | #[doc="this"] 504 | # fn bar() {} 505 | ``` 506 | 507 | are the same, as are these: 508 | 509 | ``` 510 | //! this 511 | 512 | #![doc="/// this"] 513 | ``` 514 | 515 | You won't often see this attribute used for writing documentation, but it 516 | can be useful when changing some options, or when writing a macro. 517 | 518 | ### Re-exports 519 | 520 | `rustdoc` will show the documentation for a publc re-export in both places: 521 | 522 | ```ignore 523 | extern crate foo; 524 | 525 | pub use foo::bar; 526 | ``` 527 | 528 | This will create documentation for bar both inside the documentation for the 529 | crate `foo`, as well as the documentation for your crate. It will use the same 530 | documentation in both places. 531 | 532 | This behavior can be supressed with `no_inline`: 533 | 534 | ```ignore 535 | extern crate foo; 536 | 537 | #[doc(no_inline)] 538 | pub use foo::bar; 539 | ``` 540 | 541 | ### Controlling HTML 542 | 543 | You can control a few aspects of the HTML that `rustdoc` generates through the 544 | `#![doc]` version of the attribute: 545 | 546 | ``` 547 | #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", 548 | html_favicon_url = "http://www.rust-lang.org/favicon.ico", 549 | html_root_url = "http://doc.rust-lang.org/")]; 550 | ``` 551 | 552 | This sets a few different options, with a logo, favicon, and a root URL. 553 | 554 | ## Generation options 555 | 556 | `rustdoc` also contains a few other options on the command line, for further customiziation: 557 | 558 | - `--html-in-header FILE`: includes the contents of FILE at the end of the 559 | `...` section. 560 | - `--html-before-content FILE`: includes the contents of FILE directly after 561 | ``, before the rendered content (including the search bar). 562 | - `--html-after-content FILE`: includes the contents of FILE after all the rendered content. 563 | --------------------------------------------------------------------------------