diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-01-28 12:01:57 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-02-02 10:59:14 -0800 |
| commit | 864b434bfa3fd5b3ea9e38958652ed1abdc24f1d (patch) | |
| tree | 55d1693b52303c3ae620762f31b616663746a442 /src/doc/tutorial.md | |
| parent | 2ff16b184950f5b24c3b2a4bf57b6dd7b3fbbe17 (diff) | |
| download | rust-864b434bfa3fd5b3ea9e38958652ed1abdc24f1d.tar.gz rust-864b434bfa3fd5b3ea9e38958652ed1abdc24f1d.zip | |
Move doc/ to src/doc/
We generate documentation into the doc/ directory, so we shouldn't be intermingling source files with generated files
Diffstat (limited to 'src/doc/tutorial.md')
| -rw-r--r-- | src/doc/tutorial.md | 3275 |
1 files changed, 3275 insertions, 0 deletions
diff --git a/src/doc/tutorial.md b/src/doc/tutorial.md new file mode 100644 index 00000000000..5122ac35602 --- /dev/null +++ b/src/doc/tutorial.md @@ -0,0 +1,3275 @@ +% The Rust Language Tutorial + +# Introduction + +Rust is a programming language with a focus on type safety, memory +safety, concurrency and performance. It is intended for writing +large-scale, high-performance software that is free from several +classes of common errors. Rust has a sophisticated memory model that +encourages efficient data structures and safe concurrency patterns, +forbidding invalid memory accesses that would otherwise cause +segmentation faults. It is statically typed and compiled ahead of +time. + +As a multi-paradigm language, Rust supports writing code in +procedural, functional and object-oriented styles. Some of its +pleasant high-level features include: + +* **Type inference.** Type annotations on local variable declarations + are optional. +* **Safe task-based concurrency.** Rust's lightweight tasks do not share + memory, instead communicating through messages. +* **Higher-order functions.** Efficient and flexible closures provide + iteration and other control structures +* **Pattern matching and algebraic data types.** Pattern matching on + Rust's enumeration types (a more powerful version of C's enums, + similar to algebraic data types in functional languages) is a + compact and expressive way to encode program logic. +* **Polymorphism.** Rust has type-parametric functions and + types, type classes and OO-style interfaces. + +## Scope + +This is an introductory tutorial for the Rust programming language. It +covers the fundamentals of the language, including the syntax, the +type system and memory model, generics, and modules. [Additional +tutorials](#what-next) cover specific language features in greater +depth. + +This tutorial assumes that the reader is already familiar with one or +more languages in the C family. Understanding of pointers and general +memory management techniques will help. + +## Conventions + +Throughout the tutorial, language keywords and identifiers defined in +example code are displayed in `code font`. + +Code snippets are indented, and also shown in a monospaced font. Not +all snippets constitute whole programs. For brevity, we'll often show +fragments of programs that don't compile on their own. To try them +out, you might have to wrap them in `fn main() { ... }`, and make sure +they don't contain references to names that aren't actually defined. + +> ***Warning:*** Rust is a language under ongoing development. Notes +> about potential changes to the language, implementation +> deficiencies, and other caveats appear offset in blockquotes. + +# Getting started + +> **NOTE**: The tarball and installer links are for the most recent release, +> not master. + +The Rust compiler currently must be built from a [tarball] or [git], unless +you are on Windows, in which case using the [installer][win-exe] is +recommended. There is a list of community-maintained nightly builds and +packages [on the wiki][wiki-packages]. + +Since the Rust compiler is written in Rust, it must be built by +a precompiled "snapshot" version of itself (made in an earlier state +of development). The source build automatically fetches these snapshots +from the Internet on our supported platforms. + +Snapshot binaries are currently built and tested on several platforms: + +* Windows (7, 8, Server 2008 R2), x86 only +* Linux (2.6.18 or later, various distributions), x86 and x86-64 +* OSX 10.7 (Lion) or greater, x86 and x86-64 + +You may find that other platforms work, but these are our "tier 1" +supported build environments that are most likely to work. + +> ***Note:*** Windows users should read the detailed +> "[getting started][wiki-start]" notes on the wiki. Even when using +> the binary installer, the Windows build requires a MinGW installation, +> the precise details of which are not discussed here. Finally, `rustc` may +> need to be [referred to as `rustc.exe`][bug-3319]. It's a bummer, we +> know. + +[bug-3319]: https://github.com/mozilla/rust/issues/3319 +[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust +[git]: https://github.com/mozilla/rust.git + +To build from source you will also need the following prerequisite +packages: + +* g++ 4.4 or clang++ 3.x +* python 2.6 or later (but not 3.x) +* perl 5.0 or later +* gnu make 3.81 or later +* curl + +If you've fulfilled those prerequisites, something along these lines +should work. + +~~~~ {.notrust} +$ curl -O http://static.rust-lang.org/dist/rust-0.9.tar.gz +$ tar -xzf rust-0.9.tar.gz +$ cd rust-0.9 +$ ./configure +$ make && make install +~~~~ + +You may need to use `sudo make install` if you do not normally have +permission to modify the destination directory. The install locations +can be adjusted by passing a `--prefix` argument to +`configure`. Various other options are also supported: pass `--help` +for more information on them. + +When complete, `make install` will place several programs into +`/usr/local/bin`: `rustc`, the Rust compiler, and `rustdoc`, the +API-documentation tool. + +[tarball]: http://static.rust-lang.org/dist/rust-0.9.tar.gz +[win-exe]: http://static.rust-lang.org/dist/rust-0.9-install.exe + +## Compiling your first program + +Rust program files are, by convention, given the extension `.rs`. Say +we have a file `hello.rs` containing this program: + +~~~~ +fn main() { + println!("hello?"); +} +~~~~ + +If the Rust compiler was installed successfully, running `rustc +hello.rs` will produce an executable called `hello` (or `hello.exe` on +Windows) which, upon running, will likely do exactly what you expect. + +The Rust compiler tries to provide useful information when it encounters an +error. If you introduce an error into the program (for example, by changing +`println!` to some nonexistent macro), and then compile it, you'll see +an error message like this: + +~~~~ {.notrust} +hello.rs:2:5: 2:24 error: macro undefined: 'print_with_unicorns' +hello.rs:2 print_with_unicorns!("hello?"); + ^~~~~~~~~~~~~~~~~~~ +~~~~ + +In its simplest form, a Rust program is a `.rs` file with some types +and functions defined in it. If it has a `main` function, it can be +compiled to an executable. Rust does not allow code that's not a +declaration to appear at the top level of the file: all statements must +live inside a function. Rust programs can also be compiled as +libraries, and included in other programs, even ones not written in Rust. + +## Editing Rust code + +There are vim highlighting and indentation scripts in the Rust source +distribution under `src/etc/vim/`. There is an emacs mode under +`src/etc/emacs/` called `rust-mode`, but do read the instructions +included in that directory. In particular, if you are running emacs +24, then using emacs's internal package manager to install `rust-mode` +is the easiest way to keep it up to date. There is also a package for +Sublime Text 2, available both [standalone][sublime] and through +[Sublime Package Control][sublime-pkg], and support for Kate +under `src/etc/kate`. + +A community-maintained list of available Rust tooling is [on the +wiki][wiki-packages]. + +There is ctags support via `src/etc/ctags.rust`, but many other +tools and editors are not yet supported. If you end up writing a Rust +mode for your favorite editor, let us know so that we can link to it. + +[sublime]: http://github.com/dbp/sublime-rust +[sublime-pkg]: http://wbond.net/sublime_packages/package_control + +# Syntax basics + +Assuming you've programmed in any C-family language (C++, Java, +JavaScript, C#, or PHP), Rust will feel familiar. Code is arranged +in blocks delineated by curly braces; there are control structures +for branching and looping, like the familiar `if` and `while`; function +calls are written `myfunc(arg1, arg2)`; operators are written the same +and mostly have the same precedence as in C; comments are again like C; +module names are separated with double-colon (`::`) as with C++. + +The main surface difference to be aware of is that the condition at +the head of control structures like `if` and `while` does not require +parentheses, while their bodies *must* be wrapped in +braces. Single-statement, unbraced bodies are not allowed. + +~~~~ +# mod universe { pub fn recalibrate() -> bool { true } } +fn main() { + /* A simple loop */ + loop { + // A tricky calculation + if universe::recalibrate() { + return; + } + } +} +~~~~ + +The `let` keyword introduces a local variable. Variables are immutable by +default. To introduce a local variable that you can re-assign later, use `let +mut` instead. + +~~~~ +let hi = "hi"; +let mut count = 0; + +while count < 10 { + println!("count is {}", count); + count += 1; +} +~~~~ + +Although Rust can almost always infer the types of local variables, you can +specify a variable's type by following it in the `let` with a colon, then the +type name. Static items, on the other hand, always require a type annotation. + + +~~~~ +static MONSTER_FACTOR: f64 = 57.8; +let monster_size = MONSTER_FACTOR * 10.0; +let monster_size: int = 50; +~~~~ + +Local variables may shadow earlier declarations, as in the previous example: +`monster_size` was first declared as a `f64`, and then a second +`monster_size` was declared as an `int`. If you were to actually compile this +example, though, the compiler would determine that the first `monster_size` is +unused and issue a warning (because this situation is likely to indicate a +programmer error). For occasions where unused variables are intentional, their +names may be prefixed with an underscore to silence the warning, like `let +_monster_size = 50;`. + +Rust identifiers start with an alphabetic +character or an underscore, and after that may contain any sequence of +alphabetic characters, numbers, or underscores. The preferred style is to +write function, variable, and module names with lowercase letters, using +underscores where they help readability, while writing types in camel case. + +~~~ +let my_variable = 100; +type MyType = int; // primitive types are _not_ camel case +~~~ + +## Expressions and semicolons + +Though it isn't apparent in all code, there is a fundamental +difference between Rust's syntax and predecessors like C. +Many constructs that are statements in C are expressions +in Rust, allowing code to be more concise. For example, you might +write a piece of code like this: + +~~~~ +# let item = "salad"; +let price; +if item == "salad" { + price = 3.50; +} else if item == "muffin" { + price = 2.25; +} else { + price = 2.00; +} +~~~~ + +But, in Rust, you don't have to repeat the name `price`: + +~~~~ +# let item = "salad"; +let price = + if item == "salad" { + 3.50 + } else if item == "muffin" { + 2.25 + } else { + 2.00 + }; +~~~~ + +Both pieces of code are exactly equivalent: they assign a value to +`price` depending on the condition that holds. Note that there +are no semicolons in the blocks of the second snippet. This is +important: the lack of a semicolon after the last statement in a +braced block gives the whole block the value of that last expression. + +Put another way, the semicolon in Rust *ignores the value of an expression*. +Thus, if the branches of the `if` had looked like `{ 4; }`, the above example +would simply assign `()` (nil or void) to `price`. But without the semicolon, each +branch has a different value, and `price` gets the value of the branch that +was taken. + +In short, everything that's not a declaration (declarations are `let` for +variables; `fn` for functions; and any top-level named items such as +[traits](#traits), [enum types](#enums), and static items) is an +expression, including function bodies. + +~~~~ +fn is_four(x: int) -> bool { + // No need for a return statement. The result of the expression + // is used as the return value. + x == 4 +} +~~~~ + +## Primitive types and literals + +There are general signed and unsigned integer types, `int` and `uint`, +as well as 8-, 16-, 32-, and 64-bit variants, `i8`, `u16`, etc. +Integers can be written in decimal (`144`), hexadecimal (`0x90`), octal (`0o70`), or +binary (`0b10010000`) base. Each integral type has a corresponding literal +suffix that can be used to indicate the type of a literal: `i` for `int`, +`u` for `uint`, `i8` for the `i8` type. + +In the absence of an integer literal suffix, Rust will infer the +integer type based on type annotations and function signatures in the +surrounding program. In the absence of any type information at all, +Rust will assume that an unsuffixed integer literal has type +`int`. + +~~~~ +let a = 1; // `a` is an `int` +let b = 10i; // `b` is an `int`, due to the `i` suffix +let c = 100u; // `c` is a `uint` +let d = 1000i32; // `d` is an `i32` +~~~~ + +There are two floating-point types: `f32`, and `f64`. +Floating-point numbers are written `0.0`, `1e6`, or `2.1e-4`. +Like integers, floating-point literals are inferred to the correct type. +Suffixes `f32`, and `f64` can be used to create literals of a specific type. + +The keywords `true` and `false` produce literals of type `bool`. + +Characters, the `char` type, are four-byte Unicode codepoints, +whose literals are written between single quotes, as in `'x'`. +Just like C, Rust understands a number of character escapes, using the backslash +character, such as `\n`, `\r`, and `\t`. String literals, +written between double quotes, allow the same escape sequences, and do no +other processing, unlike languages such as PHP or shell. + +On the other hand, raw string literals do not process any escape sequences. +They are written as `r##"blah"##`, with a matching number of zero or more `#` +before the opening and after the closing quote, and can contain any sequence of +characters except their closing delimiter. More on strings +[later](#vectors-and-strings). + +The nil type, written `()`, has a single value, also written `()`. + +## Operators + +Rust's set of operators contains very few surprises. Arithmetic is done with +`*`, `/`, `%`, `+`, and `-` (multiply, quotient, remainder, add, and subtract). `-` is +also a unary prefix operator that negates numbers. As in C, the bitwise operators +`>>`, `<<`, `&`, `|`, and `^` are also supported. + +Note that, if applied to an integer value, `!` flips all the bits (bitwise +NOT, like `~` in C). + +The comparison operators are the traditional `==`, `!=`, `<`, `>`, +`<=`, and `>=`. Short-circuiting (lazy) boolean operators are written +`&&` (and) and `||` (or). + +For compile-time type casting, Rust uses the binary `as` operator. It takes +an expression on the left side and a type on the right side and will, if a +meaningful conversion exists, convert the result of the expression to the +given type. Generally, `as` is only used with the primitive numeric types or +pointers, and is not overloadable. [`transmute`][transmute] can be used for +unsafe C-like casting of same-sized types. + +~~~~ +let x: f64 = 4.0; +let y: uint = x as uint; +assert!(y == 4u); +~~~~ + +[transmute]: http://static.rust-lang.org/doc/master/std/cast/fn.transmute.html + +## Syntax extensions + +*Syntax extensions* are special forms that are not built into the language, +but are instead provided by the libraries. To make it clear to the reader when +a name refers to a syntax extension, the names of all syntax extensions end +with `!`. The standard library defines a few syntax extensions, the most +useful of which is [`format!`][fmt], a `sprintf`-like text formatter that you +will often see in examples, and its related family of macros: `print!`, +`println!`, and `write!`. + +`format!` draws syntax from Python, but contains many of the same principles +that [printf][pf] has. Unlike printf, `format!` will give you a compile-time +error when the types of the directives don't match the types of the arguments. + +~~~~ +# let mystery_object = (); + +// `{}` will print the "default format" of a type +println!("{} is {}", "the answer", 43); + +// `{:?}` will conveniently print any type +println!("what is this thing: {:?}", mystery_object); +~~~~ + +[pf]: http://en.cppreference.com/w/cpp/io/c/fprintf +[fmt]: http://static.rust-lang.org/doc/master/std/fmt/index.html + +You can define your own syntax extensions with the macro system. For details, +see the [macro tutorial][macros]. Note that macro definition is currently +considered an unstable feature. + +# Control structures + +## Conditionals + +We've seen `if` expressions a few times already. To recap, braces are +compulsory, an `if` can have an optional `else` clause, and multiple +`if`/`else` constructs can be chained together: + +~~~~ +if false { + println!("that's odd"); +} else if true { + println!("right"); +} else { + println!("neither true nor false"); +} +~~~~ + +The condition given to an `if` construct *must* be of type `bool` (no +implicit conversion happens). If the arms are blocks that have a +value, this value must be of the same type for every arm in which +control reaches the end of the block: + +~~~~ +fn signum(x: int) -> int { + if x < 0 { -1 } + else if x > 0 { 1 } + else { 0 } +} +~~~~ + +## Pattern matching + +Rust's `match` construct is a generalized, cleaned-up version of C's +`switch` construct. You provide it with a value and a number of +*arms*, each labelled with a pattern, and the code compares the value +against each pattern in order until one matches. The matching pattern +executes its corresponding arm. + +~~~~ +# let my_number = 1; +match my_number { + 0 => println!("zero"), + 1 | 2 => println!("one or two"), + 3..10 => println!("three to ten"), + _ => println!("something else") +} +~~~~ + +Unlike in C, there is no "falling through" between arms: only one arm +executes, and it doesn't have to explicitly `break` out of the +construct when it is finished. + +A `match` arm consists of a *pattern*, then an arrow `=>`, followed by +an *action* (expression). Literals are valid patterns and match only +their own value. A single arm may match multiple different patterns by +combining them with the pipe operator (`|`), so long as every pattern +binds the same set of variables. Ranges of numeric literal patterns +can be expressed with two dots, as in `M..N`. The underscore (`_`) is +a wildcard pattern that matches any single value. (`..`) is a different +wildcard that can match one or more fields in an `enum` variant. + +The patterns in a match arm are followed by a fat arrow, `=>`, then an +expression to evaluate. Each case is separated by commas. It's often +convenient to use a block expression for each case, in which case the +commas are optional. + +~~~ +# let my_number = 1; +match my_number { + 0 => { println!("zero") } + _ => { println!("something else") } +} +~~~ + +`match` constructs must be *exhaustive*: they must have an arm +covering every possible case. For example, the typechecker would +reject the previous example if the arm with the wildcard pattern was +omitted. + +A powerful application of pattern matching is *destructuring*: +matching in order to bind names to the contents of data +types. + +> ***Note:*** The following code makes use of tuples (`(f64, f64)`) which +> are explained in section 5.3. For now you can think of tuples as a list of +> items. + +~~~~ +use std::f64; +use std::num::atan; +fn angle(vector: (f64, f64)) -> f64 { + let pi = f64::consts::PI; + match vector { + (0.0, y) if y < 0.0 => 1.5 * pi, + (0.0, y) => 0.5 * pi, + (x, y) => atan(y / x) + } +} +~~~~ + +A variable name in a pattern matches any value, *and* binds that name +to the value of the matched value inside of the arm's action. Thus, `(0.0, +y)` matches any tuple whose first element is zero, and binds `y` to +the second element. `(x, y)` matches any two-element tuple, and binds both +elements to variables. +A subpattern can also be bound to a variable, using `variable @ pattern`. For +example: + +~~~~ +# let age = 23; +match age { + a @ 0..20 => println!("{} years old", a), + _ => println!("older than 21") +} +~~~~ + +Any `match` arm can have a guard clause (written `if EXPR`), called a +*pattern guard*, which is an expression of type `bool` that +determines, after the pattern is found to match, whether the arm is +taken or not. The variables bound by the pattern are in scope in this +guard expression. The first arm in the `angle` example shows an +example of a pattern guard. + +You've already seen simple `let` bindings, but `let` is a little +fancier than you've been led to believe. It, too, supports destructuring +patterns. For example, you can write this to extract the fields from a +tuple, introducing two variables at once: `a` and `b`. + +~~~~ +# fn get_tuple_of_two_ints() -> (int, int) { (1, 1) } +let (a, b) = get_tuple_of_two_ints(); +~~~~ + +Let bindings only work with _irrefutable_ patterns: that is, patterns +that can never fail to match. This excludes `let` from matching +literals and most `enum` variants. + +## Loops + +`while` denotes a loop that iterates as long as its given condition +(which must have type `bool`) evaluates to `true`. Inside a loop, the +keyword `break` aborts the loop, and `continue` aborts the current +iteration and continues with the next. + +~~~~ +let mut cake_amount = 8; +while cake_amount > 0 { + cake_amount -= 1; +} +~~~~ + +`loop` denotes an infinite loop, and is the preferred way of writing `while true`: + +~~~~ +let mut x = 5u; +loop { + x += x - 3; + if x % 5 == 0 { break; } + println!("{}", x); +} +~~~~ + +This code prints out a weird sequence of numbers and stops as soon as +it finds one that can be divided by five. + +# Data structures + +## Structs + +Rust struct types must be declared before they are used using the `struct` +syntax: `struct Name { field1: T1, field2: T2 [, ...] }`, where `T1`, `T2`, +... denote types. To construct a struct, use the same syntax, but leave off +the `struct`: for example: `Point { x: 1.0, y: 2.0 }`. + +Structs are quite similar to C structs and are even laid out the same way in +memory (so you can read from a Rust struct in C, and vice-versa). Use the dot +operator to access struct fields, as in `mypoint.x`. + +~~~~ +struct Point { + x: f64, + y: f64 +} +~~~~ + +Structs have "inherited mutability", which means that any field of a struct +may be mutable, if the struct is in a mutable slot. + +With a value (say, `mypoint`) of such a type in a mutable location, you can do +`mypoint.y += 1.0`. But in an immutable location, such an assignment to a +struct without inherited mutability would result in a type error. + +~~~~ {.ignore} +# struct Point { x: f64, y: f64 } +let mut mypoint = Point { x: 1.0, y: 1.0 }; +let origin = Point { x: 0.0, y: 0.0 }; + +mypoint.y += 1.0; // `mypoint` is mutable, and its fields as well +origin.y += 1.0; // ERROR: assigning to immutable field +~~~~ + +`match` patterns destructure structs. The basic syntax is +`Name { fieldname: pattern, ... }`: + +~~~~ +# struct Point { x: f64, y: f64 } +# let mypoint = Point { x: 0.0, y: 0.0 }; +match mypoint { + Point { x: 0.0, y: yy } => println!("{}", yy), + Point { x: xx, y: yy } => println!("{} {}", xx, yy), +} +~~~~ + +In general, the field names of a struct do not have to appear in the same +order they appear in the type. When you are not interested in all +the fields of a struct, a struct pattern may end with `, ..` (as in +`Name { field1, .. }`) to indicate that you're ignoring all other fields. +Additionally, struct fields have a shorthand matching form that simply +reuses the field name as the binding name. + +~~~ +# struct Point { x: f64, y: f64 } +# let mypoint = Point { x: 0.0, y: 0.0 }; +match mypoint { + Point { x, .. } => println!("{}", x), +} +~~~ + +## Enums + +Enums are datatypes that have several alternate representations. For +example, consider the following type: + +~~~~ +# struct Point { x: f64, y: f64 } +enum Shape { + Circle(Point, f64), + Rectangle(Point, Point) +} +~~~~ + +A value of this type is either a `Circle`, in which case it contains a +`Point` struct and a f64, or a `Rectangle`, in which case it contains +two `Point` structs. The run-time representation of such a value +includes an identifier of the actual form that it holds, much like the +"tagged union" pattern in C, but with better static guarantees. + +The above declaration will define a type `Shape` that can refer to +such shapes, and two functions, `Circle` and `Rectangle`, which can be +used to construct values of the type (taking arguments of the +specified types). So `Circle(Point { x: 0.0, y: 0.0 }, 10.0)` is the way to +create a new circle. + +Enum variants need not have parameters. This `enum` declaration, +for example, is equivalent to a C enum: + +~~~~ +enum Direction { + North, + East, + South, + West +} +~~~~ + +This declaration defines `North`, `East`, `South`, and `West` as constants, +all of which have type `Direction`. + +When an enum is C-like (that is, when none of the variants have +parameters), it is possible to explicitly set the discriminator values +to a constant value: + +~~~~ +enum Color { + Red = 0xff0000, + Green = 0x00ff00, + Blue = 0x0000ff +} +~~~~ + +If an explicit discriminator is not specified for a variant, the value +defaults to the value of the previous variant plus one. If the first +variant does not have a discriminator, it defaults to 0. For example, +the value of `North` is 0, `East` is 1, `South` is 2, and `West` is 3. + +When an enum is C-like, you can apply the `as` cast operator to +convert it to its discriminator value as an `int`. + +For enum types with multiple variants, destructuring is the only way to +get at their contents. All variant constructors can be used as +patterns, as in this definition of `area`: + +~~~~ +use std::f64; +# struct Point {x: f64, y: f64} +# enum Shape { Circle(Point, f64), Rectangle(Point, Point) } +fn area(sh: Shape) -> f64 { + match sh { + Circle(_, size) => f64::consts::PI * size * size, + Rectangle(Point { x, y }, Point { x: x2, y: y2 }) => (x2 - x) * (y2 - y) + } +} +~~~~ + +You can write a lone `_` to ignore an individual field, and can +ignore all fields of a variant like: `Circle(..)`. As in their +introduction form, nullary enum patterns are written without +parentheses. + +~~~~ +# struct Point { x: f64, y: f64 } +# enum Direction { North, East, South, West } +fn point_from_direction(dir: Direction) -> Point { + match dir { + North => Point { x: 0.0, y: 1.0 }, + East => Point { x: 1.0, y: 0.0 }, + South => Point { x: 0.0, y: -1.0 }, + West => Point { x: -1.0, y: 0.0 } + } +} +~~~~ + +Enum variants may also be structs. For example: + +~~~~ +use std::f64; +# struct Point { x: f64, y: f64 } +# fn square(x: f64) -> f64 { x * x } +enum Shape { + Circle { center: Point, radius: f64 }, + Rectangle { top_left: Point, bottom_right: Point } +} +fn area(sh: Shape) -> f64 { + match sh { + Circle { radius: radius, .. } => f64::consts::PI * square(radius), + Rectangle { top_left: top_left, bottom_right: bottom_right } => { + (bottom_right.x - top_left.x) * (top_left.y - bottom_right.y) + } + } +} +~~~~ + +> ***Note:*** This feature of the compiler is currently gated behind the +> `#[feature(struct_variant)]` directive. More about these directives can be +> found in the manual. + +## Tuples + +Tuples in Rust behave exactly like structs, except that their fields do not +have names. Thus, you cannot access their fields with dot notation. Tuples +can have any arity (number of elements) except for 0 (though you may consider +unit, `()`, as the empty tuple if you like). + +~~~~ +let mytup: (int, int, f64) = (10, 20, 30.0); +match mytup { + (a, b, c) => info!("{}", a + b + (c as int)) +} +~~~~ + +## Tuple structs + +Rust also has _tuple structs_, which behave like both structs and tuples, +except that, unlike tuples, tuple structs have names (so `Foo(1, 2)` has a +different type from `Bar(1, 2)`), and tuple structs' _fields_ do not have +names. + +For example: + +~~~~ +struct MyTup(int, int, f64); +let mytup: MyTup = MyTup(10, 20, 30.0); +match mytup { + MyTup(a, b, c) => info!("{}", a + b + (c as int)) +} +~~~~ + +<a name="newtype"></a> + +There is a special case for tuple structs with a single field, which are +sometimes called "newtypes" (after Haskell's "newtype" feature). These are +used to define new types in such a way that the new name is not just a +synonym for an existing type but is rather its own distinct type. + +~~~~ +struct GizmoId(int); +~~~~ + +Types like this can be useful to differentiate between data that have +the same underlying type but must be used in different ways. + +~~~~ +struct Inches(int); +struct Centimeters(int); +~~~~ + +The above definitions allow for a simple way for programs to avoid +confusing numbers that correspond to different units. Their integer +values can be extracted with pattern matching: + +~~~ +# struct Inches(int); + +let length_with_unit = Inches(10); +let Inches(integer_length) = length_with_unit; +println!("length is {} inches", integer_length); +~~~ + +# Functions + +We've already seen several function definitions. Like all other static +declarations, such as `type`, functions can be declared both at the +top level and inside other functions (or in modules, which we'll come +back to [later](#crates-and-the-module-system)). The `fn` keyword introduces a +function. A function has an argument list, which is a parenthesized +list of `name: type` pairs separated by commas. An arrow `->` +separates the argument list and the function's return type. + +~~~~ +fn line(a: int, b: int, x: int) -> int { + return a * x + b; +} +~~~~ + +The `return` keyword immediately returns from the body of a function. It +is optionally followed by an expression to return. A function can +also return a value by having its top-level block produce an +expression. + +~~~~ +fn line(a: int, b: int, x: int) -> int { + a * x + b +} +~~~~ + +It's better Rust style to write a return value this way instead of +writing an explicit `return`. The utility of `return` comes in when +returning early from a function. Functions that do not return a value +are said to return nil, `()`, and both the return type and the return +value may be omitted from the definition. The following two functions +are equivalent. + +~~~~ +fn do_nothing_the_hard_way() -> () { return (); } + +fn do_nothing_the_easy_way() { } +~~~~ + +Ending the function with a semicolon like so is equivalent to returning `()`. + +~~~~ +fn line(a: int, b: int, x: int) -> int { a * x + b } +fn oops(a: int, b: int, x: int) -> () { a * x + b; } + +assert!(8 == line(5, 3, 1)); +assert!(() == oops(5, 3, 1)); +~~~~ + +As with `match` expressions and `let` bindings, function arguments support +pattern destructuring. Like `let`, argument patterns must be irrefutable, +as in this example that unpacks the first value from a tuple and returns it. + +~~~ +fn first((value, _): (int, f64)) -> int { value } +~~~ + +# Destructors + +A *destructor* is a function responsible for cleaning up the resources used by +an object when it is no longer accessible. Destructors can be defined to handle +the release of resources like files, sockets and heap memory. + +Objects are never accessible after their destructor has been called, so no +dynamic failures are possible from accessing freed resources. When a task +fails, destructors of all objects in the task are called. + +The `~` sigil represents a unique handle for a memory allocation on the heap: + +~~~~ +{ + // an integer allocated on the heap + let y = ~10; +} +// the destructor frees the heap memory as soon as `y` goes out of scope +~~~~ + +Rust includes syntax for heap memory allocation in the language since it's +commonly used, but the same semantics can be implemented by a type with a +custom destructor. + +# Ownership + +Rust formalizes the concept of object ownership to delegate management of an +object's lifetime to either a variable or a task-local garbage collector. An +object's owner is responsible for managing the lifetime of the object by +calling the destructor, and the owner determines whether the object is mutable. + +Ownership is recursive, so mutability is inherited recursively and a destructor +destroys the contained tree of owned objects. Variables are top-level owners +and destroy the contained object when they go out of scope. + +~~~~ +// the struct owns the objects contained in the `x` and `y` fields +struct Foo { x: int, y: ~int } + +{ + // `a` is the owner of the struct, and thus the owner of the struct's fields + let a = Foo { x: 5, y: ~10 }; +} +// when `a` goes out of scope, the destructor for the `~int` in the struct's +// field is called + +// `b` is mutable, and the mutability is inherited by the objects it owns +let mut b = Foo { x: 5, y: ~10 }; +b.x = 10; +~~~~ + +If an object doesn't contain any non-Send types, it consists of a single +ownership tree and is itself given the `Send` trait which allows it to be sent +between tasks. Custom destructors can only be implemented directly on types +that are `Send`, but non-`Send` types can still *contain* types with custom +destructors. Example of types which are not `Send` are [`Gc<T>`][gc] and +[`Rc<T>`][rc], the shared-ownership types. + +[gc]: http://static.rust-lang.org/doc/master/std/gc/struct.Gc.html +[rc]: http://static.rust-lang.org/doc/master/std/rc/struct.Rc.html + +# Implementing a linked list + +An `enum` is a natural fit for describing a linked list, because it can express +a `List` type as being *either* the end of the list (`Nil`) or another node +(`Cons`). The full definition of the `Cons` variant will require some thought. + +~~~ {.ignore} +enum List { + Cons(...), // an incomplete definition of the next element in a List + Nil // the end of a List +} +~~~ + +The obvious approach is to define `Cons` as containing an element in the list +along with the next `List` node. However, this will generate a compiler error. + +~~~ {.ignore} +// error: illegal recursive enum type; wrap the inner value in a box to make it representable +enum List { + Cons(u32, List), // an element (`u32`) and the next node in the list + Nil +} +~~~ + +This error message is related to Rust's precise control over memory layout, and +solving it will require introducing the concept of *boxing*. + +## Boxes + +A value in Rust is stored directly inside the owner. If a `struct` contains +four `u32` fields, it will be four times as large as a single `u32`. + +~~~ +use std::mem::size_of; // bring `size_of` into the current scope, for convenience + +struct Foo { + a: u32, + b: u32, + c: u32, + d: u32 +} + +assert_eq!(size_of::<Foo>(), size_of::<u32>() * 4); + +struct Bar { + a: Foo, + b: Foo, + c: Foo, + d: Foo +} + +assert_eq!(size_of::<Bar>(), size_of::<u32>() * 16); +~~~ + +Our previous attempt at defining the `List` type included an `u32` and a `List` +directly inside `Cons`, making it at least as big as the sum of both types. The +type was invalid because the size was infinite! + +An *owned box* (`~`) uses a dynamic memory allocation to provide the invariant +of always being the size of a pointer, regardless of the contained type. This +can be leverage to create a valid `List` definition: + +~~~ +enum List { + Cons(u32, ~List), + Nil +} +~~~ + +Defining a recursive data structure like this is the canonical example of an +owned box. Much like an unboxed value, an owned box has a single owner and is +therefore limited to expressing a tree-like data structure. + +Consider an instance of our `List` type: + +~~~ +# enum List { +# Cons(u32, ~List), +# Nil +# } +let list = Cons(1, ~Cons(2, ~Cons(3, ~Nil))); +~~~ + +It represents an owned tree of values, inheriting mutability down the tree and +being destroyed along with the owner. Since the `list` variable above is +immutable, the whole list is immutable. The memory allocation itself is the +box, while the owner holds onto a pointer to it: + + List box List box List box List box + +--------------+ +--------------+ +--------------+ +--------------+ + list -> | Cons | 1 | ~ | -> | Cons | 2 | ~ | -> | Cons | 3 | ~ | -> | Nil | + +--------------+ +--------------+ +--------------+ +--------------+ + +> Note: the above diagram shows the logical contents of the enum. The actual +> memory layout of the enum may vary. For example, for the `List` enum shown +> above, Rust guarantees that there will be no enum tag field in the actual +> structure. See the language reference for more details. + +An owned box is a common example of a type with a destructor. The allocated +memory is cleaned up when the box is destroyed. + +## Move semantics + +Rust uses a shallow copy for parameter passing, assignment and returning from +functions. Passing around the `List` will copy only as deep as the pointer to +the box rather than doing an implicit heap allocation. + +~~~ +# enum List { +# Cons(u32, ~List), +# Nil +# } +let xs = Cons(1, ~Cons(2, ~Cons(3, ~Nil))); +let ys = xs; // copies `Cons(u32, pointer)` shallowly +~~~ + +Rust will consider a shallow copy of a type with a destructor like `List` to +*move ownership* of the value. After a value has been moved, the source +location cannot be used unless it is reinitialized. + +~~~ +# enum List { +# Cons(u32, ~List), +# Nil +# } +let mut xs = Nil; +let ys = xs; + +// attempting to use `xs` will result in an error here + +xs = Nil; + +// `xs` can be used again +~~~ + +A destructor call will only occur for a variable that has not been moved from, +as it is only called a single time. + + +Avoiding a move can be done with the library-defined `clone` method: + +~~~~ +let x = ~5; +let y = x.clone(); // `y` is a newly allocated box +let z = x; // no new memory allocated, `x` can no longer be used +~~~~ + +The `clone` method is provided by the `Clone` trait, and can be derived for +our `List` type. Traits will be explained in detail later. + +~~~{.ignore} +#[deriving(Clone)] +enum List { + Cons(u32, ~List), + Nil +} + +let x = Cons(5, ~Nil); +let y = x.clone(); + +// `x` can still be used! + +let z = x; + +// and now, it can no longer be used since it has been moved +~~~ + +The mutability of a value may be changed by moving it to a new owner: + +~~~~ +let r = ~13; +let mut s = r; // box becomes mutable +*s += 1; +let t = s; // box becomes immutable +~~~~ + +A simple way to define a function prepending to the `List` type is to take +advantage of moves: + +~~~ +enum List { + Cons(u32, ~List), + Nil +} + +fn prepend(xs: List, value: u32) -> List { + Cons(value, ~xs) +} + +let mut xs = Nil; +xs = prepend(xs, 1); +xs = prepend(xs, 2); +xs = prepend(xs, 3); +~~~ + +However, this is not a very flexible definition of `prepend` as it requires +ownership of a list to be passed in rather than just mutating it in-place. + +## References + +The obvious signature for a `List` equality comparison is the following: + +~~~{.ignore} +fn eq(xs: List, ys: List) -> bool { ... } +~~~ + +However, this will cause both lists to be moved into the function. Ownership +isn't required to compare the lists, so the function should take *references* +(&T) instead. + +~~~{.ignore} +fn eq(xs: &List, ys: &List) -> bool { ... } +~~~ + +A reference is a *non-owning* view of a value. A reference can be obtained with the `&` (address-of) +operator. It can be dereferenced by using the `*` operator. In a pattern, such as `match` expression +branches, the `ref` keyword can be used to bind to a variable name by-reference rather than +by-value. A recursive definition of equality using references is as follows: + +~~~ +# enum List { +# Cons(u32, ~List), +# Nil +# } +fn eq(xs: &List, ys: &List) -> bool { + // Match on the next node in both lists. + match (xs, ys) { + // If we have reached the end of both lists, they are equal. + (&Nil, &Nil) => true, + // If the current element in both lists is equal, keep going. + (&Cons(x, ~ref next_xs), &Cons(y, ~ref next_ys)) if x == y => eq(next_xs, next_ys), + // If the current elements are not equal, the lists are not equal. + _ => false + } +} + +let xs = Cons(5, ~Cons(10, ~Nil)); +let ys = Cons(5, ~Cons(10, ~Nil)); +assert!(eq(&xs, &ys)); +~~~ + +Note that Rust doesn't guarantee [tail-call](http://en.wikipedia.org/wiki/Tail_call) optimization, +but LLVM is able to handle a simple case like this with optimizations enabled. + +## Lists of other types + +Our `List` type is currently always a list of 32-bit unsigned integers. By +leveraging Rust's support for generics, it can be extended to work for any +element type. + +The `u32` in the previous definition can be substituted with a type parameter: + +~~~ +enum List<T> { + Cons(T, ~List<T>), + Nil +} +~~~ + +The old `List` of `u32` is now available as `List<u32>`. The `prepend` +definition has to be updated too: + +~~~ +# enum List<T> { +# Cons(T, ~List<T>), +# Nil +# } +fn prepend<T>(xs: List<T>, value: T) -> List<T> { + Cons(value, ~xs) +} +~~~ + +Generic functions and types like this are equivalent to defining specialized +versions for each set of type parameters. + +Using the generic `List<T>` works much like before, thanks to type inference: + +~~~ +# enum List<T> { +# Cons(T, ~List<T>), +# Nil +# } +# fn prepend<T>(xs: List<T>, value: T) -> List<T> { +# Cons(value, ~xs) +# } +let mut xs = Nil; // Unknown type! This is a `List<T>`, but `T` can be anything. +xs = prepend(xs, 10); // The compiler infers the type of `xs` as `List<int>` from this. +xs = prepend(xs, 15); +xs = prepend(xs, 20); +~~~ + +The code sample above demonstrates type inference making most type annotations optional. It is +equivalent to the following type-annotated code: + +~~~ +# enum List<T> { +# Cons(T, ~List<T>), +# Nil +# } +# fn prepend<T>(xs: List<T>, value: T) -> List<T> { +# Cons(value, ~xs) +# } +let mut xs: List<int> = Nil::<int>; +xs = prepend::<int>(xs, 10); +xs = prepend::<int>(xs, 15); +xs = prepend::<int>(xs, 20); +~~~ + +In declarations, the language uses `Type<T, U, V>` to describe a list of type +parameters, but expressions use `identifier::<T, U, V>`, to disambiguate the +`<` operator. + +## Defining list equality with generics + +Generic functions are type-checked from the definition, so any necessary properties of the type must +be specified up-front. Our previous definition of list equality relied on the element type having +the `==` operator available, and took advantage of the lack of a destructor on `u32` to copy it +without a move of ownership. + +We can add a *trait bound* on the `Eq` trait to require that the type implement the `==` operator. +Two more `ref` annotations need to be added to avoid attempting to move out the element types: + +~~~ +# enum List<T> { +# Cons(T, ~List<T>), +# Nil +# } +fn eq<T: Eq>(xs: &List<T>, ys: &List<T>) -> bool { + // Match on the next node in both lists. + match (xs, ys) { + // If we have reached the end of both lists, they are equal. + (&Nil, &Nil) => true, + // If the current element in both lists is equal, keep going. + (&Cons(ref x, ~ref next_xs), &Cons(ref y, ~ref next_ys)) if x == y => eq(next_xs, next_ys), + // If the current elements are not equal, the lists are not equal. + _ => false + } +} + +let xs = Cons('c', ~Cons('a', ~Cons('t', ~Nil))); +let ys = Cons('c', ~Cons('a', ~Cons('t', ~Nil))); +assert!(eq(&xs, &ys)); +~~~ + +This would be a good opportunity to implement the `Eq` trait for our list type, making the `==` and +`!=` operators available. We'll need to provide an `impl` for the `Eq` trait and a definition of the +`eq` method. In a method, the `self` parameter refers to an instance of the type we're implementing +on. + +~~~ +# enum List<T> { +# Cons(T, ~List<T>), +# Nil +# } +impl<T: Eq> Eq for List<T> { + fn eq(&self, ys: &List<T>) -> bool { + // Match on the next node in both lists. + match (self, ys) { + // If we have reached the end of both lists, they are equal. + (&Nil, &Nil) => true, + // If the current element in both lists is equal, keep going. + (&Cons(ref x, ~ref next_xs), &Cons(ref y, ~ref next_ys)) if x == y => next_xs == next_ys, + // If the current elements are not equal, the lists are not equal. + _ => false + } + } +} + +let xs = Cons(5, ~Cons(10, ~Nil)); +let ys = Cons(5, ~Cons(10, ~Nil)); +assert!(xs.eq(&ys)); +assert!(xs == ys); +assert!(!xs.ne(&ys)); +assert!(!(xs != ys)); +~~~ + +# More on boxes + +The most common use case for owned boxes is creating recursive data structures +like a binary search tree. Rust's trait-based generics system (covered later in +the tutorial) is usually used for static dispatch, but also provides dynamic +dispatch via boxing. Values of different types may have different sizes, but a +box is able to *erase* the difference via the layer of indirection they +provide. + +In uncommon cases, the indirection can provide a performance gain or memory +reduction by making values smaller. However, unboxed values should almost +always be preferred when they are usable. + +Note that returning large unboxed values via boxes is unnecessary. A large +value is returned via a hidden output parameter, and the decision on where to +place the return value should be left to the caller: + +~~~~ +fn foo() -> (u64, u64, u64, u64, u64, u64) { + (5, 5, 5, 5, 5, 5) +} + +let x = ~foo(); // allocates a `~` box, and writes the integers directly to it +~~~~ + +Beyond the properties granted by the size, an owned box behaves as a regular +value by inheriting the mutability and lifetime of the owner: + +~~~~ +let x = 5; // immutable +let mut y = 5; // mutable +y += 2; + +let x = ~5; // immutable +let mut y = ~5; // mutable +*y += 2; // the `*` operator is needed to access the contained value +~~~~ + +# References + +In contrast with +owned boxes, where the holder of an owned box is the owner of the pointed-to +memory, references never imply ownership - they are "borrowed". +A reference can be borrowed to +any object, and the compiler verifies that it cannot outlive the lifetime of +the object. + +As an example, consider a simple struct type, `Point`: + +~~~ +struct Point { + x: f64, + y: f64 +} +~~~~ + +We can use this simple definition to allocate points in many different +ways. For example, in this code, each of these three local variables +contains a point, but allocated in a different location: + +~~~ +# struct Point { x: f64, y: f64 } +let on_the_stack : Point = Point { x: 3.0, y: 4.0 }; +let managed_box : @Point = @Point { x: 5.0, y: 1.0 }; +let owned_box : ~Point = ~Point { x: 7.0, y: 9.0 }; +~~~ + +Suppose we want to write a procedure that computes the distance +between any two points, no matter where they are stored. For example, +we might like to compute the distance between `on_the_stack` and +`managed_box`, or between `managed_box` and `owned_box`. One option is +to define a function that takes two arguments of type point—that is, +it takes the points by value. But this will cause the points to be +copied when we call the function. For points, this is probably not so +bad, but often copies are expensive. So we’d like to define a function +that takes the points by pointer. We can use references to do this: + +~~~ +# struct Point { x: f64, y: f64 } +# fn sqrt(f: f64) -> f64 { 0.0 } +fn compute_distance(p1: &Point, p2: &Point) -> f64 { + let x_d = p1.x - p2.x; + let y_d = p1.y - p2.y; + sqrt(x_d * x_d + y_d * y_d) +} +~~~ + +Now we can call `compute_distance()` in various ways: + +~~~ +# struct Point{ x: f64, y: f64 }; +# let on_the_stack : Point = Point { x: 3.0, y: 4.0 }; +# let managed_box : @Point = @Point { x: 5.0, y: 1.0 }; +# let owned_box : ~Point = ~Point { x: 7.0, y: 9.0 }; +# fn compute_distance(p1: &Point, p2: &Point) -> f64 { 0.0 } +compute_distance(&on_the_stack, managed_box); +compute_distance(managed_box, owned_box); +~~~ + +Here the `&` operator is used to take the address of the variable +`on_the_stack`; this is because `on_the_stack` has the type `Point` +(that is, a struct value) and we have to take its address to get a +reference. We also call this _borrowing_ the local variable +`on_the_stack`, because we are creating an alias: that is, another +route to the same data. + +In the case of the boxes `managed_box` and `owned_box`, however, no +explicit action is necessary. The compiler will automatically convert +a box like `@point` or `~point` to a reference like +`&point`. This is another form of borrowing; in this case, the +contents of the managed/owned box are being lent out. + +Whenever a value is borrowed, there are some limitations on what you +can do with the original. For example, if the contents of a variable +have been lent out, you cannot send that variable to another task, nor +will you be permitted to take actions that might cause the borrowed +value to be freed or to change its type. This rule should make +intuitive sense: you must wait for a borrowed value to be returned +(that is, for the reference to go out of scope) before you can +make full use of it again. + +For a more in-depth explanation of references and lifetimes, read the +[references and lifetimes guide][lifetimes]. + +## Freezing + +Lending an immutable pointer to an object freezes it and prevents mutation. +`Freeze` objects have freezing enforced statically at compile-time. An example +of a non-`Freeze` type is [`RefCell<T>`][refcell]. + +~~~~ +let mut x = 5; +{ + let y = &x; // `x` is now frozen, it cannot be modified +} +// `x` is now unfrozen again +# x = 3; +~~~~ + +[refcell]: http://static.rust-lang.org/doc/master/std/cell/struct.RefCell.html + +# Dereferencing pointers + +Rust uses the unary star operator (`*`) to access the contents of a +box or pointer, similarly to C. + +~~~ +let managed = @10; +let owned = ~20; +let borrowed = &30; + +let sum = *managed + *owned + *borrowed; +~~~ + +Dereferenced mutable pointers may appear on the left hand side of +assignments. Such an assignment modifies the value that the pointer +points to. + +~~~ +let managed = @10; +let mut owned = ~20; + +let mut value = 30; +let borrowed = &mut value; + +*owned = *borrowed + 100; +*borrowed = *managed + 1000; +~~~ + +Pointers have high operator precedence, but lower precedence than the +dot operator used for field and method access. This precedence order +can sometimes make code awkward and parenthesis-filled. + +~~~ +# struct Point { x: f64, y: f64 } +# enum Shape { Rectangle(Point, Point) } +# impl Shape { fn area(&self) -> int { 0 } } +let start = @Point { x: 10.0, y: 20.0 }; +let end = ~Point { x: (*start).x + 100.0, y: (*start).y + 100.0 }; +let rect = &Rectangle(*start, *end); +let area = (*rect).area(); +~~~ + +To combat this ugliness the dot operator applies _automatic pointer +dereferencing_ to the receiver (the value on the left-hand side of the +dot), so in most cases, explicitly dereferencing the receiver is not necessary. + +~~~ +# struct Point { x: f64, y: f64 } +# enum Shape { Rectangle(Point, Point) } +# impl Shape { fn area(&self) -> int { 0 } } +let start = @Point { x: 10.0, y: 20.0 }; +let end = ~Point { x: start.x + 100.0, y: start.y + 100.0 }; +let rect = &Rectangle(*start, *end); +let area = rect.area(); +~~~ + +You can write an expression that dereferences any number of pointers +automatically. For example, if you feel inclined, you could write +something silly like + +~~~ +# struct Point { x: f64, y: f64 } +let point = &@~Point { x: 10.0, y: 20.0 }; +println!("{:f}", point.x); +~~~ + +The indexing operator (`[]`) also auto-dereferences. + +# Vectors and strings + +A vector is a contiguous block of memory containing zero or more values of the +same type. Rust also supports vector reference types, called slices, which are +a view into a block of memory represented as a pointer and a length. + +Strings are represented as vectors of `u8`, with the guarantee of containing a +valid UTF-8 sequence. + +Fixed-size vectors are an unboxed block of memory, with the element length as +part of the type. A fixed-size vector owns the elements it contains, so the +elements are mutable if the vector is mutable. Fixed-size strings do not exist. + +~~~ +// A fixed-size vector +let numbers = [1, 2, 3]; +let more_numbers = numbers; + +// The type of a fixed-size vector is written as `[Type, ..length]` +let five_zeroes: [int, ..5] = [0, ..5]; +~~~ + +A unique vector is dynamically sized, and has a destructor to clean up +allocated memory on the heap. A unique vector owns the elements it contains, so +the elements are mutable if the vector is mutable. + +~~~ +// A dynamically sized vector (unique vector) +let mut numbers = ~[1, 2, 3]; +numbers.push(4); +numbers.push(5); + +// The type of a unique vector is written as `~[int]` +let more_numbers: ~[int] = numbers; + +// The original `numbers` value can no longer be used, due to move semantics. + +let mut string = ~"fo"; +string.push_char('o'); +~~~ + +Slices are similar to fixed-size vectors, but the length is not part of the +type. They simply point into a block of memory and do not have ownership over +the elements. + +~~~ +// A slice +let xs = &[1, 2, 3]; + +// Slices have their type written as `&[int]` +let ys: &[int] = xs; + +// Other vector types coerce to slices +let three = [1, 2, 3]; +let zs: &[int] = three; + +// An unadorned string literal is an immutable string slice +let string = "foobar"; + +// A string slice type is written as `&str` +let view: &str = string.slice(0, 3); +~~~ + +Mutable slices also exist, just as there are mutable references. However, there +are no mutable string slices. Strings are a multi-byte encoding (UTF-8) of +Unicode code points, so they cannot be freely mutated without the ability to +alter the length. + +~~~ +let mut xs = [1, 2, 3]; +let view = xs.mut_slice(0, 2); +view[0] = 5; + +// The type of a mutable slice is written as `&mut [T]` +let ys: &mut [int] = &mut [1, 2, 3]; +~~~ + +Square brackets denote indexing into a vector: + +~~~~ +# enum Crayon { Almond, AntiqueBrass, Apricot, +# Aquamarine, Asparagus, AtomicTangerine, +# BananaMania, Beaver, Bittersweet }; +# fn draw_scene(c: Crayon) { } +let crayons: [Crayon, ..3] = [BananaMania, Beaver, Bittersweet]; +match crayons[0] { + Bittersweet => draw_scene(crayons[0]), + _ => () +} +~~~~ + +A vector can be destructured using pattern matching: + +~~~~ +let numbers: &[int] = &[1, 2, 3]; +let score = match numbers { + [] => 0, + [a] => a * 10, + [a, b] => a * 6 + b * 4, + [a, b, c, ..rest] => a * 5 + b * 3 + c * 2 + rest.len() as int +}; +~~~~ + +Both vectors and strings support a number of useful [methods](#methods), +defined in [`std::vec`] and [`std::str`]. + +[`std::vec`]: std/vec/index.html +[`std::str`]: std/str/index.html + +# Ownership escape hatches + +Ownership can cleanly describe tree-like data structures, and references provide non-owning pointers. However, more flexibility is often desired and Rust provides ways to escape from strict +single parent ownership. + +The standard library provides the `std::rc::Rc` pointer type to express *shared ownership* over a +reference counted box. As soon as all of the `Rc` pointers go out of scope, the box and the +contained value are destroyed. + +~~~ +use std::rc::Rc; + +// A fixed-size array allocated in a reference-counted box +let x = Rc::new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); +let y = x.clone(); // a new owner +let z = x; // this moves `x` into `z`, rather than creating a new owner + +assert_eq!(*z.borrow(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + +// the variable is mutable, but not the contents of the box +let mut a = Rc::new([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]); +a = z; +~~~ + +A garbage collected pointer is provided via `std::gc::Gc`, with a task-local garbage collector +having ownership of the box. It allows the creation of cycles, and the individual `Gc` pointers do +not have a destructor. + +~~~ +use std::gc::Gc; + +// A fixed-size array allocated in a garbage-collected box +let x = Gc::new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); +let y = x; // does not perform a move, unlike with `Rc` +let z = x; + +assert_eq!(*z.borrow(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); +~~~ + +With shared ownership, mutability cannot be inherited so the boxes are always immutable. However, +it's possible to use *dynamic* mutability via types like `std::cell::Cell` where freezing is handled +via dynamic checks and can fail at runtime. + +The `Rc` and `Gc` types are not sendable, so they cannot be used to share memory between tasks. Safe +immutable and mutable shared memory is provided by the `extra::arc` module. + +# Closures + +Named functions, like those we've seen so far, may not refer to local +variables declared outside the function: they do not close over their +environment (sometimes referred to as "capturing" variables in their +environment). For example, you couldn't write the following: + +~~~~ {.ignore} +let foo = 10; + +fn bar() -> int { + return foo; // `bar` cannot refer to `foo` +} +~~~~ + +Rust also supports _closures_, functions that can access variables in +the enclosing scope. + +~~~~ +fn call_closure_with_ten(b: |int|) { b(10); } + +let captured_var = 20; +let closure = |arg| println!("captured_var={}, arg={}", captured_var, arg); + +call_closure_with_ten(closure); +~~~~ + +Closures begin with the argument list between vertical bars and are followed by +a single expression. Remember that a block, `{ <expr1>; <expr2>; ... }`, is +considered a single expression: it evaluates to the result of the last +expression it contains if that expression is not followed by a semicolon, +otherwise the block evaluates to `()`. + +The types of the arguments are generally omitted, as is the return type, +because the compiler can almost always infer them. In the rare case where the +compiler needs assistance, though, the arguments and return types may be +annotated. + +~~~~ +let square = |x: int| -> uint { (x * x) as uint }; +~~~~ + +There are several forms of closure, each with its own role. The most +common, called a _stack closure_, has type `||` and can directly +access local variables in the enclosing scope. + +~~~~ +let mut max = 0; +[1, 2, 3].map(|x| if *x > max { max = *x }); +~~~~ + +Stack closures are very efficient because their environment is +allocated on the call stack and refers by pointer to captured +locals. To ensure that stack closures never outlive the local +variables to which they refer, stack closures are not +first-class. That is, they can only be used in argument position; they +cannot be stored in data structures or returned from +functions. Despite these limitations, stack closures are used +pervasively in Rust code. + +## Owned closures + +Owned closures, written `proc`, +hold on to things that can safely be sent between +processes. They copy the values they close over, much like managed +closures, but they also own them: that is, no other code can access +them. Owned closures are used in concurrent code, particularly +for spawning [tasks][tasks]. + +## Closure compatibility + +Rust closures have a convenient subtyping property: you can pass any kind of +closure (as long as the arguments and return types match) to functions +that expect a `||`. Thus, when writing a higher-order function that +only calls its function argument, and does nothing else with it, you +should almost always declare the type of that argument as `||`. That way, +callers may pass any kind of closure. + +~~~~ +fn call_twice(f: ||) { f(); f(); } +let closure = || { "I'm a closure, and it doesn't matter what type I am"; }; +fn function() { "I'm a normal function"; } +call_twice(closure); +call_twice(function); +~~~~ + +> ***Note:*** Both the syntax and the semantics will be changing +> in small ways. At the moment they can be unsound in some +> scenarios, particularly with non-copyable types. + +## Do syntax + +The `do` expression makes it easier to call functions that take procedures +as arguments. + +Consider this function that takes a procedure: + +~~~~ +fn call_it(op: proc(v: int)) { + op(10) +} +~~~~ + +As a caller, if we use a closure to provide the final operator +argument, we can write it in a way that has a pleasant, block-like +structure. + +~~~~ +# fn call_it(op: proc(v: int)) { } +call_it(proc(n) { + println!("{}", n); +}); +~~~~ + +A practical example of this pattern is found when using the `spawn` function, +which starts a new task. + +~~~~ +use std::task::spawn; +spawn(proc() { + debug!("I'm a new task") +}); +~~~~ + +If you want to see the output of `debug!` statements, you will need to turn on +`debug!` logging. To enable `debug!` logging, set the RUST_LOG environment +variable to the name of your crate, which, for a file named `foo.rs`, will be +`foo` (e.g., with bash, `export RUST_LOG=foo`). + +# Methods + +Methods are like functions except that they always begin with a special argument, +called `self`, +which has the type of the method's receiver. The +`self` argument is like `this` in C++ and many other languages. +Methods are called with dot notation, as in `my_vec.len()`. + +_Implementations_, written with the `impl` keyword, can define +methods on most Rust types, including structs and enums. +As an example, let's define a `draw` method on our `Shape` enum. + +~~~ +# fn draw_circle(p: Point, f: f64) { } +# fn draw_rectangle(p: Point, p: Point) { } +struct Point { + x: f64, + y: f64 +} + +enum Shape { + Circle(Point, f64), + Rectangle(Point, Point) +} + +impl Shape { + fn draw(&self) { + match *self { + Circle(p, f) => draw_circle(p, f), + Rectangle(p1, p2) => draw_rectangle(p1, p2) + } + } +} + +let s = Circle(Point { x: 1.0, y: 2.0 }, 3.0); +s.draw(); +~~~ + +This defines an _implementation_ for `Shape` containing a single +method, `draw`. In most respects the `draw` method is defined +like any other function, except for the name `self`. + +The type of `self` is the type on which the method is implemented, +or a pointer thereof. As an argument it is written either `self`, +`&self`, `@self`, or `~self`. +A caller must in turn have a compatible pointer type to call the method. + +~~~ +# fn draw_circle(p: Point, f: f64) { } +# fn draw_rectangle(p: Point, p: Point) { } +# struct Point { x: f64, y: f64 } +# enum Shape { +# Circle(Point, f64), +# Rectangle(Point, Point) +# } +impl Shape { + fn draw_reference(&self) { ... } + fn draw_managed(@self) { ... } + fn draw_owned(~self) { ... } + fn draw_value(self) { ... } +} + +let s = Circle(Point { x: 1.0, y: 2.0 }, 3.0); + +(@s).draw_managed(); +(~s).draw_owned(); +(&s).draw_reference(); +s.draw_value(); +~~~ + +Methods typically take a reference self type, +so the compiler will go to great lengths to convert a callee +to a reference. + +~~~ +# fn draw_circle(p: Point, f: f64) { } +# fn draw_rectangle(p: Point, p: Point) { } +# struct Point { x: f64, y: f64 } +# enum Shape { +# Circle(Point, f64), +# Rectangle(Point, Point) +# } +# impl Shape { +# fn draw_reference(&self) { ... } +# fn draw_managed(@self) { ... } +# fn draw_owned(~self) { ... } +# fn draw_value(self) { ... } +# } +# let s = Circle(Point { x: 1.0, y: 2.0 }, 3.0); +// As with typical function arguments, managed and owned pointers +// are automatically converted to references + +(@s).draw_reference(); +(~s).draw_reference(); + +// Unlike typical function arguments, the self value will +// automatically be referenced ... +s.draw_reference(); + +// ... and dereferenced +(& &s).draw_reference(); + +// ... and dereferenced and borrowed +(&@~s).draw_reference(); +~~~ + +Implementations may also define standalone (sometimes called "static") +methods. The absence of a `self` parameter distinguishes such methods. +These methods are the preferred way to define constructor functions. + +~~~~ {.ignore} +impl Circle { + fn area(&self) -> f64 { ... } + fn new(area: f64) -> Circle { ... } +} +~~~~ + +To call such a method, just prefix it with the type name and a double colon: + +~~~~ +use std::f64::consts::PI; +struct Circle { radius: f64 } +impl Circle { + fn new(area: f64) -> Circle { Circle { radius: (area / PI).sqrt() } } +} +let c = Circle::new(42.5); +~~~~ + +# Generics + +Throughout this tutorial, we've been defining functions that act only +on specific data types. With type parameters we can also define +functions whose arguments have generic types, and which can be invoked +with a variety of types. Consider a generic `map` function, which +takes a function `function` and a vector `vector` and returns a new +vector consisting of the result of applying `function` to each element +of `vector`: + +~~~~ +fn map<T, U>(vector: &[T], function: |v: &T| -> U) -> ~[U] { + let mut accumulator = ~[]; + for element in vector.iter() { + accumulator.push(function(element)); + } + return accumulator; +} +~~~~ + +When defined with type parameters, as denoted by `<T, U>`, this +function can be applied to any type of vector, as long as the type of +`function`'s argument and the type of the vector's contents agree with +each other. + +Inside a generic function, the names of the type parameters +(capitalized by convention) stand for opaque types. All you can do +with instances of these types is pass them around: you can't apply any +operations to them or pattern-match on them. Note that instances of +generic types are often passed by pointer. For example, the parameter +`function()` is supplied with a pointer to a value of type `T` and not +a value of type `T` itself. This ensures that the function works with +the broadest set of types possible, since some types are expensive or +illegal to copy and pass by value. + +Generic `type`, `struct`, and `enum` declarations follow the same pattern: + +~~~~ +use std::hashmap::HashMap; +type Set<T> = HashMap<T, ()>; + +struct Stack<T> { + elements: ~[T] +} + +enum Option<T> { + Some(T), + None +} +~~~~ + +These declarations can be instantiated to valid types like `Set<int>`, +`Stack<int>`, and `Option<int>`. + +The last type in that example, `Option`, appears frequently in Rust code. +Because Rust does not have null pointers (except in unsafe code), we need +another way to write a function whose result isn't defined on every possible +combination of arguments of the appropriate types. The usual way is to write +a function that returns `Option<T>` instead of `T`. + +~~~~ +# struct Point { x: f64, y: f64 } +# enum Shape { Circle(Point, f64), Rectangle(Point, Point) } +fn radius(shape: Shape) -> Option<f64> { + match shape { + Circle(_, radius) => Some(radius), + Rectangle(..) => None + } +} +~~~~ + +The Rust compiler compiles generic functions very efficiently by +*monomorphizing* them. *Monomorphization* is a fancy name for a simple +idea: generate a separate copy of each generic function at each call site, +a copy that is specialized to the argument +types and can thus be optimized specifically for them. In this +respect, Rust's generics have similar performance characteristics to +C++ templates. + +## Traits + +Within a generic function -- that is, a function parameterized by a +type parameter, say, `T` -- the operations we can do on arguments of +type `T` are quite limited. After all, since we don't know what type +`T` will be instantiated with, we can't safely modify or query values +of type `T`. This is where _traits_ come into play. Traits are Rust's +most powerful tool for writing polymorphic code. Java developers will +see them as similar to Java interfaces, and Haskellers will notice +their similarities to type classes. Rust's traits give us a way to +express *bounded polymorphism*: by limiting the set of possible types +that a type parameter could refer to, they expand the number of +operations we can safely perform on arguments of that type. + +As motivation, let us consider copying of values in Rust. The `clone` +method is not defined for values of every type. One reason is +user-defined destructors: copying a value of a type that has a +destructor could result in the destructor running multiple times. +Therefore, values of types that have destructors cannot be copied +unless we explicitly implement `clone` for them. + +This complicates handling of generic functions. +If we have a function with a type parameter `T`, +can we copy values of type `T` inside that function? +In Rust, we can't, +and if we try to run the following code the compiler will complain. + +~~~~ {.ignore} +// This does not compile +fn head_bad<T>(v: &[T]) -> T { + v[0] // error: copying a non-copyable value +} +~~~~ + +However, we can tell the compiler +that the `head` function is only for copyable types. +In Rust, copyable types are those that _implement the `Clone` trait_. +We can then explicitly create a second copy of the value we are returning +by calling the `clone` method: + +~~~~ +// This does +fn head<T: Clone>(v: &[T]) -> T { + v[0].clone() +} +~~~~ + +The bounded type parameter `T: Clone` says that `head` +can be called on an argument of type `&[T]` for any `T`, +so long as there is an implementation of the +`Clone` trait for `T`. +When instantiating a generic function, +we can only instantiate it with types +that implement the correct trait, +so we could not apply `head` to a vector whose elements are of some type +that does not implement `Clone`. + +While most traits can be defined and implemented by user code, +three traits are automatically derived and implemented +for all applicable types by the compiler, +and may not be overridden: + +* `Send` - Sendable types. +Types are sendable +unless they contain managed boxes, managed closures, or references. + +* `Freeze` - Constant (immutable) types. +These are types that do not contain anything intrinsically mutable. +Intrinsically mutable values include `Cell` in the standard library. + +* `'static` - Non-borrowed types. +These are types that do not contain any data whose lifetime is bound to +a particular stack frame. These are types that do not contain any +references, or types where the only contained references +have the `'static` lifetime. + +> ***Note:*** These two traits were referred to as 'kinds' in earlier +> iterations of the language, and often still are. + +Additionally, the `Drop` trait is used to define destructors. This +trait provides one method called `drop`, which is automatically +called when a value of the type that implements this trait is +destroyed, either because the value went out of scope or because the +garbage collector reclaimed it. + +~~~ +struct TimeBomb { + explosivity: uint +} + +impl Drop for TimeBomb { + fn drop(&mut self) { + for _ in range(0, self.explosivity) { + println!("blam!"); + } + } +} +~~~ + +It is illegal to call `drop` directly. Only code inserted by the compiler +may call it. + +## Declaring and implementing traits + +At its simplest, a trait is a set of zero or more _method signatures_. +For example, we could declare the trait +`Printable` for things that can be printed to the console, +with a single method signature: + +~~~~ +trait Printable { + fn print(&self); +} +~~~~ + +We say that the `Printable` trait _provides_ a `print` method with the +given signature. This means that we can call `print` on an argument +of any type that implements the `Printable` trait. + +Rust's built-in `Send` and `Freeze` types are examples of traits that +don't provide any methods. + +Traits may be implemented for specific types with [impls]. An impl for +a particular trait gives an implementation of the methods that +trait provides. For instance, the following impls of +`Printable` for `int` and `~str` give implementations of the `print` +method. + +[impls]: #methods + +~~~~ +# trait Printable { fn print(&self); } +impl Printable for int { + fn print(&self) { println!("{:?}", *self) } +} + +impl Printable for ~str { + fn print(&self) { println!("{}", *self) } +} + +# 1.print(); +# (~"foo").print(); +~~~~ + +Methods defined in an impl for a trait may be called just like +any other method, using dot notation, as in `1.print()`. + +## Default method implementations in trait definitions + +Sometimes, a method that a trait provides will have the same +implementation for most or all of the types that implement that trait. +For instance, suppose that we wanted `bool`s and `f32`s to be +printable, and that we wanted the implementation of `print` for those +types to be exactly as it is for `int`, above: + +~~~~ +# trait Printable { fn print(&self); } +impl Printable for f32 { + fn print(&self) { println!("{:?}", *self) } +} + +impl Printable for bool { + fn print(&self) { println!("{:?}", *self) } +} + +# true.print(); +# 3.14159.print(); +~~~~ + +This works fine, but we've now repeated the same definition of `print` +in three places. Instead of doing that, we can simply include the +definition of `print` right in the trait definition, instead of just +giving its signature. That is, we can write the following: + +~~~~ +trait Printable { + // Default method implementation + fn print(&self) { println!("{:?}", *self) } +} + +impl Printable for int {} + +impl Printable for ~str { + fn print(&self) { println!("{}", *self) } +} + +impl Printable for bool {} + +impl Printable for f32 {} + +# 1.print(); +# (~"foo").print(); +# true.print(); +# 3.14159.print(); +~~~~ + +Here, the impls of `Printable` for `int`, `bool`, and `f32` don't +need to provide an implementation of `print`, because in the absence +of a specific implementation, Rust just uses the _default method_ +provided in the trait definition. Depending on the trait, default +methods can save a great deal of boilerplate code from having to be +written in impls. Of course, individual impls can still override the +default method for `print`, as is being done above in the impl for +`~str`. + +## Type-parameterized traits + +Traits may be parameterized by type variables. For example, a trait +for generalized sequence types might look like the following: + +~~~~ +trait Seq<T> { + fn length(&self) -> uint; +} + +impl<T> Seq<T> for ~[T] { + fn length(&self) -> uint { self.len() } +} +~~~~ + +The implementation has to explicitly declare the type parameter that +it binds, `T`, before using it to specify its trait type. Rust +requires this declaration because the `impl` could also, for example, +specify an implementation of `Seq<int>`. The trait type (appearing +between `impl` and `for`) *refers* to a type, rather than +defining one. + +The type parameters bound by a trait are in scope in each of the +method declarations. So, re-declaring the type parameter +`T` as an explicit type parameter for `len`, in either the trait or +the impl, would be a compile-time error. + +Within a trait definition, `Self` is a special type that you can think +of as a type parameter. An implementation of the trait for any given +type `T` replaces the `Self` type parameter with `T`. The following +trait describes types that support an equality operation: + +~~~~ +// In a trait, `self` refers to the self argument. +// `Self` refers to the type implementing the trait. +trait Eq { + fn equals(&self, other: &Self) -> bool; +} + +// In an impl, `self` refers just to the value of the receiver +impl Eq for int { + fn equals(&self, other: &int) -> bool { *other == *self } +} +~~~~ + +Notice that in the trait definition, `equals` takes a +second parameter of type `Self`. +In contrast, in the `impl`, `equals` takes a second parameter of +type `int`, only using `self` as the name of the receiver. + +Just as in type implementations, traits can define standalone (static) +methods. These methods are called by prefixing the method name with the trait +name and a double colon. The compiler uses type inference to decide which +implementation to use. + +~~~~ +use std::f64::consts::PI; +trait Shape { fn new(area: f64) -> Self; } +struct Circle { radius: f64 } +struct Square { length: f64 } + +impl Shape for Circle { + fn new(area: f64) -> Circle { Circle { radius: (area / PI).sqrt() } } +} +impl Shape for Square { + fn new(area: f64) -> Square { Square { length: (area).sqrt() } } +} + +let area = 42.5; +let c: Circle = Shape::new(area); +let s: Square = Shape::new(area); +~~~~ + +## Bounded type parameters and static method dispatch + +Traits give us a language for defining predicates on types, or +abstract properties that types can have. We can use this language to +define _bounds_ on type parameters, so that we can then operate on +generic types. + +~~~~ +# trait Printable { fn print(&self); } +fn print_all<T: Printable>(printable_things: ~[T]) { + for thing in printable_things.iter() { + thing.print(); + } +} +~~~~ + +Declaring `T` as conforming to the `Printable` trait (as we earlier +did with `Clone`) makes it possible to call methods from that trait +on values of type `T` inside the function. It will also cause a +compile-time error when anyone tries to call `print_all` on an array +whose element type does not have a `Printable` implementation. + +Type parameters can have multiple bounds by separating them with `+`, +as in this version of `print_all` that copies elements. + +~~~ +# trait Printable { fn print(&self); } +fn print_all<T: Printable + Clone>(printable_things: ~[T]) { + let mut i = 0; + while i < printable_things.len() { + let copy_of_thing = printable_things[i].clone(); + copy_of_thing.print(); + i += 1; + } +} +~~~ + +Method calls to bounded type parameters are _statically dispatched_, +imposing no more overhead than normal function invocation, so are +the preferred way to use traits polymorphically. + +This usage of traits is similar to Haskell type classes. + +## Trait objects and dynamic method dispatch + +The above allows us to define functions that polymorphically act on +values of a single unknown type that conforms to a given trait. +However, consider this function: + +~~~~ +# type Circle = int; type Rectangle = int; +# impl Drawable for int { fn draw(&self) {} } +# fn new_circle() -> int { 1 } +trait Drawable { fn draw(&self); } + +fn draw_all<T: Drawable>(shapes: ~[T]) { + for shape in shapes.iter() { shape.draw(); } +} +# let c: Circle = new_circle(); +# draw_all(~[c]); +~~~~ + +You can call that on an array of circles, or an array of rectangles +(assuming those have suitable `Drawable` traits defined), but not on +an array containing both circles and rectangles. When such behavior is +needed, a trait name can alternately be used as a type, called +an _object_. + +~~~~ +# trait Drawable { fn draw(&self); } +fn draw_all(shapes: &[@Drawable]) { + for shape in shapes.iter() { shape.draw(); } +} +~~~~ + +In this example, there is no type parameter. Instead, the `@Drawable` +type denotes any managed box value that implements the `Drawable` +trait. To construct such a value, you use the `as` operator to cast a +value to an object: + +~~~~ +# type Circle = int; type Rectangle = bool; +# trait Drawable { fn draw(&self); } +# fn new_circle() -> Circle { 1 } +# fn new_rectangle() -> Rectangle { true } +# fn draw_all(shapes: &[@Drawable]) {} + +impl Drawable for Circle { fn draw(&self) { ... } } +impl Drawable for Rectangle { fn draw(&self) { ... } } + +let c: @Circle = @new_circle(); +let r: @Rectangle = @new_rectangle(); +draw_all([c as @Drawable, r as @Drawable]); +~~~~ + +We omit the code for `new_circle` and `new_rectangle`; imagine that +these just return `Circle`s and `Rectangle`s with a default size. Note +that, like strings and vectors, objects have dynamic size and may +only be referred to via one of the pointer types. +Other pointer types work as well. +Casts to traits may only be done with compatible pointers so, +for example, an `@Circle` may not be cast to an `~Drawable`. + +~~~ +# type Circle = int; type Rectangle = int; +# trait Drawable { fn draw(&self); } +# impl Drawable for int { fn draw(&self) {} } +# fn new_circle() -> int { 1 } +# fn new_rectangle() -> int { 2 } +// A managed object +let boxy: @Drawable = @new_circle() as @Drawable; +// An owned object +let owny: ~Drawable = ~new_circle() as ~Drawable; +// A borrowed object +let stacky: &Drawable = &new_circle() as &Drawable; +~~~ + +Method calls to trait types are _dynamically dispatched_. Since the +compiler doesn't know specifically which functions to call at compile +time, it uses a lookup table (also known as a vtable or dictionary) to +select the method to call at runtime. + +This usage of traits is similar to Java interfaces. + +By default, each of the three storage classes for traits enforce a +particular set of built-in kinds that their contents must fulfill in +order to be packaged up in a trait object of that storage class. + +* The contents of owned traits (`~Trait`) must fulfill the `Send` bound. +* The contents of managed traits (`@Trait`) must fulfill the `'static` bound. +* The contents of reference traits (`&Trait`) are not constrained by any bound. + +Consequently, the trait objects themselves automatically fulfill their +respective kind bounds. However, this default behavior can be overridden by +specifying a list of bounds on the trait type, for example, by writing `~Trait:` +(which indicates that the contents of the owned trait need not fulfill any +bounds), or by writing `~Trait:Send+Freeze`, which indicates that in addition +to fulfilling `Send`, contents must also fulfill `Freeze`, and as a consequence, +the trait itself fulfills `Freeze`. + +* `~Trait:Send` is equivalent to `~Trait`. +* `@Trait:'static` is equivalent to `@Trait`. +* `&Trait:` is equivalent to `&Trait`. + +Builtin kind bounds can also be specified on closure types in the same way (for +example, by writing `fn:Freeze()`), and the default behaviours are the same as +for traits of the same storage class. + +## Trait inheritance + +We can write a trait declaration that _inherits_ from other traits, called _supertraits_. +Types that implement a trait must also implement its supertraits. +For example, +we can define a `Circle` trait that inherits from `Shape`. + +~~~~ +trait Shape { fn area(&self) -> f64; } +trait Circle : Shape { fn radius(&self) -> f64; } +~~~~ + +Now, we can implement `Circle` on a type only if we also implement `Shape`. + +~~~~ +use std::f64::consts::PI; +# trait Shape { fn area(&self) -> f64; } +# trait Circle : Shape { fn radius(&self) -> f64; } +# struct Point { x: f64, y: f64 } +# fn square(x: f64) -> f64 { x * x } +struct CircleStruct { center: Point, radius: f64 } +impl Circle for CircleStruct { + fn radius(&self) -> f64 { (self.area() / PI).sqrt() } +} +impl Shape for CircleStruct { + fn area(&self) -> f64 { PI * square(self.radius) } +} +~~~~ + +Notice that methods of `Circle` can call methods on `Shape`, as our +`radius` implementation calls the `area` method. +This is a silly way to compute the radius of a circle +(since we could just return the `radius` field), but you get the idea. + +In type-parameterized functions, +methods of the supertrait may be called on values of subtrait-bound type parameters. +Refering to the previous example of `trait Circle : Shape`: + +~~~ +# trait Shape { fn area(&self) -> f64; } +# trait Circle : Shape { fn radius(&self) -> f64; } +fn radius_times_area<T: Circle>(c: T) -> f64 { + // `c` is both a Circle and a Shape + c.radius() * c.area() +} +~~~ + +Likewise, supertrait methods may also be called on trait objects. + +~~~ {.ignore} +use std::f64::consts::PI; +# trait Shape { fn area(&self) -> f64; } +# trait Circle : Shape { fn radius(&self) -> f64; } +# struct Point { x: f64, y: f64 } +# struct CircleStruct { center: Point, radius: f64 } +# impl Circle for CircleStruct { fn radius(&self) -> f64 { (self.area() / PI).sqrt() } } +# impl Shape for CircleStruct { fn area(&self) -> f64 { PI * square(self.radius) } } + +let concrete = @CircleStruct{center:Point{x:3f,y:4f},radius:5f}; +let mycircle: @Circle = concrete as @Circle; +let nonsense = mycircle.radius() * mycircle.area(); +~~~ + +> ***Note:*** Trait inheritance does not actually work with objects yet + +## Deriving implementations for traits + +A small number of traits in `std` and `extra` can have implementations +that can be automatically derived. These instances are specified by +placing the `deriving` attribute on a data type declaration. For +example, the following will mean that `Circle` has an implementation +for `Eq` and can be used with the equality operators, and that a value +of type `ABC` can be randomly generated and converted to a string: + +~~~ +#[deriving(Eq)] +struct Circle { radius: f64 } + +#[deriving(Rand, ToStr)] +enum ABC { A, B, C } +~~~ + +The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, +`TotalOrd`, `Encodable` `Decodable`, `Clone`, `DeepClone`, +`IterBytes`, `Rand`, `Default`, `Zero`, and `ToStr`. + +# Crates and the module system + +Rust's module system is very powerful, but because of that also somewhat complex. +Nevertheless, this section will try to explain every important aspect of it. + +## Crates + +In order to speak about the module system, we first need to define the medium it exists in: + +Let's say you've written a program or a library, compiled it, and got the resulting binary. +In Rust, the content of all source code that the compiler directly had to compile in order to end up with +that binary is collectively called a 'crate'. + +For example, for a simple hello world program your crate only consists of this code: + +~~~~ +// `main.rs` +fn main() { + println!("Hello world!"); +} +~~~~ + +A crate is also the unit of independent compilation in Rust: `rustc` always compiles a single crate at a time, +from which it produces either a library or an executable. + +Note that merely using an already compiled library in your code does not make it part of your crate. + +## The module hierarchy + +For every crate, all the code in it is arranged in a hierarchy of modules starting with a single +root module. That root module is called the 'crate root'. + +All modules in a crate below the crate root are declared with the `mod` keyword: + +~~~~ +// This is the crate root + +mod farm { + // This is the body of module 'farm' declared in the crate root. + + fn chicken() { println!("cluck cluck"); } + fn cow() { println!("mooo"); } + + mod barn { + // Body of module 'barn' + + fn hay() { println!("..."); } + } +} + +fn main() { + println!("Hello farm!"); +} +~~~~ + +As you can see, your module hierarchy is now three modules deep: There is the crate root, which contains your `main()` +function, and the module `farm`. The module `farm` also contains two functions and a third module `barn`, +which contains a function `hay`. + +(In case you already stumbled over `extern mod`: It isn't directly related to a bare `mod`, we'll get to it later. ) + +## Paths and visibility + +We've now defined a nice module hierarchy. But how do we access the items in it from our `main` function? +One way to do it is to simply fully qualifying it: + +~~~~ {.ignore} +mod farm { + fn chicken() { println!("cluck cluck"); } + // ... +} + +fn main() { + println!("Hello chicken!"); + + ::farm::chicken(); // Won't compile yet, see further down +} +~~~~ + +The `::farm::chicken` construct is what we call a 'path'. + +Because it's starting with a `::`, it's also a 'global path', which qualifies +an item by its full path in the module hierarchy relative to the crate root. + +If the path were to start with a regular identifier, like `farm::chicken`, it +would be a 'local path' instead. We'll get to them later. + +Now, if you actually tried to compile this code example, you'll notice that you +get a `function 'chicken' is private` error. That's because by default, items +(`fn`, `struct`, `static`, `mod`, ...) are private. + +To make them visible outside their containing modules, you need to mark them +_public_ with `pub`: + +~~~~ +mod farm { + pub fn chicken() { println!("cluck cluck"); } + pub fn cow() { println!("mooo"); } + // ... +} + +fn main() { + println!("Hello chicken!"); + ::farm::chicken(); // This compiles now +} +~~~~ + +Visibility restrictions in Rust exist only at module boundaries. This +is quite different from most object-oriented languages that also +enforce restrictions on objects themselves. That's not to say that +Rust doesn't support encapsulation: both struct fields and methods can +be private. But this encapsulation is at the module level, not the +struct level. + +For convenience, fields are _public_ by default, and can be made _private_ with +the `priv` keyword: + +~~~ +mod farm { +# pub type Chicken = int; +# struct Human(int); +# impl Human { pub fn rest(&self) { } } +# pub fn make_me_a_farm() -> Farm { Farm { chickens: ~[], farmer: Human(0) } } + pub struct Farm { + priv chickens: ~[Chicken], + farmer: Human + } + + impl Farm { + fn feed_chickens(&self) { ... } + pub fn add_chicken(&self, c: Chicken) { ... } + } + + pub fn feed_animals(farm: &Farm) { + farm.feed_chickens(); + } +} + +fn main() { + let f = make_me_a_farm(); + f.add_chicken(make_me_a_chicken()); + farm::feed_animals(&f); + f.farmer.rest(); + + // This wouldn't compile because both are private: + // `f.feed_chickens();` + // `let chicken_counter = f.chickens.len();` +} +# fn make_me_a_farm() -> farm::Farm { farm::make_me_a_farm() } +# fn make_me_a_chicken() -> farm::Chicken { 0 } +~~~ + +Exact details and specifications about visibility rules can be found in the Rust +manual. + +## Files and modules + +One important aspect about Rusts module system is that source files are not important: +You define a module hierarchy, populate it with all your definitions, define visibility, +maybe put in a `fn main()`, and that's it: No need to think about source files. + +The only file that's relevant is the one that contains the body of your crate root, +and it's only relevant because you have to pass that file to `rustc` to compile your crate. + +And in principle, that's all you need: You can write any Rust program as one giant source file that contains your +crate root and everything below it in `mod ... { ... }` declarations. + +However, in practice you usually want to split you code up into multiple source files to make it more manageable. +In order to do that, Rust allows you to move the body of any module into it's own source file, which works like this: + +If you declare a module without its body, like `mod foo;`, the compiler will look for the +files `foo.rs` and `foo/mod.rs` inside some directory (usually the same as of the source file containing +the `mod foo;`). If it finds either, it uses the content of that file as the body of the module. +If it finds both, that's a compile error. + +So, if we want to move the content of `mod farm` into it's own file, it would look like this: + +~~~~ {.ignore} +// `main.rs` - contains body of the crate root +mod farm; // Compiler will look for `farm.rs` and `farm/mod.rs` + +fn main() { + println!("Hello farm!"); + ::farm::cow(); +} +~~~~ + +~~~~ +// `farm.rs` - contains body of module 'farm' in the crate root +pub fn chicken() { println!("cluck cluck"); } +pub fn cow() { println!("mooo"); } + +pub mod barn { + pub fn hay() { println!("..."); } +} +# fn main() { } +~~~~ + +In short, `mod foo;` is just syntactic sugar for `mod foo { /* content of <...>/foo.rs or <...>/foo/mod.rs */ }`. + +This also means that having two or more identical `mod foo;` somewhere +in your crate hierarchy is generally a bad idea, +just like copy-and-paste-ing a module into two or more places is one. +Both will result in duplicate and mutually incompatible definitions. + +The directory the compiler looks in for those two files is determined by starting with +the same directory as the source file that contains the `mod foo;` declaration, and concatenating to that a +path equivalent to the relative path of all nested `mod { ... }` declarations the `mod foo;` +is contained in, if any. + +For example, given a file with this module body: + +~~~ {.ignore} +// `src/main.rs` +mod plants; +mod animals { + mod fish; + mod mammals { + mod humans; + } +} +~~~ + +The compiler would then try all these files: + +~~~ {.notrust} +src/plants.rs +src/plants/mod.rs + +src/animals/fish.rs +src/animals/fish/mod.rs + +src/animals/mammals/humans.rs +src/animals/mammals/humans/mod.rs +~~~ + +Keep in mind that identical module hierachies can still lead to different path lookups +depending on how and where you've moved a module body to its own file. +For example, if we move the `animals` module above into its own file... + +~~~ {.ignore} +// `src/main.rs` +mod plants; +mod animals; +~~~ + +~~~ {.ignore} +// `src/animals.rs` or `src/animals/mod.rs` +mod fish; +mod mammals { + mod humans; +} +~~~ + +...then the source files of `mod animals`'s submodules can +either be placed right next to that of its parents, or in a subdirectory if `animals` source file is: + +~~~ {.notrust} +src/plants.rs +src/plants/mod.rs + +src/animals.rs - if file sits next to that of parent module's: + src/fish.rs + src/fish/mod.rs + + src/mammals/humans.rs + src/mammals/humans/mod.rs + +src/animals/mod.rs - if file is in it's own subdirectory: + src/animals/fish.rs + src/animals/fish/mod.rs + + src/animals/mammals/humans.rs + src/animals/mammals/humans/mod.rs + +~~~ + +These rules allow you to have both small modules that only need +to consist of one source file each and can be conveniently placed right next to each other, +and big complicated modules that group the source files of submodules in subdirectories. + +If you need to circumvent the defaults, you can also overwrite the path a `mod foo;` would take: + +~~~ {.ignore} +#[path="../../area51/alien.rs"] +mod classified; +~~~ + +## Importing names into the local scope + +Always referring to definitions in other modules with their global +path gets old really fast, so Rust has a way to import +them into the local scope of your module: `use`-statements. + +They work like this: At the beginning of any module body, `fn` body, or any other block +you can write a list of `use`-statements, consisting of the keyword `use` and a __global path__ to an item +without the `::` prefix. For example, this imports `cow` into the local scope: + +~~~ +use farm::cow; +# mod farm { pub fn cow() { println!("I'm a hidden ninja cow!") } } +# fn main() { cow() } +~~~ + +The path you give to `use` is per default global, meaning relative to the crate root, +no matter how deep the module hierarchy is, or whether the module body it's written in +is contained in its own file (remember: files are irrelevant). + +This is different to other languages, where you often only find a single import construct that combines the semantic +of `mod foo;` and `use`-statements, and which tend to work relative to the source file or use an absolute file path +- Rubys `require` or C/C++'s `#include` come to mind. + +However, it's also possible to import things relative to the module of the `use`-statement: +Adding a `super::` in front of the path will start in the parent module, +while adding a `self::` prefix will start in the current module: + +~~~ +# mod workaround { +# pub fn some_parent_item(){ println!("...") } +# mod foo { +use super::some_parent_item; +use self::some_child_module::some_item; +# pub fn bar() { some_parent_item(); some_item() } +# pub mod some_child_module { pub fn some_item() {} } +# } +# } +~~~ + +Again - relative to the module, not to the file. + +Imports are also shadowed by local definitions: +For each name you mention in a module/block, `rust` +will first look at all items that are defined locally, +and only if that results in no match look at items you brought in +scope with corresponding `use` statements. + +~~~ {.ignore} +# // FIXME: Allow unused import in doc test +use farm::cow; +// ... +# mod farm { pub fn cow() { println!("Hidden ninja cow is hidden.") } } +fn cow() { println!("Mooo!") } + +fn main() { + cow() // resolves to the locally defined `cow()` function +} +~~~ + +To make this behavior more obvious, the rule has been made that `use`-statement always need to be written +before any declaration, like in the example above. This is a purely artificial rule introduced +because people always assumed they shadowed each other based on order, despite the fact that all items in rust are +mutually recursive, order independent definitions. + +One odd consequence of that rule is that `use` statements also go in front of any `mod` declaration, +even if they refer to things inside them: + +~~~ +use farm::cow; +mod farm { + pub fn cow() { println!("Moooooo?") } +} + +fn main() { cow() } +~~~ + +This is what our `farm` example looks like with `use` statements: + +~~~~ +use farm::chicken; +use farm::cow; +use farm::barn; + +mod farm { + pub fn chicken() { println!("cluck cluck"); } + pub fn cow() { println!("mooo"); } + + pub mod barn { + pub fn hay() { println!("..."); } + } +} + +fn main() { + println!("Hello farm!"); + + // Can now refer to those names directly: + chicken(); + cow(); + barn::hay(); +} +~~~~ + +And here an example with multiple files: + +~~~{.ignore} +// `a.rs` - crate root +use b::foo; +mod b; +fn main() { foo(); } +~~~ + +~~~{.ignore} +// `b.rs` +use b::c::bar; +pub mod c; +pub fn foo() { bar(); } +~~~ + +~~~ +// `c.rs` +pub fn bar() { println!("Baz!"); } +# fn main() {} +~~~ + +There also exist two short forms for importing multiple names at once: + +1. Explicit mention multiple names as the last element of an `use` path: + +~~~ +use farm::{chicken, cow}; +# mod farm { +# pub fn cow() { println!("Did I already mention how hidden and ninja I am?") } +# pub fn chicken() { println!("I'm Bat-chicken, guardian of the hidden tutorial code.") } +# } +# fn main() { cow(); chicken() } +~~~ + +2. Import everything in a module with a wildcard: + +~~~ +use farm::*; +# mod farm { +# pub fn cow() { println!("Bat-chicken? What a stupid name!") } +# pub fn chicken() { println!("Says the 'hidden ninja' cow.") } +# } +# fn main() { cow(); chicken() } +~~~ + +> ***Note:*** This feature of the compiler is currently gated behind the +> `#[feature(globs)]` directive. More about these directives can be found in +> the manual. + +However, that's not all. You can also rename an item while you're bringing it into scope: + +~~~ +use egg_layer = farm::chicken; +# mod farm { pub fn chicken() { println!("Laying eggs is fun!") } } +// ... + +fn main() { + egg_layer(); +} +~~~ + +In general, `use` creates an local alias: +An alternate path and a possibly different name to access the same item, +without touching the original, and with both being interchangeable. + +## Reexporting names + +It is also possible to reexport items to be accessible under your module. + +For that, you write `pub use`: + +~~~ +mod farm { + pub use self::barn::hay; + + pub fn chicken() { println!("cluck cluck"); } + pub fn cow() { println!("mooo"); } + + mod barn { + pub fn hay() { println!("..."); } + } +} + +fn main() { + farm::chicken(); + farm::cow(); + farm::hay(); +} +~~~ + +Just like in normal `use` statements, the exported names +merely represent an alias to the same thing and can also be renamed. + +The above example also demonstrate what you can use `pub use` for: +The nested `barn` module is private, but the `pub use` allows users +of the module `farm` to access a function from `barn` without needing +to know that `barn` exists. + +In other words, you can use them to decouple an public api from their internal implementation. + +## Using libraries + +So far we've only talked about how to define and structure your own crate. + +However, most code out there will want to use preexisting libraries, +as there really is no reason to start from scratch each time you start a new project. + +In Rust terminology, we need a way to refer to other crates. + +For that, Rust offers you the `extern mod` declaration: + +~~~ +extern mod extra; +// extra ships with Rust, you'll find more details further down. + +fn main() { + // The rational number '1/2': + let one_half = ::extra::rational::Ratio::new(1, 2); +} +~~~ + +Despite its name, `extern mod` is a distinct construct from regular `mod` declarations: +A statement of the form `extern mod foo;` will cause `rustc` to search for the crate `foo`, +and if it finds a matching binary it lets you use it from inside your crate. + +The effect it has on your module hierarchy mirrors aspects of both `mod` and `use`: + +- Like `mod`, it causes `rustc` to actually emit code: + The linkage information the binary needs to use the library `foo`. + +- But like `use`, all `extern mod` statements that refer to the same library are interchangeable, + as each one really just presents an alias to an external module (the crate root of the library + you're linking against). + +Remember how `use`-statements have to go before local declarations because the latter shadows the former? +Well, `extern mod` statements also have their own rules in that regard: +Both `use` and local declarations can shadow them, so the rule is that `extern mod` has to go in front +of both `use` and local declarations. + +Which can result in something like this: + +~~~ +extern mod extra; + +use farm::dog; +use extra::rational::Ratio; + +mod farm { + pub fn dog() { println!("woof"); } +} + +fn main() { + farm::dog(); + let a_third = Ratio::new(1, 3); +} +~~~ + +It's a bit weird, but it's the result of shadowing rules that have been set that way because +they model most closely what people expect to shadow. + +## Package ids + +If you use `extern mod`, per default `rustc` will look for libraries in the library search path (which you can +extend with the `-L` switch). + +## Crate metadata and settings + +For every crate you can define a number of metadata items, such as link name, version or author. +You can also toggle settings that have crate-global consequences. Both mechanism +work by providing attributes in the crate root. + +For example, Rust uniquely identifies crates by their link metadata, which includes +the link name and the version. It also hashes the filename and the symbols in a binary +based on the link metadata, allowing you to use two different versions of the same library in a crate +without conflict. + +Therefore, if you plan to compile your crate as a library, you should annotate it with that information: + +~~~~ +// `lib.rs` + +# #[crate_type = "lib"]; +// Package ID +#[crate_id = "farm#2.5"]; + +// ... +# fn farm() {} +~~~~ + +You can also specify package ID information in a `extern mod` statement. For +example, these `extern mod` statements would both accept and select the +crate define above: + +~~~~ {.ignore} +extern mod farm; +extern mod farm = "farm#2.5"; +extern mod my_farm = "farm"; +~~~~ + +Other crate settings and metadata include things like enabling/disabling certain errors or warnings, +or setting the crate type (library or executable) explicitly: + +~~~~ +// `lib.rs` +// ... + +// This crate is a library ("bin" is the default) +#[crate_id = "farm#2.5"]; +#[crate_type = "lib"]; + +// Turn on a warning +#[warn(non_camel_case_types)] +# fn farm() {} +~~~~ + +## A minimal example + +Now for something that you can actually compile yourself. + +We define two crates, and use one of them as a library in the other. + +~~~~ +// `world.rs` +#[crate_id = "world#0.42"]; +# extern mod extra; +pub fn explore() -> &'static str { "world" } +# fn main() {} +~~~~ + +~~~~ {.ignore} +// `main.rs` +extern mod world; +fn main() { println!("hello {}", world::explore()); } +~~~~ + +Now compile and run like this (adjust to your platform if necessary): + +~~~~ {.notrust} +> rustc --lib world.rs # compiles libworld-<HASH>-0.42.so +> rustc main.rs -L . # compiles main +> ./main +"hello world" +~~~~ + +Notice that the library produced contains the version in the file name +as well as an inscrutable string of alphanumerics. As explained in the previous paragraph, +these are both part of Rust's library versioning scheme. The alphanumerics are +a hash representing the crates package ID. + +## The standard library and the prelude + +While reading the examples in this tutorial, you might have asked yourself where all +those magical predefined items like `range` are coming from. + +The truth is, there's nothing magical about them: They are all defined normally +in the `std` library, which is a crate that ships with Rust. + +The only magical thing that happens is that `rustc` automatically inserts this line into your crate root: + +~~~ {.ignore} +extern mod std; +~~~ + +As well as this line into every module body: + +~~~ {.ignore} +use std::prelude::*; +~~~ + +The role of the `prelude` module is to re-export common definitions from `std`. + +This allows you to use common types and functions like `Option<T>` or `range` +without needing to import them. And if you need something from `std` that's not in the prelude, +you just have to import it with an `use` statement. + +For example, it re-exports `range` which is defined in `std::iter::range`: + +~~~ +use iter_range = std::iter::range; + +fn main() { + // `range` is imported by default + for _ in range(0, 10) {} + + // Doesn't hinder you from importing it under a different name yourself + for _ in iter_range(0, 10) {} + + // Or from not using the automatic import. + for _ in ::std::iter::range(0, 10) {} +} +~~~ + +Both auto-insertions can be disabled with an attribute if necessary: + +~~~ +// In the crate root: +#[no_std]; +~~~ + +~~~ +// In any module: +#[no_implicit_prelude]; +~~~ + +See the [API documentation][stddoc] for details. + +[stddoc]: std/index.html + +## The extra library + +Rust also ships with the [extra library], an accumulation of useful things, +that are however not important enough to deserve a place in the standard +library. You can use them by linking to `extra` with an `extern mod extra;`. + +[extra library]: extra/index.html + +Right now `extra` contains those definitions directly, but in the future it will likely just +re-export a bunch of 'officially blessed' crates that get managed with a +package manager. + +# What next? + +Now that you know the essentials, check out any of the additional +guides on individual topics. + +* [Pointers][pointers] +* [Lifetimes][lifetimes] +* [Tasks and communication][tasks] +* [Macros][macros] +* [The foreign function interface][ffi] +* [Containers and iterators][container] +* [Error-handling and Conditions][conditions] +* [Documenting Rust code][rustdoc] +* [Testing Rust code][testing] +* [The Rust Runtime][runtime] + +There is further documentation on the [wiki], however those tend to be even more out of date as this document. + +[pointers]: guide-pointers.html +[lifetimes]: guide-lifetimes.html +[tasks]: guide-tasks.html +[macros]: guide-macros.html +[ffi]: guide-ffi.html +[container]: guide-container.html +[conditions]: guide-conditions.html +[testing]: guide-testing.html +[runtime]: guide-runtime.html +[rustdoc]: rustdoc.html +[wiki]: https://github.com/mozilla/rust/wiki/Docs + +[wiki-packages]: https://github.com/mozilla/rust/wiki/Doc-packages,-editors,-and-other-tools |
