1 % Rust Language Tutorial
7 This is a tutorial for the Rust programming language. It assumes the
8 reader is familiar with the basic concepts of programming, and has
9 programmed in one or more other languages before. It will often make
10 comparisons to other languages in the C family. The tutorial covers
11 the whole language, though not with the depth and precision of the
12 [language reference](rust.html).
16 Rust is a systems programming language with a focus on type safety,
17 memory safety, concurrency and performance. It is intended for writing
18 large, high-performance applications while preventing several classes
19 of errors commonly found in languages like C++. Rust has a
20 sophisticated memory model that makes possible many of the efficient
21 data structures used in C++, while disallowing invalid memory accesses
22 that would otherwise cause segmentation faults. Like other systems
23 languages, it is statically typed and compiled ahead of time.
25 As a multi-paradigm language, Rust supports writing code in
26 procedural, functional and object-oriented styles. Some of its nice
27 high-level features include:
29 * **Pattern matching and algebraic data types (enums).** Common in
30 functional languages, pattern matching on ADTs provides a compact
31 and expressive way to encode program logic.
32 * **Task-based concurrency.** Rust uses lightweight tasks that do
34 * **Higher-order functions.** Rust functions may take closures as
35 arguments or return closures as return values. Closures in Rust are
36 very powerful and used pervasively.
37 * **Trait polymorphism.** Rust's type system features a unique
38 combination of Java-style interfaces and Haskell-style typeclasses
40 * **Parametric polymorphism (generics).** Functions and types can be
41 parameterized over type variables with optional type constraints.
42 * **Type inference.** Type annotations on local variable
43 declarations can be omitted.
47 As a curly-brace language in the tradition of C, C++, and JavaScript,
48 Rust looks a lot like other languages you may be familiar with.
51 fn boring_old_factorial(n: int) -> int {
52 let mut result = 1, i = 1;
61 Several differences from C stand out. Types do not come before, but
62 after variable names (preceded by a colon). For local variables
63 (introduced with `let`), types are optional, and will be inferred when
64 left off. Constructs like `while` and `if` do not require parentheses
65 around the condition (though they allow them).
67 You should, however, not conclude that Rust is simply an evolution of
68 C. As will become clear in the rest of this tutorial, it goes in quite
69 a different direction, with efficient, strongly-typed and memory-safe
70 support for many high-level idioms.
74 Throughout the tutorial, words that indicate language keywords or
75 identifiers defined in the example code are displayed in `code font`.
77 Code snippets are indented, and also shown in a monospaced font. Not
78 all snippets constitute whole programs. For brevity, we'll often show
79 fragments of programs that don't compile on their own. To try them
80 out, you might have to wrap them in `fn main() { ... }`, and make sure
81 they don't contain references to things that aren't actually defined.
83 > ***Warning:*** Rust is a language under heavy development. Notes
84 > about potential changes to the language, implementation
85 > deficiencies, and other caveats appear offset in blockquotes.
91 The Rust compiler currently must be built from a [tarball][]. We hope
92 to be distributing binary packages for various operating systems in
95 The Rust compiler is slightly unusual in that it is written in Rust
96 and therefore must be built by a precompiled "snapshot" version of
97 itself (made in an earlier state of development). As such, source
100 * You are connected to the internet, to fetch snapshots.
101 * You can at least execute snapshot binaries of one of the forms we
102 offer them in. Currently we build and test snapshots on:
103 * Windows (7, server 2008 r2) x86 only
104 * Linux (various distributions) x86 and x86-64
105 * OSX 10.6 ("Snow Leopard") or 10.7 ("Lion") x86 and x86-64
107 You may find other platforms work, but these are our "tier 1" supported
108 build environments that are most likely to work. Further platforms will
109 be added to the list in the future via cross-compilation.
111 To build from source you will also need the following prerequisite
114 * g++ 4.4 or clang++ 3.x
115 * python 2.6 or later
117 * gnu make 3.81 or later
120 Assuming you're on a relatively modern *nix system and have met the
121 prerequisites, something along these lines should work. Building from
122 source on Windows requires some extra steps: please see the [getting
123 started][wiki-get-started] page on the Rust wiki.
126 $ wget http://dl.rust-lang.org/dist/rust-0.4.tar.gz
127 $ tar -xzf rust-0.4.tar.gz
130 $ make && make install
133 You may need to use `sudo make install` if you do not normally have
134 permission to modify the destination directory. The install locations
135 can be adjusted by passing a `--prefix` argument to
136 `configure`. Various other options are also supported, pass `--help`
137 for more information on them.
139 When complete, `make install` will place the following programs into
142 * `rustc`, the Rust compiler
143 * `rustdoc`, the API-documentation tool
144 * `cargo`, the Rust package manager
146 [wiki-get-started]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust
147 [tarball]: http://dl.rust-lang.org/dist/rust-0.4.tar.gz
149 ## Compiling your first program
151 Rust program files are, by convention, given the extension `.rs`. Say
152 we have a file `hello.rs` containing this program:
156 io::println("hello world!");
160 If the Rust compiler was installed successfully, running `rustc
161 hello.rs` will produce a binary called `hello` (or `hello.exe`).
163 If you modify the program to make it invalid (for example, by changing
164 `io::println` to some nonexistent function), and then compile it,
165 you'll see an error message like this:
168 hello.rs:2:4: 2:16 error: unresolved name: io::print_it
169 hello.rs:2 io::print_it("hello world!");
173 The Rust compiler tries to provide useful information when it runs
176 ## Anatomy of a Rust program
178 In its simplest form, a Rust program is a `.rs` file with some
179 types and functions defined in it. If it has a `main` function, it can
180 be compiled to an executable. Rust does not allow code that's not a
181 declaration to appear at the top level of the file—all statements must
182 live inside a function.
184 Rust programs can also be compiled as libraries, and included in other
185 programs. The `extern mod std` directive that appears at the top of a lot of
186 examples imports the [standard library][std]. This is described in more
187 detail [later on](#modules-and-crates).
189 [std]: http://doc.rust-lang.org/doc/std
193 There are Vim highlighting and indentation scripts in the Rust source
194 distribution under `src/etc/vim/`, and an emacs mode under
195 `src/etc/emacs/`. There is a package for Sublime Text 2 at
196 [github.com/dbp/sublime-rust](http://github.com/dbp/sublime-rust), also
197 available through [package control](http://wbond.net/sublime_packages/package_control).
199 Other editors are not provided for yet. If you end up writing a Rust
200 mode for your favorite editor, let us know so that we can link to it.
206 Assuming you've programmed in any C-family language (C++, Java,
207 JavaScript, C#, or PHP), Rust will feel familiar. The main surface
208 difference to be aware of is that the bodies of `if` statements and of
209 `while` loops *have* to be wrapped in brackets. Single-statement,
210 bracket-less bodies are not allowed.
212 Accounting for these differences, the surface syntax of Rust
213 statements and expressions is C-like. Function calls are written
214 `myfunc(arg1, arg2)`, operators have mostly the same name and
215 precedence that they have in C, comments look the same, and constructs
216 like `if` and `while` are available:
223 /* Ensure that basic math works. */
237 Though it isn't apparent in all code, there is a fundamental
238 difference between Rust's syntax and its predecessors in this family
239 of languages. Many constructs that are statements in C are expressions
240 in Rust. This allows Rust to be more expressive. For example, you might
241 write a piece of code like this:
244 # let item = "salad";
248 } else if item == "muffin" {
255 But, in Rust, you don't have to repeat the name `price`:
258 # let item = "salad";
259 let price = if item == "salad" { 3.50 }
260 else if item == "muffin" { 2.25 }
264 Both pieces of code are exactly equivalent—they assign a value to `price`
265 depending on the condition that holds. Note that the semicolons are omitted
266 from the second snippet. This is important; the lack of a semicolon after the
267 last statement in a braced block gives the whole block the value of that last
270 Put another way, the semicolon in Rust *ignores the value of an expression*.
271 Thus, if the branches of the `if` had looked like `{ 4; }`, the above example
272 would simply assign nil (void) to `price`. But without the semicolon, each
273 branch has a different value, and `price` gets the value of the branch that
276 This feature also works for function bodies. This function returns a boolean:
279 fn is_four(x: int) -> bool { x == 4 }
282 In short, everything that's not a declaration (`let` for variables,
283 `fn` for functions, et cetera) is an expression.
285 If all those things are expressions, you might conclude that you have
286 to add a terminating semicolon after *every* statement, even ones that
287 are not traditionally terminated with a semicolon in C (like `while`).
288 That is not the case, though. Expressions that end in a block only
289 need a semicolon if that block contains a trailing expression. `while`
290 loops do not allow trailing expressions, and `if` statements tend to
291 only have a trailing expression when you want to use their value for
292 something—in which case you'll have embedded it in a bigger statement,
293 like the `let x = ...` example above.
297 Rust identifiers follow the same rules as C; they start with an alphabetic
298 character or an underscore, and after that may contain any sequence of
299 alphabetic characters, numbers, or underscores. The preferred style is to
300 begin function, variable, and module names with a lowercase letter, using
301 underscores where they help readability, while beginning types with a capital
304 The double-colon (`::`) is used as a module separator, so
305 `io::println` means 'the thing named `println` in the module
308 ## Variable declaration
310 The `let` keyword, as we've seen, introduces a local variable. Local
311 variables are immutable by default: `let mut` can be used to introduce
312 a local variable that can be reassigned. Global constants can be
313 defined with `const`:
316 const REPEAT: int = 5;
320 while count < REPEAT {
327 Local variables may shadow earlier declarations, making the earlier variables
331 let my_favorite_value: float = 57.8;
332 let my_favorite_value: int = my_favorite_value as int;
337 The basic types are written like this:
340 : Nil, the type that has only a single value.
343 : Boolean type, with values `true` and `false`.
346 : A machine-pointer-sized integer.
349 : A machine-pointer-sized unsigned integer.
351 `i8`, `i16`, `i32`, `i64`
352 : Signed integers with a specific size (in bits).
354 `u8`, `u16`, `u32`, `u64`
355 : Unsigned integers with a specific size.
358 : The largest floating-point type efficiently supported on the target
362 : Floating-point types with a specific size.
365 : A Unicode character (32 bits).
367 These can be combined in composite types, which will be described in
368 more detail later on (the `T`s here stand for any other type):
371 : Vector (like an array in other languages) with N elements.
374 : Mutable vector with N elements.
377 : Tuple type. Any arity above 1 is supported.
380 : Pointer types. See [Boxes and pointers](#boxes-and-pointers) for an explanation of what `@`, `~`, and `&` mean.
382 Some types can only be manipulated by pointer, never directly. For instance,
383 you cannot refer to a string (`str`); instead you refer to a pointer to a
384 string (`@str`, `~str`, or `&str`). These *dynamically-sized* types consist
387 `fn(arg1: T1, arg2: T2) -> T3`
391 : String type (in UTF-8).
394 : Vector with unknown size (also called a slice).
397 : Mutable vector with unknown size.
399 Types can be given names with `type` declarations:
402 type MonsterSize = uint;
405 This will provide a synonym, `MonsterSize`, for unsigned integers. It will not
406 actually create a new, incompatible type—`MonsterSize` and `uint` can be used
407 interchangeably, and using one where the other is expected is not a type
408 error. Read about [single-variant enums](#single_variant_enum)
409 further on if you need to create a type name that's not just a
414 The `-> bool` in the `is_four` example is the way a function's return
415 type is written. For functions that do not return a meaningful value,
416 you can optionally say `-> ()`, but usually the return annotation is simply
417 left off, as in the `fn main() { ... }` examples we've seen earlier.
419 Every argument to a function must have its type declared (for example,
420 `x: int`). Inside the function, type inference will be able to
421 automatically deduce the type of most locals (generic functions, which
422 we'll come back to later, will occasionally need additional
423 annotation). Locals can be written either with or without a type
427 // The type of this vector will be inferred based on its use.
429 # vec::map(x, fn&(_y: &int) -> int { *_y });
430 // Explicitly say this is a vector of zero integers.
431 let y: [int * 0] = [];
436 Integers can be written in decimal (`144`), hexadecimal (`0x90`), and
437 binary (`0b10010000`) base.
439 If you write an integer literal without a suffix (`3`, `-500`, etc.),
440 the Rust compiler will try to infer its type based on type annotations
441 and function signatures in the surrounding program. In the absence of any type
442 annotations at all, Rust will assume that an unsuffixed integer literal has
443 type `int`. It's also possible to avoid any type ambiguity by writing integer
444 literals with a suffix. For example:
448 log(error, x); // x is an int
450 log(error, y); // y is an uint
453 Note that, in Rust, no implicit conversion between integer types
454 happens. If you are adding one to a variable of type `uint`, saying
455 `+= 1u8` will give you a type error.
457 Floating point numbers are written `0.0`, `1e6`, or `2.1e-4`. Without
458 a suffix, the literal is assumed to be of type `float`. Suffixes `f` (32-bit)
459 and `l` (64-bit) can be used to create literals of a specific type.
463 The nil literal is written just like the type: `()`. The keywords
464 `true` and `false` produce the boolean literals.
466 Character literals are written between single quotes, as in `'x'`. Just as in
467 C, Rust understands a number of character escapes, using the backslash
468 character, `\n`, `\r`, and `\t` being the most common.
470 String literals allow the same escape sequences. They are written
471 between double quotes (`"hello"`). Rust strings may contain newlines.
475 Rust's set of operators contains very few surprises. Arithmetic is done with
476 `*`, `/`, `%`, `+`, and `-` (multiply, divide, remainder, plus, minus). `-` is
477 also a unary prefix operator that does negation. As in C, the bit operators
478 `>>`, `<<`, `&`, `|`, and `^` are also supported.
480 Note that, if applied to an integer value, `!` flips all the bits (like `~` in
483 The comparison operators are the traditional `==`, `!=`, `<`, `>`,
484 `<=`, and `>=`. Short-circuiting (lazy) boolean operators are written
485 `&&` (and) and `||` (or).
487 For type casting, Rust uses the binary `as` operator. It takes an
488 expression on the left side and a type on the right side and will,
489 if a meaningful conversion exists, convert the result of the
490 expression to the given type.
494 let y: uint = x as uint;
498 The main difference with C is that `++` and `--` are missing, and that
499 the logical bitwise operators have higher precedence — in C, `x & 2 > 0`
500 comes out as `x & (2 > 0)`, in Rust, it means `(x & 2) > 0`, which is
501 more likely to be what you expect (unless you are a C veteran).
505 *Syntax extensions* are special forms that are not built into the language,
506 but are instead provided by the libraries. To make it clear to the reader when
507 a syntax extension is being used, the names of all syntax extensions end with
508 `!`. The standard library defines a few syntax extensions, the most useful of
509 which is `fmt!`, a `sprintf`-style text formatter that is expanded at compile
513 io::println(fmt!("%s is %d", ~"the answer", 42));
516 `fmt!` supports most of the directives that [printf][pf] supports, but
517 will give you a compile-time error when the types of the directives
518 don't match the types of the arguments.
520 [pf]: http://en.cppreference.com/w/cpp/io/c/fprintf
522 You can define your own syntax extensions with the macro system, which is out
523 of scope of this tutorial.
529 We've seen `if` pass by a few times already. To recap, braces are
530 compulsory, an optional `else` clause can be appended, and multiple
531 `if`/`else` constructs can be chained together:
535 io::println(~"that's odd");
537 io::println(~"right");
539 io::println(~"neither true nor false");
543 The condition given to an `if` construct *must* be of type boolean (no
544 implicit conversion happens). If the arms return a value, this value
545 must be of the same type for every arm in which control reaches the
549 fn signum(x: int) -> int {
558 Rust's `match` construct is a generalized, cleaned-up version of C's
559 `switch` construct. You provide it with a value and a number of *arms*,
560 each labelled with a pattern, and the code will attempt to match each pattern
561 in order. For the first one that matches, the arm is executed.
566 0 => io::println("zero"),
567 1 | 2 => io::println("one or two"),
568 3..10 => io::println("three to ten"),
569 _ => io::println("something else")
573 There is no 'falling through' between arms, as in C—only one arm is
574 executed, and it doesn't have to explicitly `break` out of the
575 construct when it is finished.
577 The part to the left of the arrow `=>` is called the *pattern*. Literals are
578 valid patterns and will match only their own value. The pipe operator
579 (`|`) can be used to assign multiple patterns to a single arm. Ranges
580 of numeric literal patterns can be expressed with two dots, as in `M..N`. The
581 underscore (`_`) is a wildcard pattern that matches everything.
583 The patterns in an match arm are followed by a fat arrow, `=>`, then an
584 expression to evaluate. Each case is separated by commas. It's often
585 convenient to use a block expression for a case, in which case the
595 io::println("something else")
600 `match` constructs must be *exhaustive*: they must have an arm covering every
601 possible case. For example, if the arm with the wildcard pattern was left off
602 in the above example, the typechecker would reject it.
604 A powerful application of pattern matching is *destructuring*, where
605 you use the matching to get at the contents of data types. Remember
606 that `(float, float)` is a tuple of two floats:
609 use float::consts::pi;
610 fn angle(vector: (float, float)) -> float {
612 (0f, y) if y < 0f => 1.5 * pi,
614 (x, y) => float::atan(y / x)
619 A variable name in a pattern matches everything, *and* binds that name
620 to the value of the matched thing inside of the arm block. Thus, `(0f,
621 y)` matches any tuple whose first element is zero, and binds `y` to
622 the second element. `(x, y)` matches any tuple, and binds both
623 elements to a variable.
625 Any `match` arm can have a guard clause (written `if EXPR`), which is
626 an expression of type `bool` that determines, after the pattern is
627 found to match, whether the arm is taken or not. The variables bound
628 by the pattern are available in this guard expression.
632 You've already seen simple `let` bindings. `let` is also a little fancier: it
633 is possible to use destructuring patterns in it. For example, you can say this
634 to extract the fields from a tuple:
637 # fn get_tuple_of_two_ints() -> (int, int) { (1, 1) }
638 let (a, b) = get_tuple_of_two_ints();
641 This will introduce two new variables, `a` and `b`, bound to the
642 content of the tuple.
644 You may only use *irrefutable* patterns—patterns that can never fail to
645 match—in let bindings. Other types of patterns, such as literals, are
650 `while` produces a loop that runs as long as its given condition
651 (which must have type `bool`) evaluates to true. Inside a loop, the
652 keyword `break` can be used to abort the loop, and `again` can be used
653 to abort the current iteration and continue with the next.
656 let mut cake_amount = 8;
657 while cake_amount > 0 {
662 `loop` is the preferred way of writing `while true`:
668 if x % 5 == 0 { break; }
669 io::println(int::str(x));
673 This code prints out a weird sequence of numbers and stops as soon as
674 it finds one that can be divided by five.
676 For more involved iteration, such as going over the elements of a
677 collection, Rust uses higher-order functions. We'll come back to those
682 Like all other static declarations, such as `type`, functions can be
683 declared both at the top level and inside other functions (or modules,
684 which we'll come back to [later](#modules-and-crates)).
686 We've already seen several function definitions. They are introduced
687 with the `fn` keyword, the type of arguments are specified following
688 colons and the return type follows the arrow.
691 fn repeat(string: &str, count: int) -> ~str {
692 let mut result = ~"";
700 The `return` keyword immediately returns from the body of a function. It
701 is optionally followed by an expression to return. A function can
702 also return a value by having its top level block produce an
706 # const copernicus: int = 0;
707 fn int_to_str(i: int) -> ~str {
717 # const copernicus: int = 0;
718 fn int_to_str(i: int) -> ~str {
719 if i == copernicus { ~"tube sock" }
724 Functions that do not return a value are said to return nil, `()`,
725 and both the return type and the return value may be omitted from
726 the definition. The following two functions are equivalent.
729 fn do_nothing_the_hard_way() -> () { return (); }
731 fn do_nothing_the_easy_way() { }
736 The core datatypes of Rust are structs, enums (tagged unions, algebraic data
737 types), and tuples. They are immutable by default.
740 struct Point { x: float, y: float }
743 Circle(Point, float),
744 Rectangle(Point, Point)
750 Rust struct types must be declared before they are used using the `struct`
751 syntax: `struct Name { field1: T1, field2: T2 [, ...] }`, where `T1`, `T2`,
752 ... denote types. To construct a struct, use the same syntax, but leave off
753 the `struct`; for example: `Point { x: 1.0, y: 2.0 }`.
755 Structs are quite similar to C structs and are even laid out the same way in
756 memory (so you can read from a Rust struct in C, and vice-versa). The dot
757 operator is used to access struct fields (`mypoint.x`).
759 Fields that you want to mutate must be explicitly marked `mut`.
768 With a value of such a type, you can do `mystack.head += 1`. If `mut` were
769 omitted from the type, such an assignment would result in a type error.
773 Structs can be destructured in `match` patterns. The basic syntax is
774 `Name {fieldname: pattern, ...}`:
776 # struct Point { x: float, y: float }
777 # let mypoint = Point { x: 0.0, y: 0.0 };
779 Point { x: 0.0, y: y } => { io::println(y.to_str()); }
780 Point { x: x, y: y } => { io::println(x.to_str() + " " + y.to_str()); }
784 In general, the field names of a struct do not have to appear in the same
785 order they appear in the type. When you are not interested in all
786 the fields of a struct, a struct pattern may end with `, _` (as in
787 `Name {field1, _}`) to indicate that you're ignoring all other fields.
791 Enums are datatypes that have several alternate representations. For
792 example, consider the type shown earlier:
795 # struct Point { x: float, y: float }
797 Circle(Point, float),
798 Rectangle(Point, Point)
802 A value of this type is either a Circle, in which case it contains a
803 point struct and a float, or a Rectangle, in which case it contains
804 two point records. The run-time representation of such a value
805 includes an identifier of the actual form that it holds, much like the
806 'tagged union' pattern in C, but with better ergonomics.
808 The above declaration will define a type `shape` that can be used to
809 refer to such shapes, and two functions, `circle` and `rectangle`,
810 which can be used to construct values of the type (taking arguments of
811 the specified types). So `circle({x: 0f, y: 0f}, 10f)` is the way to
814 Enum variants need not have type parameters. This, for example, is
815 equivalent to a C enum:
826 This will define `North`, `East`, `South`, and `West` as constants,
827 all of which have type `Direction`.
829 When an enum is C-like, that is, when none of the variants have
830 parameters, it is possible to explicitly set the discriminator values
841 If an explicit discriminator is not specified for a variant, the value
842 defaults to the value of the previous variant plus one. If the first
843 variant does not have a discriminator, it defaults to 0. For example,
844 the value of `North` is 0, `East` is 1, etc.
846 When an enum is C-like the `as` cast operator can be used to get the
847 discriminator's value.
849 <a name="single_variant_enum"></a>
851 There is a special case for enums with a single variant. These are
852 used to define new types in such a way that the new name is not just a
853 synonym for an existing type, but its own distinct type. If you say:
859 That is a shorthand for this:
862 enum GizmoId { GizmoId(int) }
865 Enum types like this can have their content extracted with the
866 dereference (`*`) unary operator:
869 # enum GizmoId = int;
870 let my_gizmo_id = GizmoId(10);
871 let id_int: int = *my_gizmo_id;
876 For enum types with multiple variants, destructuring is the only way to
877 get at their contents. All variant constructors can be used as
878 patterns, as in this definition of `area`:
881 # type Point = {x: float, y: float};
882 # enum Shape { Circle(Point, float), Rectangle(Point, Point) }
883 fn area(sh: Shape) -> float {
885 Circle(_, size) => float::consts::pi * size * size,
886 Rectangle({x, y}, {x: x2, y: y2}) => (x2 - x) * (y2 - y)
891 Another example, matching nullary enum variants:
894 # type Point = {x: float, y: float};
895 # enum Direction { North, East, South, West }
896 fn point_from_direction(dir: Direction) -> Point {
898 North => {x: 0f, y: 1f},
899 East => {x: 1f, y: 0f},
900 South => {x: 0f, y: -1f},
901 West => {x: -1f, y: 0f}
908 Tuples in Rust behave exactly like records, except that their fields
909 do not have names (and can thus not be accessed with dot notation).
910 Tuples can have any arity except for 0 or 1 (though you may consider
911 nil, `()`, as the empty tuple if you like).
914 let mytup: (int, int, float) = (10, 20, 30.0);
916 (a, b, c) => log(info, a + b + (c as int))
920 # The Rust memory model
922 At this junction let's take a detour to explain the concepts involved
923 in Rust's memory model. Rust has a very particular approach to
924 memory management that plays a significant role in shaping the "feel"
925 of the language. Understanding the memory landscape will illuminate
926 several of Rust's unique features as we encounter them.
928 Rust has three competing goals that inform its view of memory:
930 * Memory safety: memory that is managed by and is accessible to the
931 Rust language must be guaranteed to be valid; under normal
932 circumstances it must be impossible for Rust to trigger a
933 segmentation fault or leak memory
934 * Performance: high-performance low-level code must be able to employ
935 a number of allocation strategies; low-performance high-level code
936 must be able to employ a single, garbage-collection-based, heap
938 * Concurrency: Rust must maintain memory safety guarantees, even for
939 code running in parallel
941 ## How performance considerations influence the memory model
943 Most languages that offer strong memory safety guarantees rely upon a
944 garbage-collected heap to manage all of the objects. This approach is
945 straightforward both in concept and in implementation, but has
946 significant costs. Languages that take this approach tend to
947 aggressively pursue ways to ameliorate allocation costs (think the
948 Java Virtual Machine). Rust supports this strategy with _shared
949 boxes_: memory allocated on the heap that may be referred to (shared)
950 by multiple variables.
952 By comparison, languages like C++ offer very precise control over
953 where objects are allocated. In particular, it is common to put them
954 directly on the stack, avoiding expensive heap allocation. In Rust
955 this is possible as well, and the compiler will use a clever _pointer
956 lifetime analysis_ to ensure that no variable can refer to stack
957 objects after they are destroyed.
959 ## How concurrency considerations influence the memory model
961 Memory safety in a concurrent environment involves avoiding race
962 conditions between two threads of execution accessing the same
963 memory. Even high-level languages often require programmers to
964 correctly employ locking to ensure that a program is free of races.
966 Rust starts from the position that memory cannot be shared between
967 tasks. Experience in other languages has proven that isolating each
968 task's heap from the others is a reliable strategy and one that is
969 easy for programmers to reason about. Heap isolation has the
970 additional benefit that garbage collection must only be done
971 per-heap. Rust never "stops the world" to garbage-collect memory.
973 Complete isolation of heaps between tasks implies that any data
974 transferred between tasks must be copied. While this is a fine and
975 useful way to implement communication between tasks, it is also very
976 inefficient for large data structures. Because of this, Rust also
977 employs a global _exchange heap_. Objects allocated in the exchange
978 heap have _ownership semantics_, meaning that there is only a single
979 variable that refers to them. For this reason, they are referred to as
980 _unique boxes_. All tasks may allocate objects on the exchange heap,
981 then transfer ownership of those objects to other tasks, avoiding
984 ## What to be aware of
986 Rust has three "realms" in which objects can be allocated: the stack,
987 the local heap, and the exchange heap. These realms have corresponding
988 pointer types: the borrowed pointer (`&T`), the shared box (`@T`),
989 and the unique box (`~T`). These three sigils will appear
990 repeatedly as we explore the language. Learning the appropriate role
991 of each is key to using Rust effectively.
995 In contrast to a lot of modern languages, aggregate types like records
996 and enums are _not_ represented as pointers to allocated memory in
997 Rust. They are, as in C and C++, represented directly. This means that
998 if you `let x = {x: 1f, y: 1f};`, you are creating a record on the
999 stack. If you then copy it into a data structure, the whole record is
1000 copied, not just a pointer.
1002 For small records like `point`, this is usually more efficient than
1003 allocating memory and going through a pointer. But for big records, or
1004 records with mutable fields, it can be useful to have a single copy on
1005 the heap, and refer to that through a pointer.
1007 Rust supports several types of pointers. The safe pointer types are
1008 `@T` for shared boxes allocated on the local heap, `~T`, for
1009 uniquely-owned boxes allocated on the exchange heap, and `&T`, for
1010 borrowed pointers, which may point to any memory, and whose lifetimes
1011 are governed by the call stack.
1013 All pointer types can be dereferenced with the `*` unary operator.
1017 Shared boxes are pointers to heap-allocated, garbage collected memory.
1018 Creating a shared box is done by simply applying the unary `@`
1019 operator to an expression. The result of the expression will be boxed,
1020 resulting in a box of the right type. Copying a shared box, as happens
1021 during assignment, only copies a pointer, never the contents of the
1025 let x: @int = @10; // New box, refcount of 1
1026 let y = x; // Copy the pointer, increase refcount
1027 // When x and y go out of scope, refcount goes to 0, box is freed
1030 Shared boxes never cross task boundaries.
1032 > ***Note:*** shared boxes are currently reclaimed through reference
1033 > counting and cycle collection, but we will switch to a tracing
1034 > garbage collector.
1038 In contrast to shared boxes, unique boxes have a single owner and thus
1039 two unique boxes may not refer to the same memory. All unique boxes
1040 across all tasks are allocated on a single _exchange heap_, where
1041 their uniquely owned nature allows them to be passed between tasks.
1043 Because unique boxes are uniquely owned, copying them involves allocating
1044 a new unique box and duplicating the contents. Copying unique boxes
1045 is expensive so the compiler will complain if you do.
1049 let y = x; // error: copying a non-implicitly copyable type
1052 If you really want to copy a unique box you must say so explicitly.
1059 This is where the 'move' (`<-`) operator comes in. It is similar to
1060 `=`, but it de-initializes its source. Thus, the unique box can move
1061 from `x` to `y`, without violating the constraint that it only has a
1062 single owner (if you used assignment instead of the move operator, the
1063 box would, in principle, be copied).
1070 > ***Note:*** this discussion of copying vs moving does not account
1071 > for the "last use" rules that automatically promote copy operations
1072 > to moves. This is an evolving area of the language that will
1073 > continue to change.
1075 Unique boxes, when they do not contain any shared boxes, can be sent
1076 to other tasks. The sending task will give up ownership of the box,
1077 and won't be able to access it afterwards. The receiving task will
1078 become the sole owner of the box.
1080 ## Borrowed pointers
1082 Rust borrowed pointers are a general purpose reference/pointer type,
1083 similar to the C++ reference type, but guaranteed to point to valid
1084 memory. In contrast to unique pointers, where the holder of a unique
1085 pointer is the owner of the pointed-to memory, borrowed pointers never
1086 imply ownership. Pointers may be borrowed from any type, in which case
1087 the pointer is guaranteed not to outlive the value it points to.
1090 # fn work_with_foo_by_pointer(f: &~str) { }
1092 work_with_foo_by_pointer(&foo);
1095 The following shows an example of what is _not_ possible with borrowed
1096 pointers. If you were able to write this then the pointer to `foo`
1097 would outlive `foo` itself.
1107 > ***Note:*** borrowed pointers are a new addition to the language.
1108 > They are not used extensively yet but are expected to become the
1109 > pointer type used in many common situations, in particular for
1110 > by-reference argument passing. Rust's current solution for passing
1111 > arguments by reference is [argument modes](#argument-passing).
1115 All pointer types have a mutable variant, written `@mut T` or `~mut
1116 T`. Given such a pointer, you can write to its contents by combining
1117 the dereference operator with a mutating action.
1120 fn increase_contents(pt: @mut int) {
1127 Vectors are a contiguous section of memory containing zero or more
1128 values of the same type. Like other types in Rust, vectors can be
1129 stored on the stack, the local heap, or the exchange heap.
1133 Almond, AntiqueBrass, Apricot,
1134 Aquamarine, Asparagus, AtomicTangerine,
1135 BananaMania, Beaver, Bittersweet
1138 // A stack vector of crayons
1139 let stack_crayons: &[Crayon] = &[Almond, AntiqueBrass, Apricot];
1140 // A local heap (shared) vector of crayons
1141 let local_crayons: @[Crayon] = @[Aquamarine, Asparagus, AtomicTangerine];
1142 // An exchange heap (unique) vector of crayons
1143 let exchange_crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];
1146 > ***Note:*** Until recently Rust only had unique vectors, using the
1147 > unadorned `[]` syntax for literals. This syntax is still supported
1148 > but is deprecated. In the future it will probably represent some
1149 > "reasonable default" vector type.
1151 > Unique vectors are the currently-recommended vector type for general
1152 > use as they are the most tested and well-supported by existing
1153 > libraries. There will be a gradual shift toward using more
1154 > stack and local vectors in the coming releases.
1156 Vector literals are enclosed in square brackets and dereferencing is
1157 also done with square brackets (zero-based):
1160 # enum Crayon { Almond, AntiqueBrass, Apricot,
1161 # Aquamarine, Asparagus, AtomicTangerine,
1162 # BananaMania, Beaver, Bittersweet };
1163 # fn draw_scene(c: Crayon) { }
1165 let crayons = ~[BananaMania, Beaver, Bittersweet];
1167 Bittersweet => draw_scene(crayons[0]),
1172 By default, vectors are immutable—you can not replace their elements.
1173 The type written as `~[mut T]` is a vector with mutable
1174 elements. Mutable vector literals are written `~[mut]` (empty) or `~[mut
1175 1, 2, 3]` (with elements).
1178 # enum Crayon { Almond, AntiqueBrass, Apricot,
1179 # Aquamarine, Asparagus, AtomicTangerine,
1180 # BananaMania, Beaver, Bittersweet };
1182 let crayons = ~[mut BananaMania, Beaver, Bittersweet];
1183 crayons[0] = AtomicTangerine;
1186 The `+` operator means concatenation when applied to vector types.
1189 # enum Crayon { Almond, AntiqueBrass, Apricot,
1190 # Aquamarine, Asparagus, AtomicTangerine,
1191 # BananaMania, Beaver, Bittersweet };
1193 let my_crayons = ~[Almond, AntiqueBrass, Apricot];
1194 let your_crayons = ~[BananaMania, Beaver, Bittersweet];
1196 let our_crayons = my_crayons + your_crayons;
1199 The `+=` operator also works as expected, provided the assignee
1200 lives in a mutable slot.
1203 # enum Crayon { Almond, AntiqueBrass, Apricot,
1204 # Aquamarine, Asparagus, AtomicTangerine,
1205 # BananaMania, Beaver, Bittersweet };
1207 let mut my_crayons = ~[Almond, AntiqueBrass, Apricot];
1208 let your_crayons = ~[BananaMania, Beaver, Bittersweet];
1210 my_crayons += your_crayons;
1213 ## Vector and string methods
1215 Both vectors and strings support a number of useful
1216 [methods](#implementation). While we haven't covered methods yet,
1217 most vector functionality is provided by methods, so let's have a
1218 brief look at a few common ones.
1223 # Almond, AntiqueBrass, Apricot,
1224 # Aquamarine, Asparagus, AtomicTangerine,
1225 # BananaMania, Beaver, Bittersweet
1227 # fn unwrap_crayon(c: Crayon) -> int { 0 }
1228 # fn eat_crayon_wax(i: int) { }
1229 # fn store_crayon_in_nasal_cavity(i: uint, c: Crayon) { }
1230 # fn crayon_to_str(c: Crayon) -> ~str { ~"" }
1232 let crayons = ~[Almond, AntiqueBrass, Apricot];
1234 // Check the length of the vector
1235 assert crayons.len() == 3;
1236 assert !crayons.is_empty();
1238 // Iterate over a vector, obtaining a pointer to each element
1239 for crayons.each |crayon| {
1240 let delicious_crayon_wax = unwrap_crayon(*crayon);
1241 eat_crayon_wax(delicious_crayon_wax);
1244 // Map vector elements
1245 let crayon_names = crayons.map(|v| crayon_to_str(*v));
1246 let favorite_crayon_name = crayon_names[0];
1248 // Remove whitespace from before and after the string
1249 let new_favorite_crayon_name = favorite_crayon_name.trim();
1251 if favorite_crayon_name.len() > 5 {
1252 // Create a substring
1253 println(favorite_crayon_name.substr(0, 5));
1259 Named functions, like those we've seen so far, may not refer to local
1260 variables declared outside the function - they do not "close over
1261 their environment". For example, you couldn't write the following:
1267 return foo; // `bar` cannot refer to `foo`
1271 Rust also supports _closures_, functions that can access variables in
1272 the enclosing scope.
1275 # use println = io::println;
1276 fn call_closure_with_ten(b: fn(int)) { b(10); }
1278 let captured_var = 20;
1279 let closure = |arg| println(fmt!("captured_var=%d, arg=%d", captured_var, arg));
1281 call_closure_with_ten(closure);
1284 Closures begin with the argument list between bars and are followed by
1285 a single expression. The types of the arguments are generally omitted,
1286 as is the return type, because the compiler can almost always infer
1287 them. In the rare case where the compiler needs assistance though, the
1288 arguments and return types may be annotated.
1291 # type mygoodness = fn(~str) -> ~str; type what_the = int;
1292 let bloop = |well, oh: mygoodness| -> what_the { fail oh(well) };
1295 There are several forms of closure, each with its own role. The most
1296 common, called a _stack closure_, has type `fn&` and can directly
1297 access local variables in the enclosing scope.
1301 (~[1, 2, 3]).map(|x| if *x > max { max = *x });
1304 Stack closures are very efficient because their environment is
1305 allocated on the call stack and refers by pointer to captured
1306 locals. To ensure that stack closures never outlive the local
1307 variables to which they refer, they can only be used in argument
1308 position and cannot be stored in structures nor returned from
1309 functions. Despite the limitations stack closures are used
1310 pervasively in Rust code.
1314 When you need to store a closure in a data structure, a stack closure
1315 will not do, since the compiler will refuse to let you store it. For
1316 this purpose, Rust provides a type of closure that has an arbitrary
1317 lifetime, written `fn@` (boxed closure, analogous to the `@` pointer
1318 type described earlier).
1320 A boxed closure does not directly access its environment, but merely
1321 copies out the values that it closes over into a private data
1322 structure. This means that it can not assign to these variables, and
1323 will not 'see' updates to them.
1325 This code creates a closure that adds a given string to its argument,
1326 returns it from a function, and then calls it:
1331 fn mk_appender(suffix: ~str) -> fn@(~str) -> ~str {
1332 return fn@(s: ~str) -> ~str { s + suffix };
1336 let shout = mk_appender(~"!");
1337 io::println(shout(~"hey ho, let's go"));
1341 This example uses the long closure syntax, `fn@(s: ~str) ...`,
1342 making the fact that we are declaring a box closure explicit. In
1343 practice boxed closures are usually defined with the short closure
1344 syntax introduced earlier, in which case the compiler will infer
1345 the type of closure. Thus our boxed closure example could also
1349 fn mk_appender(suffix: ~str) -> fn@(~str) -> ~str {
1350 return |s| s + suffix;
1356 Unique closures, written `fn~` in analogy to the `~` pointer type,
1357 hold on to things that can safely be sent between
1358 processes. They copy the values they close over, much like boxed
1359 closures, but they also 'own' them—meaning no other code can access
1360 them. Unique closures are used in concurrent code, particularly
1361 for spawning [tasks](#tasks).
1363 ## Closure compatibility
1365 A nice property of Rust closures is that you can pass any kind of
1366 closure (as long as the arguments and return types match) to functions
1367 that expect a `fn()`. Thus, when writing a higher-order function that
1368 wants to do nothing with its function argument beyond calling it, you
1369 should almost always specify the type of that argument as `fn()`, so
1370 that callers have the flexibility to pass whatever they want.
1373 fn call_twice(f: fn()) { f(); f(); }
1374 call_twice(|| { ~"I am an inferred stack closure"; } );
1375 call_twice(fn&() { ~"I am also a stack closure"; } );
1376 call_twice(fn@() { ~"I am a boxed closure"; });
1377 call_twice(fn~() { ~"I am a unique closure"; });
1378 fn bare_function() { ~"I am a plain function"; }
1379 call_twice(bare_function);
1384 Closures in Rust are frequently used in combination with higher-order
1385 functions to simulate control structures like `if` and
1386 `loop`. Consider this function that iterates over a vector of
1387 integers, passing in a pointer to each integer in the vector:
1390 fn each(v: ~[int], op: fn(v: &int)) {
1399 The reason we pass in a *pointer* to an integer rather than the
1400 integer itself is that this is how the actual `each()` function for
1401 vectors works. Using a pointer means that the function can be used
1402 for vectors of any type, even large records that would be impractical
1403 to copy out of the vector on each iteration. As a caller, if we use a
1404 closure to provide the final operator argument, we can write it in a
1405 way that has a pleasant, block-like structure.
1408 # fn each(v: ~[int], op: fn(v: &int)) { }
1409 # fn do_some_work(i: int) { }
1410 each(~[1, 2, 3], |n| {
1416 This is such a useful pattern that Rust has a special form of function
1417 call that can be written more like a built-in control structure:
1420 # fn each(v: ~[int], op: fn(v: &int)) { }
1421 # fn do_some_work(i: int) { }
1422 do each(~[1, 2, 3]) |n| {
1428 The call is prefixed with the keyword `do` and, instead of writing the
1429 final closure inside the argument list it is moved outside of the
1430 parenthesis where it looks visually more like a typical block of
1431 code. The `do` expression is purely syntactic sugar for a call that
1432 takes a final closure argument.
1434 `do` is often used for task spawning.
1440 debug!("I'm a task, whatever");
1444 That's nice, but look at all those bars and parentheses - that's two empty
1445 argument lists back to back. Wouldn't it be great if they weren't
1455 Empty argument lists can be omitted from `do` expressions.
1459 Most iteration in Rust is done with `for` loops. Like `do`,
1460 `for` is a nice syntax for doing control flow with closures.
1461 Additionally, within a `for` loop, `break`, `again`, and `return`
1462 work just as they do with `while` and `loop`.
1464 Consider again our `each` function, this time improved to
1465 break early when the iteratee returns `false`:
1468 fn each(v: ~[int], op: fn(v: &int) -> bool) {
1479 And using this function to iterate over a vector:
1482 # use each = vec::each;
1483 # use println = io::println;
1484 each(~[2, 4, 8, 5, 16], |n| {
1486 println(~"found odd number!");
1492 With `for`, functions like `each` can be treated more
1493 like builtin looping structures. When calling `each`
1494 in a `for` loop, instead of returning `false` to break
1495 out of the loop, you just write `break`. To skip ahead
1496 to the next iteration, write `again`.
1499 # use each = vec::each;
1500 # use println = io::println;
1501 for each(~[2, 4, 8, 5, 16]) |n| {
1503 println(~"found odd number!");
1509 As an added bonus, you can use the `return` keyword, which is not
1510 normally allowed in closures, in a block that appears as the body of a
1511 `for` loop — this will cause a return to happen from the outer
1512 function, not just the loop body.
1515 # use each = vec::each;
1516 fn contains(v: ~[int], elt: int) -> bool {
1518 if (*x == elt) { return true; }
1524 `for` syntax only works with stack closures.
1528 ## Generic functions
1530 Throughout this tutorial, we've been defining functions that act only on
1531 single data types. It's a burden to define such functions again and again for
1532 every type they apply to. Thus, Rust allows functions and datatypes to have
1536 fn map<T, U>(vector: &[T], function: fn(v: &T) -> U) -> ~[U] {
1537 let mut accumulator = ~[];
1538 for vec::each(vector) |element| {
1539 vec::push(accumulator, function(element));
1545 When defined with type parameters, this function can be applied to any
1546 type of vector, as long as the type of `function`'s argument and the
1547 type of the vector's content agree with each other.
1549 Inside a generic function, the names of the type parameters
1550 (capitalized by convention) stand for opaque types. You can't look
1551 inside them, but you can pass them around. Note that instances of
1552 generic types are almost always passed by pointer. For example, the
1553 parameter `function()` is supplied with a pointer to a value of type
1554 `T` and not a value of type `T` itself. This ensures that the
1555 function works with the broadest set of types possible, since some
1556 types are expensive or illegal to copy and pass by value.
1558 ## Generic datatypes
1560 Generic `type`, `struct`, and `enum` declarations follow the same pattern:
1573 These declarations produce valid types like `Stack<u8>` and `Maybe<int>`.
1577 Perhaps surprisingly, the 'copy' (duplicate) operation is not defined
1578 for all Rust types. Resource types (classes with destructors) cannot be
1579 copied, and neither can any type whose copying would require copying a
1580 resource (such as records or unique boxes containing a resource).
1582 This complicates handling of generic functions. If you have a type
1583 parameter `T`, can you copy values of that type? In Rust, you can't,
1584 unless you explicitly declare that type parameter to have copyable
1585 'kind'. A kind is a type of type.
1588 // This does not compile
1589 fn head_bad<T>(v: ~[T]) -> T { v[0] }
1591 fn head<T: Copy>(v: ~[T]) -> T { v[0] }
1594 When instantiating a generic function, you can only instantiate it
1595 with types that fit its kinds. So you could not apply `head` to a
1596 resource type. Rust has several kinds that can be used as type bounds:
1598 * `Copy` - Copyable types. All types are copyable unless they
1599 are classes with destructors or otherwise contain
1600 classes with destructors.
1601 * `Send` - Sendable types. All types are sendable unless they
1602 contain shared boxes, closures, or other local-heap-allocated
1604 * `Const` - Constant types. These are types that do not contain
1605 mutable fields nor shared boxes.
1607 > ***Note:*** Rust type kinds are syntactically very similar to
1608 > [traits](#traits) when used as type bounds, and can be
1609 > conveniently thought of as built-in traits. In the future type
1610 > kinds will actually be traits that the compiler has special
1615 Traits are Rust's take on value polymorphism—the thing that
1616 object-oriented languages tend to solve with methods and inheritance.
1617 For example, writing a function that can operate on multiple types of
1620 > ***Note:*** This feature is very new, and will need a few extensions to be
1621 > applicable to more advanced use cases.
1625 A trait consists of a set of methods. A method is a function that
1626 can be applied to a `self` value and a number of arguments, using the
1627 dot notation: `self.foo(arg1, arg2)`.
1629 For example, we could declare the trait `to_str` for things that
1630 can be converted to a string, with a single method of the same name:
1634 fn to_str() -> ~str;
1640 To actually implement a trait for a given type, the `impl` form
1641 is used. This defines implementations of `to_str` for the `int` and
1645 # trait ToStr { fn to_str() -> ~str; }
1647 fn to_str() -> ~str { int::to_str(self, 10u) }
1650 fn to_str() -> ~str { self }
1654 Given these, we may call `1.to_str()` to get `~"1"`, or
1655 `(~"foo").to_str()` to get `~"foo"` again. This is basically a form of
1656 static overloading—when the Rust compiler sees the `to_str` method
1657 call, it looks for an implementation that matches the type with a
1658 method that matches the name, and simply calls that.
1660 ## Bounded type parameters
1662 The useful thing about value polymorphism is that it does not have to
1663 be static. If object-oriented languages only let you call a method on
1664 an object when they knew exactly which sub-type it had, that would not
1665 get you very far. To be able to call methods on types that aren't
1666 known at compile time, it is possible to specify 'bounds' for type
1670 # trait ToStr { fn to_str() -> ~str; }
1671 fn comma_sep<T: ToStr>(elts: ~[T]) -> ~str {
1672 let mut result = ~"", first = true;
1673 for elts.each |elt| {
1674 if first { first = false; }
1675 else { result += ~", "; }
1676 result += elt.to_str();
1682 The syntax for this is similar to the syntax for specifying that a
1683 parameter type has to be copyable (which is, in principle, another
1684 kind of bound). By declaring `T` as conforming to the `to_str`
1685 trait, it becomes possible to call methods from that trait on
1686 values of that type inside the function. It will also cause a
1687 compile-time error when anyone tries to call `comma_sep` on an array
1688 whose element type does not have a `to_str` implementation in scope.
1690 ## Polymorphic traits
1692 Traits may contain type parameters. A trait for
1693 generalized sequence types is:
1698 fn iter(b: fn(v: &T));
1700 impl<T> ~[T]: Seq<T> {
1701 fn len() -> uint { vec::len(self) }
1702 fn iter(b: fn(v: &T)) {
1703 for vec::each(self) |elt| { b(elt); }
1708 The implementation has to explicitly declare the type
1709 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 after the colon in the `impl` -- *refers* to a type, rather than defining one.
1711 The type parameters bound by a trait are in scope in each of the
1712 method declarations. So, re-declaring the type parameter
1713 `T` as an explicit type parameter for `len` -- in either the trait or
1714 the impl -- would be a compile-time error.
1716 ## The `self` type in traits
1718 In a trait, `self` is a special type that you can think of as a
1719 type parameter. An implementation of the trait for any given type
1720 `T` replaces the `self` type parameter with `T`. The following
1721 trait describes types that support an equality operation:
1725 fn equals(&&other: self) -> bool;
1729 fn equals(&&other: int) -> bool { other == self }
1733 Notice that `equals` takes an `int` argument, rather than a `self` argument, in
1734 an implementation for type `int`.
1736 ## Casting to a trait type
1738 The above allows us to define functions that polymorphically act on
1739 values of *an* unknown type that conforms to a given trait.
1740 However, consider this function:
1743 # type Circle = int; type Rectangle = int;
1744 # trait Drawable { fn draw(); }
1745 # impl int: Drawable { fn draw() {} }
1746 # fn new_circle() -> int { 1 }
1747 fn draw_all<T: Drawable>(shapes: ~[T]) {
1748 for shapes.each |shape| { shape.draw(); }
1750 # let c: Circle = new_circle();
1754 You can call that on an array of circles, or an array of squares
1755 (assuming those have suitable `drawable` traits defined), but not
1756 on an array containing both circles and squares.
1758 When this is needed, a trait name can be used as a type, causing
1759 the function to be written simply like this:
1762 # trait Drawable { fn draw(); }
1763 fn draw_all(shapes: ~[Drawable]) {
1764 for shapes.each |shape| { shape.draw(); }
1768 There is no type parameter anymore (since there isn't a single type
1769 that we're calling the function on). Instead, the `drawable` type is
1770 used to refer to a type that is a reference-counted box containing a
1771 value for which a `drawable` implementation exists, combined with
1772 information on where to find the methods for this implementation. This
1773 is very similar to the 'vtables' used in most object-oriented
1776 To construct such a value, you use the `as` operator to cast a value
1780 # type Circle = int; type Rectangle = int;
1781 # trait Drawable { fn draw(); }
1782 # impl int: Drawable { fn draw() {} }
1783 # fn new_circle() -> int { 1 }
1784 # fn new_rectangle() -> int { 2 }
1785 # fn draw_all(shapes: ~[Drawable]) {}
1786 let c: Circle = new_circle();
1787 let r: Rectangle = new_rectangle();
1788 draw_all(~[c as Drawable, r as Drawable]);
1791 This will store the value into a box, along with information about the
1792 implementation (which is looked up in the scope of the cast). The
1793 `drawable` type simply refers to such boxes, and calling methods on it
1794 always works, no matter what implementations are in scope.
1796 Note that the allocation of a box is somewhat more expensive than
1797 simply using a type parameter and passing in the value as-is, and much
1798 more expensive than statically resolved method calls.
1800 ## Trait-less implementations
1802 If you only intend to use an implementation for static overloading,
1803 and there is no trait available that it conforms to, you are free
1804 to leave off the type after the colon. However, this is only possible when you
1805 are defining an implementation in the same module as the receiver
1806 type, and the receiver type is a named type (i.e., an enum or a
1807 class); [single-variant enums](#single_variant_enum) are a common
1810 # Modules and crates
1812 The Rust namespace is divided into modules. Each source file starts
1813 with its own module.
1817 The `mod` keyword can be used to open a new, local module. In the
1818 example below, `chicken` lives in the module `farm`, so, unless you
1819 explicitly import it, you must refer to it by its long name,
1825 fn chicken() -> ~str { ~"cluck cluck" }
1826 fn cow() -> ~str { ~"mooo" }
1829 io::println(farm::chicken());
1833 Modules can be nested to arbitrary depth.
1837 The unit of independent compilation in Rust is the crate. Libraries
1838 tend to be packaged as crates, and your own programs may consist of
1841 When compiling a single `.rs` file, the file acts as the whole crate.
1842 You can compile it with the `--lib` compiler switch to create a shared
1843 library, or without, provided that your file contains a `fn main`
1844 somewhere, to create an executable.
1846 It is also possible to include multiple files in a crate. For this
1847 purpose, you create a `.rc` crate file, which references any number of
1848 `.rs` code files. A crate file could look like this:
1851 #[link(name = "farm", vers = "2.5", author = "mjh")];
1852 #[crate_type = "lib"];
1858 Compiling this file will cause `rustc` to look for files named
1859 `cow.rs`, `chicken.rs`, `horse.rs` in the same directory as the `.rc`
1860 file, compile them all together, and, depending on the presence of the
1861 `crate_type = "lib"` attribute, output a shared library or an executable.
1862 (If the line `#[crate_type = "lib"];` was omitted, `rustc` would create an
1865 The `#[link(...)]` part provides meta information about the module,
1866 which other crates can use to load the right module. More about that
1869 To have a nested directory structure for your source files, you can
1870 nest mods in your `.rc` file:
1879 The compiler will now look for `poultry/chicken.rs` and
1880 `poultry/turkey.rs`, and export their content in `poultry::chicken`
1881 and `poultry::turkey`. You can also provide a `poultry.rs` to add
1882 content to the `poultry` module itself.
1884 ## Using other crates
1886 Having compiled a crate that contains the `#[crate_type = "lib"]`
1887 attribute, you can use it in another crate with a `use`
1888 directive. We've already seen `extern mod std` in several of the
1889 examples, which loads in the [standard library][std].
1891 [std]: http://doc.rust-lang.org/doc/std/index/General.html
1893 `use` directives can appear in a crate file, or at the top level of a
1894 single-file `.rs` crate. They will cause the compiler to search its
1895 library search path (which you can extend with `-L` switch) for a Rust
1896 crate library with the right name.
1898 It is possible to provide more specific information when using an
1902 extern mod myfarm (name = "farm", vers = "2.7");
1905 When a comma-separated list of name/value pairs is given after `use`,
1906 these are matched against the attributes provided in the `link`
1907 attribute of the crate file, and a crate is only used when the two
1908 match. A `name` value can be given to override the name used to search
1909 for the crate. So the above would import the `farm` crate under the
1910 local name `myfarm`.
1912 Our example crate declared this set of `link` attributes:
1915 #[link(name = "farm", vers = "2.5", author = "mjh")];
1918 The version does not match the one provided in the `use` directive, so
1919 unless the compiler can find another crate with the right version
1920 somewhere, it will complain that no matching crate was found.
1924 A set of basic library routines, mostly related to built-in datatypes
1925 and the task system, are always implicitly linked and included in any
1928 This library is documented [here][core].
1930 [core]: http://doc.rust-lang.org/doc/core
1932 ## A minimal example
1934 Now for something that you can actually compile yourself. We have
1939 #[link(name = "mylib", vers = "1.0")];
1940 fn world() -> ~str { ~"world" }
1946 fn main() { io::println(~"hello " + mylib::world()); }
1949 Now compile and run like this (adjust to your platform if necessary):
1952 > rustc --lib mylib.rs
1953 > rustc main.rs -L .
1960 When using identifiers from other modules, it can get tiresome to
1961 qualify them with the full module path every time (especially when
1962 that path is several modules deep). Rust allows you to import
1963 identifiers at the top of a file, module, or block.
1969 println(~"that was easy");
1973 It is also possible to import just the name of a module (`use
1974 std::list;`, then use `list::find`), to import all identifiers exported
1975 by a given module (`use io::*`), or to import a specific set
1976 of identifiers (`use math::{min, max, pi}`).
1978 You can rename an identifier when importing using the `=` operator:
1981 use prnt = io::println;
1986 By default, a module exports everything that it defines. This can be
1987 restricted with `export` directives at the top of the module or file.
1991 export encrypt, decrypt;
1992 const SUPER_SECRET_NUMBER: int = 10;
1993 fn encrypt(n: int) -> int { n + SUPER_SECRET_NUMBER }
1994 fn decrypt(n: int) -> int { n - SUPER_SECRET_NUMBER }
1998 This defines a rock-solid encryption algorithm. Code outside of the
1999 module can refer to the `enc::encrypt` and `enc::decrypt` identifiers
2000 just fine, but it does not have access to `enc::super_secret_number`.
2004 Rust uses three different namespaces: one for modules, one for types,
2005 and one for values. This means that this code is valid:
2011 fn buffalo<buffalo>(+buffalo: buffalo) -> buffalo { buffalo }
2014 let buffalo: buffalo::buffalo = 1;
2015 buffalo::buffalo::<buffalo::buffalo>(buffalo::buffalo(buffalo));
2019 You don't want to write things like that, but it *is* very practical
2020 to not have to worry about name clashes between types, values, and
2025 The resolution process in Rust simply goes up the chain of contexts,
2026 looking for the name in each context. Nested functions and modules
2027 create new contexts inside their parent function or module. A file
2028 that's part of a bigger crate will have that crate's context as its
2031 Identifiers can shadow each other. In this program, `x` is of type
2042 An `use` directive will only import into the namespaces for which
2043 identifiers are actually found. Consider this example:
2046 mod foo { fn bar() {} }
2057 When resolving the type name `bar` in the `quux` definition, the
2058 resolver will first look at local block context for `baz`. This has an
2059 import named `bar`, but that's function, not a value, So it continues
2060 to the `baz` function context and finds a value named `bar` defined
2063 Normally, multiple definitions of the same identifier in a scope are
2064 disallowed. Local variables defined with `let` are an exception to
2065 this—multiple `let` directives can redefine the same variable in a
2066 single scope. When resolving the name of such a variable, the most
2067 recent definition is used.
2077 This makes it possible to rebind a variable without actually mutating
2078 it, which is mostly useful for destructuring (which can rebind, but
2083 Rust supports a system of lightweight tasks, similar to what is found
2084 in Erlang or other actor systems. Rust tasks communicate via messages
2085 and do not share data. However, it is possible to send data without
2086 copying it by making use of [the exchange heap](#unique-boxes), which
2087 allow the sending task to release ownership of a value, so that the
2088 receiving task can keep on using it.
2090 > ***Note:*** As Rust evolves, we expect the task API to grow and
2091 > change somewhat. The tutorial documents the API as it exists today.
2095 Spawning a task is done using the various spawn functions in the
2096 module `task`. Let's begin with the simplest one, `task::spawn()`:
2102 let some_value = 22;
2105 println(~"This executes in the child task.");
2106 println(fmt!("%d", some_value));
2110 The argument to `task::spawn()` is a [unique
2111 closure](#unique-closures) of type `fn~()`, meaning that it takes no
2112 arguments and generates no return value. The effect of `task::spawn()`
2113 is to fire up a child task that will execute the closure in parallel
2118 Now that we have spawned a child task, it would be nice if we could
2119 communicate with it. This is done using *pipes*. Pipes are simply a
2120 pair of endpoints, with one for sending messages and another for
2121 receiving messages. The easiest way to create a pipe is to use
2122 `pipes::stream`. Imagine we wish to perform two expensive
2123 computations in parallel. We might write something like:
2127 use pipes::{stream, Port, Chan};
2129 let (chan, port) = stream();
2132 let result = some_expensive_computation();
2136 some_other_expensive_computation();
2137 let result = port.recv();
2139 # fn some_expensive_computation() -> int { 42 }
2140 # fn some_other_expensive_computation() {}
2143 Let's walk through this code line-by-line. The first line creates a
2144 stream for sending and receiving integers:
2147 # use pipes::stream;
2148 let (chan, port) = stream();
2151 This port is where we will receive the message from the child task
2152 once it is complete. The channel will be used by the child to send a
2153 message to the port. The next statement actually spawns the child:
2156 # use task::{spawn};
2157 # use comm::{Port, Chan};
2158 # fn some_expensive_computation() -> int { 42 }
2159 # let port = Port();
2160 # let chan = port.chan();
2162 let result = some_expensive_computation();
2167 This child will perform the expensive computation send the result
2168 over the channel. (Under the hood, `chan` was captured by the
2169 closure that forms the body of the child task. This capture is
2170 allowed because channels are sendable.)
2172 Finally, the parent continues by performing
2173 some other expensive computation and then waiting for the child's result
2174 to arrive on the port:
2177 # use pipes::{stream, Port, Chan};
2178 # fn some_other_expensive_computation() {}
2179 # let (chan, port) = stream::<int>();
2181 some_other_expensive_computation();
2182 let result = port.recv();
2185 ## Creating a task with a bi-directional communication path
2187 A very common thing to do is to spawn a child task where the parent
2188 and child both need to exchange messages with each other. The
2189 function `std::comm::DuplexStream()` supports this pattern. We'll
2190 look briefly at how it is used.
2192 To see how `spawn_conversation()` works, we will create a child task
2193 that receives `uint` messages, converts them to a string, and sends
2194 the string in response. The child terminates when `0` is received.
2195 Here is the function that implements the child task:
2198 # use std::comm::DuplexStream;
2199 # use pipes::{Port, Chan};
2200 fn stringifier(channel: &DuplexStream<~str, uint>) {
2201 let mut value: uint;
2203 value = channel.recv();
2204 channel.send(uint::to_str(value, 10u));
2205 if value == 0u { break; }
2210 The implementation of `DuplexStream` supports both sending and
2211 receiving. The `stringifier` function takes a `DuplexStream` that can
2212 send strings (the first type parameter) and receive `uint` messages
2213 (the second type parameter). The body itself simply loops, reading
2214 from the channel and then sending its response back. The actual
2215 response itself is simply the strified version of the received value,
2216 `uint::to_str(value)`.
2218 Here is the code for the parent task:
2221 # use std::comm::DuplexStream;
2222 # use pipes::{Port, Chan};
2224 # fn stringifier(channel: &DuplexStream<~str, uint>) {
2225 # let mut value: uint;
2227 # value = channel.recv();
2228 # channel.send(uint::to_str(value, 10u));
2229 # if value == 0u { break; }
2234 let (from_child, to_child) = DuplexStream();
2237 stringifier(&to_child);
2240 from_child.send(22u);
2241 assert from_child.recv() == ~"22";
2243 from_child.send(23u);
2244 from_child.send(0u);
2246 assert from_child.recv() == ~"23";
2247 assert from_child.recv() == ~"0";
2252 The parent task first calls `DuplexStream` to create a pair of bidirectional endpoints. It then uses `task::spawn` to create the child task, which captures one end of the communication channel. As a result, both parent
2253 and child can send and receive data to and from the other.
2257 The Rust language has a facility for testing built into the language.
2258 Tests can be interspersed with other code, and annotated with the
2259 `#[test]` attribute.
2262 # // FIXME: xfailed because test_twice is a #[test] function it's not
2263 # // getting compiled
2266 fn twice(x: int) -> int { x + x }
2272 assert twice(i) == 2 * i;
2278 When you compile the program normally, the `test_twice` function will
2279 not be included. To compile and run such tests, compile with the
2280 `--test` flag, and then run the result:
2283 > rustc --test twice.rs
2286 test test_twice ... ok
2287 result: ok. 1 passed; 0 failed; 0 ignored
2290 Or, if we change the file to fail, for example by replacing `x + x`
2295 test test_twice ... FAILED
2298 result: FAILED. 0 passed; 1 failed; 0 ignored
2301 You can pass a command-line argument to a program compiled with
2302 `--test` to run only the tests whose name matches the given string. If
2303 we had, for example, test functions `test_twice`, `test_once_1`, and
2304 `test_once_2`, running our program with `./twice test_once` would run
2305 the latter two, and running it with `./twice test_once_2` would run
2308 To indicate that a test is supposed to fail instead of pass, you can
2309 give it a `#[should_fail]` attribute.
2314 fn divide(a: float, b: float) -> float {
2315 if b == 0f { fail; }
2321 fn divide_by_zero() { divide(1f, 0f); }
2326 To disable a test completely, add an `#[ignore]` attribute. Running a
2327 test runner (the program compiled with `--test`) with an `--ignored`
2328 command-line flag will cause it to also run the tests labelled as
2331 A program compiled as a test runner will have the configuration flag
2332 `test` defined, so that you can add code that won't be included in a
2333 normal compile with the `#[cfg(test)]` attribute (for a full explanation
2334 of attributes, see the [language reference](rust.html)).