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.3.tar.gz
127 $ tar -xzf rust-0.3.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.3.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
197 Other editors are not provided for yet. If you end up writing a Rust
198 mode for your favorite editor, let us know so that we can link to it.
204 Assuming you've programmed in any C-family language (C++, Java,
205 JavaScript, C#, or PHP), Rust will feel familiar. The main surface
206 difference to be aware of is that the bodies of `if` statements and of
207 `while` loops *have* to be wrapped in brackets. Single-statement,
208 bracket-less bodies are not allowed.
210 Accounting for these differences, the surface syntax of Rust
211 statements and expressions is C-like. Function calls are written
212 `myfunc(arg1, arg2)`, operators have mostly the same name and
213 precedence that they have in C, comments look the same, and constructs
214 like `if` and `while` are available:
221 /* Ensure that basic math works. */
235 Though it isn't apparent in all code, there is a fundamental
236 difference between Rust's syntax and its predecessors in this family
237 of languages. Many constructs that are statements in C are expressions
238 in Rust. This allows Rust to be more expressive. For example, you might
239 write a piece of code like this:
242 # let item = "salad";
246 } else if item == "muffin" {
253 But, in Rust, you don't have to repeat the name `price`:
256 # let item = "salad";
257 let price = if item == "salad" { 3.50 }
258 else if item == "muffin" { 2.25 }
262 Both pieces of code are exactly equivalentāthey assign a value to `price`
263 depending on the condition that holds. Note that the semicolons are omitted
264 from the second snippet. This is important; the lack of a semicolon after the
265 last statement in a braced block gives the whole block the value of that last
268 Put another way, the semicolon in Rust *ignores the value of an expression*.
269 Thus, if the branches of the `if` had looked like `{ 4; }`, the above example
270 would simply assign nil (void) to `price`. But without the semicolon, each
271 branch has a different value, and `price` gets the value of the branch that
274 This feature also works for function bodies. This function returns a boolean:
277 fn is_four(x: int) -> bool { x == 4 }
280 In short, everything that's not a declaration (`let` for variables,
281 `fn` for functions, et cetera) is an expression.
283 If all those things are expressions, you might conclude that you have
284 to add a terminating semicolon after *every* statement, even ones that
285 are not traditionally terminated with a semicolon in C (like `while`).
286 That is not the case, though. Expressions that end in a block only
287 need a semicolon if that block contains a trailing expression. `while`
288 loops do not allow trailing expressions, and `if` statements tend to
289 only have a trailing expression when you want to use their value for
290 somethingāin which case you'll have embedded it in a bigger statement,
291 like the `let x = ...` example above.
295 Rust identifiers follow the same rules as C; they start with an alphabetic
296 character or an underscore, and after that may contain any sequence of
297 alphabetic characters, numbers, or underscores. The preferred style is to
298 begin function, variable, and module names with a lowercase letter, using
299 underscores where they help readability, while beginning types with a capital
302 The double-colon (`::`) is used as a module separator, so
303 `io::println` means 'the thing named `println` in the module
306 ## Variable declaration
308 The `let` keyword, as we've seen, introduces a local variable. Local
309 variables are immutable by default: `let mut` can be used to introduce
310 a local variable that can be reassigned. Global constants can be
311 defined with `const`:
314 const REPEAT: int = 5;
318 while count < REPEAT {
325 Local variables may shadow earlier declarations, making the earlier variables
329 let my_favorite_value: float = 57.8;
330 let my_favorite_value: int = my_favorite_value as int;
335 The basic types are written like this:
338 : Nil, the type that has only a single value.
341 : Boolean type, with values `true` and `false`.
344 : A machine-pointer-sized integer.
347 : A machine-pointer-sized unsigned integer.
349 `i8`, `i16`, `i32`, `i64`
350 : Signed integers with a specific size (in bits).
352 `u8`, `u16`, `u32`, `u64`
353 : Unsigned integers with a specific size.
356 : The largest floating-point type efficiently supported on the target
360 : Floating-point types with a specific size.
363 : A Unicode character (32 bits).
365 These can be combined in composite types, which will be described in
366 more detail later on (the `T`s here stand for any other type):
369 : Vector (like an array in other languages) with N elements.
372 : Mutable vector with N elements.
375 : Tuple type. Any arity above 1 is supported.
380 Some types can only be manipulated by pointer, never directly. For instance,
381 you cannot refer to a string (`str`); instead you refer to a pointer to a
382 string (`@str`, `~str`, or `&str`). These *dynamically-sized* types consist
385 `fn(arg1: T1, arg2: T2) -> T3`
389 : String type (in UTF-8).
392 : Vector with unknown size (also called a slice).
395 : Mutable vector with unknown size.
397 Types can be given names with `type` declarations:
400 type MonsterSize = uint;
403 This will provide a synonym, `MonsterSize`, for unsigned integers. It will not
404 actually create a new, incompatible typeā`MonsterSize` and `uint` can be used
405 interchangeably, and using one where the other is expected is not a type
406 error. Read about [single-variant enums](#single_variant_enum)
407 further on if you need to create a type name that's not just a
412 The `-> bool` in the `is_four` example is the way a function's return
413 type is written. For functions that do not return a meaningful value,
414 you can optionally say `-> ()`, but usually the return annotation is simply
415 left off, as in the `fn main() { ... }` examples we've seen earlier.
417 Every argument to a function must have its type declared (for example,
418 `x: int`). Inside the function, type inference will be able to
419 automatically deduce the type of most locals (generic functions, which
420 we'll come back to later, will occasionally need additional
421 annotation). Locals can be written either with or without a type
425 // The type of this vector will be inferred based on its use.
427 # vec::map(x, fn&(&&_y:int) -> int { _y });
428 // Explicitly say this is a vector of zero integers.
429 let y: [int * 0] = [];
434 Integers can be written in decimal (`144`), hexadecimal (`0x90`), and
435 binary (`0b10010000`) base.
437 If you write an integer literal without a suffix (`3`, `-500`, etc.),
438 the Rust compiler will try to infer its type based on type annotations
439 and function signatures in the surrounding program. In the absence of any type
440 annotations at all, Rust will assume that an unsuffixed integer literal has
441 type `int`. It's also possible to avoid any type ambiguity by writing integer
442 literals with a suffix. For example:
446 log(error, x); // x is an int
448 log(error, y); // y is an uint
451 Note that, in Rust, no implicit conversion between integer types
452 happens. If you are adding one to a variable of type `uint`, saying
453 `+= 1u8` will give you a type error.
455 Floating point numbers are written `0.0`, `1e6`, or `2.1e-4`. Without
456 a suffix, the literal is assumed to be of type `float`. Suffixes `f` (32-bit)
457 and `l` (64-bit) can be used to create literals of a specific type.
461 The nil literal is written just like the type: `()`. The keywords
462 `true` and `false` produce the boolean literals.
464 Character literals are written between single quotes, as in `'x'`. Just as in
465 C, Rust understands a number of character escapes, using the backslash
466 character, `\n`, `\r`, and `\t` being the most common.
468 String literals allow the same escape sequences. They are written
469 between double quotes (`"hello"`). Rust strings may contain newlines.
473 Rust's set of operators contains very few surprises. Arithmetic is done with
474 `*`, `/`, `%`, `+`, and `-` (multiply, divide, remainder, plus, minus). `-` is
475 also a unary prefix operator that does negation. As in C, the bit operators
476 `>>`, `<<`, `&`, `|`, and `^` are also supported.
478 Note that, if applied to an integer value, `!` flips all the bits (like `~` in
481 The comparison operators are the traditional `==`, `!=`, `<`, `>`,
482 `<=`, and `>=`. Short-circuiting (lazy) boolean operators are written
483 `&&` (and) and `||` (or).
485 For type casting, Rust uses the binary `as` operator. It takes an
486 expression on the left side and a type on the right side and will,
487 if a meaningful conversion exists, convert the result of the
488 expression to the given type.
492 let y: uint = x as uint;
496 The main difference with C is that `++` and `--` are missing, and that
497 the logical bitwise operators have higher precedence ā in C, `x & 2 > 0`
498 comes out as `x & (2 > 0)`, in Rust, it means `(x & 2) > 0`, which is
499 more likely to be what you expect (unless you are a C veteran).
503 *Syntax extensions* are special forms that are not built into the language,
504 but are instead provided by the libraries. To make it clear to the reader when
505 a syntax extension is being used, the names of all syntax extensions end with
506 `!`. The standard library defines a few syntax extensions, the most useful of
507 which is `fmt!`, a `sprintf`-style text formatter that is expanded at compile
511 io::println(fmt!("%s is %d", ~"the answer", 42));
514 `fmt!` supports most of the directives that [printf][pf] supports, but
515 will give you a compile-time error when the types of the directives
516 don't match the types of the arguments.
518 [pf]: http://en.cppreference.com/w/cpp/io/c/fprintf
520 You can define your own syntax extensions with the macro system, which is out
521 of scope of this tutorial.
527 We've seen `if` pass by a few times already. To recap, braces are
528 compulsory, an optional `else` clause can be appended, and multiple
529 `if`/`else` constructs can be chained together:
533 io::println(~"that's odd");
535 io::println(~"right");
537 io::println(~"neither true nor false");
541 The condition given to an `if` construct *must* be of type boolean (no
542 implicit conversion happens). If the arms return a value, this value
543 must be of the same type for every arm in which control reaches the
547 fn signum(x: int) -> int {
556 Rust's `match` construct is a generalized, cleaned-up version of C's
557 `switch` construct. You provide it with a value and a number of *arms*,
558 each labelled with a pattern, and the code will attempt to match each pattern
559 in order. For the first one that matches, the arm is executed.
564 0 => io::println("zero"),
565 1 | 2 => io::println("one or two"),
566 3..10 => io::println("three to ten"),
567 _ => io::println("something else")
571 There is no 'falling through' between arms, as in Cāonly one arm is
572 executed, and it doesn't have to explicitly `break` out of the
573 construct when it is finished.
575 The part to the left of the arrow `=>` is called the *pattern*. Literals are
576 valid patterns and will match only their own value. The pipe operator
577 (`|`) can be used to assign multiple patterns to a single arm. Ranges
578 of numeric literal patterns can be expressed with two dots, as in `M..N`. The
579 underscore (`_`) is a wildcard pattern that matches everything.
581 The patterns in an match arm are followed by a fat arrow, `=>`, then an
582 expression to evaluate. Each case is separated by commas. It's often
583 convenient to use a block expression for a case, in which case the
593 io::println("something else")
598 `match` constructs must be *exhaustive*: they must have an arm covering every
599 possible case. For example, if the arm with the wildcard pattern was left off
600 in the above example, the typechecker would reject it.
602 A powerful application of pattern matching is *destructuring*, where
603 you use the matching to get at the contents of data types. Remember
604 that `(float, float)` is a tuple of two floats:
607 use float::consts::pi;
608 fn angle(vector: (float, float)) -> float {
610 (0f, y) if y < 0f => 1.5 * pi,
612 (x, y) => float::atan(y / x)
617 A variable name in a pattern matches everything, *and* binds that name
618 to the value of the matched thing inside of the arm block. Thus, `(0f,
619 y)` matches any tuple whose first element is zero, and binds `y` to
620 the second element. `(x, y)` matches any tuple, and binds both
621 elements to a variable.
623 Any `match` arm can have a guard clause (written `if EXPR`), which is
624 an expression of type `bool` that determines, after the pattern is
625 found to match, whether the arm is taken or not. The variables bound
626 by the pattern are available in this guard expression.
630 You've already seen simple `let` bindings. `let` is also a little fancier: it
631 is possible to use destructuring patterns in it. For example, you can say this
632 to extract the fields from a tuple:
635 # fn get_tuple_of_two_ints() -> (int, int) { (1, 1) }
636 let (a, b) = get_tuple_of_two_ints();
639 This will introduce two new variables, `a` and `b`, bound to the
640 content of the tuple.
642 You may only use *irrefutable* patternsāpatterns that can never fail to
643 matchāin let bindings. Other types of patterns, such as literals, are
648 `while` produces a loop that runs as long as its given condition
649 (which must have type `bool`) evaluates to true. Inside a loop, the
650 keyword `break` can be used to abort the loop, and `again` can be used
651 to abort the current iteration and continue with the next.
654 let mut cake_amount = 8;
655 while cake_amount > 0 {
660 `loop` is the preferred way of writing `while true`:
666 if x % 5 == 0 { break; }
667 io::println(int::str(x));
671 This code prints out a weird sequence of numbers and stops as soon as
672 it finds one that can be divided by five.
674 For more involved iteration, such as going over the elements of a
675 collection, Rust uses higher-order functions. We'll come back to those
680 Like all other static declarations, such as `type`, functions can be
681 declared both at the top level and inside other functions (or modules,
682 which we'll come back to [later](#modules-and-crates)).
684 We've already seen several function definitions. They are introduced
685 with the `fn` keyword, the type of arguments are specified following
686 colons and the return type follows the arrow.
689 fn repeat(string: &str, count: int) -> ~str {
690 let mut result = ~"";
698 The `return` keyword immediately returns from the body of a function. It
699 is optionally followed by an expression to return. A function can
700 also return a value by having its top level block produce an
704 # const copernicus: int = 0;
705 fn int_to_str(i: int) -> ~str {
715 # const copernicus: int = 0;
716 fn int_to_str(i: int) -> ~str {
717 if i == copernicus { ~"tube sock" }
722 Functions that do not return a value are said to return nil, `()`,
723 and both the return type and the return value may be omitted from
724 the definition. The following two functions are equivalent.
727 fn do_nothing_the_hard_way() -> () { return (); }
729 fn do_nothing_the_easy_way() { }
734 The core datatypes of Rust are structs, enums (tagged unions, algebraic data
735 types), and tuples. They are immutable by default.
738 struct Point { x: float, y: float }
741 Circle(Point, float),
742 Rectangle(Point, Point)
748 Rust struct types must be declared before they are used using the `struct`
749 syntax: `struct Name { field1: T1, field2: T2 [, ...] }`, where `T1`, `T2`,
750 ... denote types. To construct a struct, use the same syntax, but leave off
751 the `struct`; for example: `Point { x: 1.0, y: 2.0 }`.
753 Structs are quite similar to C structs and are even laid out the same way in
754 memory (so you can read from a Rust struct in C, and vice-versa). The dot
755 operator is used to access struct fields (`mypoint.x`).
757 Fields that you want to mutate must be explicitly marked `mut`.
766 With a value of such a type, you can do `mystack.head += 1`. If `mut` were
767 omitted from the type, such an assignment would result in a type error.
771 Structs can be destructured in `match` patterns. The basic syntax is
772 `Name {fieldname: pattern, ...}`:
774 # struct Point { x: float, y: float }
775 # let mypoint = Point { x: 0.0, y: 0.0 };
777 Point { x: 0.0, y: y } => { io::println(y.to_str()); }
778 Point { x: x, y: y } => { io::println(x.to_str() + " " + y.to_str()); }
782 In general, the field names of a struct do not have to appear in the same
783 order they appear in the type. When you are not interested in all
784 the fields of a struct, a struct pattern may end with `, _` (as in
785 `Name {field1, _}`) to indicate that you're ignoring all other fields.
789 Enums are datatypes that have several alternate representations. For
790 example, consider the type shown earlier:
793 # struct Point { x: float, y: float }
795 Circle(Point, float),
796 Rectangle(Point, Point)
800 A value of this type is either a Circle, in which case it contains a
801 point struct and a float, or a Rectangle, in which case it contains
802 two point records. The run-time representation of such a value
803 includes an identifier of the actual form that it holds, much like the
804 'tagged union' pattern in C, but with better ergonomics.
806 The above declaration will define a type `shape` that can be used to
807 refer to such shapes, and two functions, `circle` and `rectangle`,
808 which can be used to construct values of the type (taking arguments of
809 the specified types). So `circle({x: 0f, y: 0f}, 10f)` is the way to
812 Enum variants need not have type parameters. This, for example, is
813 equivalent to a C enum:
824 This will define `north`, `east`, `south`, and `west` as constants,
825 all of which have type `direction`.
827 When an enum is C-like, that is, when none of the variants have
828 parameters, it is possible to explicitly set the discriminator values
839 If an explicit discriminator is not specified for a variant, the value
840 defaults to the value of the previous variant plus one. If the first
841 variant does not have a discriminator, it defaults to 0. For example,
842 the value of `north` is 0, `east` is 1, etc.
844 When an enum is C-like the `as` cast operator can be used to get the
845 discriminator's value.
847 <a name="single_variant_enum"></a>
849 There is a special case for enums with a single variant. These are
850 used to define new types in such a way that the new name is not just a
851 synonym for an existing type, but its own distinct type. If you say:
857 That is a shorthand for this:
860 enum gizmo_id { gizmo_id(int) }
863 Enum types like this can have their content extracted with the
864 dereference (`*`) unary operator:
867 # enum gizmo_id = int;
868 let my_gizmo_id = gizmo_id(10);
869 let id_int: int = *my_gizmo_id;
874 For enum types with multiple variants, destructuring is the only way to
875 get at their contents. All variant constructors can be used as
876 patterns, as in this definition of `area`:
879 # type point = {x: float, y: float};
880 # enum shape { circle(point, float), rectangle(point, point) }
881 fn area(sh: shape) -> float {
883 circle(_, size) => float::consts::pi * size * size,
884 rectangle({x, y}, {x: x2, y: y2}) => (x2 - x) * (y2 - y)
889 Another example, matching nullary enum variants:
892 # type point = {x: float, y: float};
893 # enum direction { north, east, south, west }
894 fn point_from_direction(dir: direction) -> point {
896 north => {x: 0f, y: 1f},
897 east => {x: 1f, y: 0f},
898 south => {x: 0f, y: -1f},
899 west => {x: -1f, y: 0f}
906 Tuples in Rust behave exactly like records, except that their fields
907 do not have names (and can thus not be accessed with dot notation).
908 Tuples can have any arity except for 0 or 1 (though you may consider
909 nil, `()`, as the empty tuple if you like).
912 let mytup: (int, int, float) = (10, 20, 30.0);
914 (a, b, c) => log(info, a + b + (c as int))
918 # The Rust memory model
920 At this junction let's take a detour to explain the concepts involved
921 in Rust's memory model. Rust has a very particular approach to
922 memory management that plays a significant role in shaping the "feel"
923 of the language. Understanding the memory landscape will illuminate
924 several of Rust's unique features as we encounter them.
926 Rust has three competing goals that inform its view of memory:
928 * Memory safety: memory that is managed by and is accessible to the
929 Rust language must be guaranteed to be valid; under normal
930 circumstances it must be impossible for Rust to trigger a
931 segmentation fault or leak memory
932 * Performance: high-performance low-level code must be able to employ
933 a number of allocation strategies; low-performance high-level code
934 must be able to employ a single, garbage-collection-based, heap
936 * Concurrency: Rust must maintain memory safety guarantees, even for
937 code running in parallel
939 ## How performance considerations influence the memory model
941 Most languages that offer strong memory safety guarantees rely upon a
942 garbage-collected heap to manage all of the objects. This approach is
943 straightforward both in concept and in implementation, but has
944 significant costs. Languages that take this approach tend to
945 aggressively pursue ways to ameliorate allocation costs (think the
946 Java Virtual Machine). Rust supports this strategy with _shared
947 boxes_: memory allocated on the heap that may be referred to (shared)
948 by multiple variables.
950 By comparison, languages like C++ offer very precise control over
951 where objects are allocated. In particular, it is common to put them
952 directly on the stack, avoiding expensive heap allocation. In Rust
953 this is possible as well, and the compiler will use a clever _pointer
954 lifetime analysis_ to ensure that no variable can refer to stack
955 objects after they are destroyed.
957 ## How concurrency considerations influence the memory model
959 Memory safety in a concurrent environment involves avoiding race
960 conditions between two threads of execution accessing the same
961 memory. Even high-level languages often require programmers to
962 correctly employ locking to ensure that a program is free of races.
964 Rust starts from the position that memory cannot be shared between
965 tasks. Experience in other languages has proven that isolating each
966 task's heap from the others is a reliable strategy and one that is
967 easy for programmers to reason about. Heap isolation has the
968 additional benefit that garbage collection must only be done
969 per-heap. Rust never "stops the world" to garbage-collect memory.
971 Complete isolation of heaps between tasks implies that any data
972 transferred between tasks must be copied. While this is a fine and
973 useful way to implement communication between tasks, it is also very
974 inefficient for large data structures. Because of this, Rust also
975 employs a global _exchange heap_. Objects allocated in the exchange
976 heap have _ownership semantics_, meaning that there is only a single
977 variable that refers to them. For this reason, they are referred to as
978 _unique boxes_. All tasks may allocate objects on the exchange heap,
979 then transfer ownership of those objects to other tasks, avoiding
982 ## What to be aware of
984 Rust has three "realms" in which objects can be allocated: the stack,
985 the local heap, and the exchange heap. These realms have corresponding
986 pointer types: the borrowed pointer (`&T`), the shared box (`@T`),
987 and the unique box (`~T`). These three sigils will appear
988 repeatedly as we explore the language. Learning the appropriate role
989 of each is key to using Rust effectively.
993 In contrast to a lot of modern languages, aggregate types like records
994 and enums are _not_ represented as pointers to allocated memory in
995 Rust. They are, as in C and C++, represented directly. This means that
996 if you `let x = {x: 1f, y: 1f};`, you are creating a record on the
997 stack. If you then copy it into a data structure, the whole record is
998 copied, not just a pointer.
1000 For small records like `point`, this is usually more efficient than
1001 allocating memory and going through a pointer. But for big records, or
1002 records with mutable fields, it can be useful to have a single copy on
1003 the heap, and refer to that through a pointer.
1005 Rust supports several types of pointers. The safe pointer types are
1006 `@T` for shared boxes allocated on the local heap, `~T`, for
1007 uniquely-owned boxes allocated on the exchange heap, and `&T`, for
1008 borrowed pointers, which may point to any memory, and whose lifetimes
1009 are governed by the call stack.
1011 Rust also has an unsafe pointer, written `*T`, which is a completely
1012 unchecked pointer type only used in unsafe code (and thus, in typical
1013 Rust code, very rarely).
1015 All pointer types can be dereferenced with the `*` unary operator.
1019 Shared boxes are pointers to heap-allocated, garbage collected memory.
1020 Creating a shared box is done by simply applying the unary `@`
1021 operator to an expression. The result of the expression will be boxed,
1022 resulting in a box of the right type. Copying a shared box, as happens
1023 during assignment, only copies a pointer, never the contents of the
1027 let x: @int = @10; // New box, refcount of 1
1028 let y = x; // Copy the pointer, increase refcount
1029 // When x and y go out of scope, refcount goes to 0, box is freed
1032 Shared boxes never cross task boundaries.
1034 > ***Note:*** shared boxes are currently reclaimed through reference
1035 > counting and cycle collection, but we will switch to a tracing
1036 > garbage collector.
1040 In contrast to shared boxes, unique boxes have a single owner and thus
1041 two unique boxes may not refer to the same memory. All unique boxes
1042 across all tasks are allocated on a single _exchange heap_, where
1043 their uniquely owned nature allows them to be passed between tasks.
1045 Because unique boxes are uniquely owned, copying them involves allocating
1046 a new unique box and duplicating the contents. Copying unique boxes
1047 is expensive so the compiler will complain if you do.
1051 let y = x; // error: copying a non-implicitly copyable type
1054 If you really want to copy a unique box you must say so explicitly.
1061 This is where the 'move' (`<-`) operator comes in. It is similar to
1062 `=`, but it de-initializes its source. Thus, the unique box can move
1063 from `x` to `y`, without violating the constraint that it only has a
1064 single owner (if you used assignment instead of the move operator, the
1065 box would, in principle, be copied).
1072 > ***Note:*** this discussion of copying vs moving does not account
1073 > for the "last use" rules that automatically promote copy operations
1074 > to moves. This is an evolving area of the language that will
1075 > continue to change.
1077 Unique boxes, when they do not contain any shared boxes, can be sent
1078 to other tasks. The sending task will give up ownership of the box,
1079 and won't be able to access it afterwards. The receiving task will
1080 become the sole owner of the box.
1082 ## Borrowed pointers
1084 Rust borrowed pointers are a general purpose reference/pointer type,
1085 similar to the C++ reference type, but guaranteed to point to valid
1086 memory. In contrast to unique pointers, where the holder of a unique
1087 pointer is the owner of the pointed-to memory, borrowed pointers never
1088 imply ownership. Pointers may be borrowed from any type, in which case
1089 the pointer is guaranteed not to outlive the value it points to.
1092 # fn work_with_foo_by_pointer(f: &~str) { }
1094 work_with_foo_by_pointer(&foo);
1097 The following shows an example of what is _not_ possible with borrowed
1098 pointers. If you were able to write this then the pointer to `foo`
1099 would outlive `foo` itself.
1109 > ***Note:*** borrowed pointers are a new addition to the language.
1110 > They are not used extensively yet but are expected to become the
1111 > pointer type used in many common situations, in particular for
1112 > by-reference argument passing. Rust's current solution for passing
1113 > arguments by reference is [argument modes](#argument-passing).
1117 All pointer types have a mutable variant, written `@mut T` or `~mut
1118 T`. Given such a pointer, you can write to its contents by combining
1119 the dereference operator with a mutating action.
1122 fn increase_contents(pt: @mut int) {
1129 Vectors are a contiguous section of memory containing zero or more
1130 values of the same type. Like other types in Rust, vectors can be
1131 stored on the stack, the local heap, or the exchange heap.
1135 almond, antique_brass, apricot,
1136 aquamarine, asparagus, atomic_tangerine,
1137 banana_mania, beaver, bittersweet
1140 // A stack vector of crayons
1141 let stack_crayons: &[crayon] = &[almond, antique_brass, apricot];
1142 // A local heap (shared) vector of crayons
1143 let local_crayons: @[crayon] = @[aquamarine, asparagus, atomic_tangerine];
1144 // An exchange heap (unique) vector of crayons
1145 let exchange_crayons: ~[crayon] = ~[banana_mania, beaver, bittersweet];
1148 > ***Note:*** Until recently Rust only had unique vectors, using the
1149 > unadorned `[]` syntax for literals. This syntax is still supported
1150 > but is deprecated. In the future it will probably represent some
1151 > "reasonable default" vector type.
1153 > Unique vectors are the currently-recommended vector type for general
1154 > use as they are the most tested and well-supported by existing
1155 > libraries. There will be a gradual shift toward using more
1156 > stack and local vectors in the coming releases.
1158 Vector literals are enclosed in square brackets and dereferencing is
1159 also done with square brackets (zero-based):
1162 # enum crayon { almond, antique_brass, apricot,
1163 # aquamarine, asparagus, atomic_tangerine,
1164 # banana_mania, beaver, bittersweet };
1165 # fn draw_scene(c: crayon) { }
1167 let crayons = ~[banana_mania, beaver, bittersweet];
1169 bittersweet => draw_scene(crayons[0]),
1174 By default, vectors are immutableāyou can not replace their elements.
1175 The type written as `~[mut T]` is a vector with mutable
1176 elements. Mutable vector literals are written `~[mut]` (empty) or `~[mut
1177 1, 2, 3]` (with elements).
1180 # enum crayon { almond, antique_brass, apricot,
1181 # aquamarine, asparagus, atomic_tangerine,
1182 # banana_mania, beaver, bittersweet };
1184 let crayons = ~[mut banana_mania, beaver, bittersweet];
1185 crayons[0] = atomic_tangerine;
1188 The `+` operator means concatenation when applied to vector types.
1191 # enum crayon { almond, antique_brass, apricot,
1192 # aquamarine, asparagus, atomic_tangerine,
1193 # banana_mania, beaver, bittersweet };
1195 let my_crayons = ~[almond, antique_brass, apricot];
1196 let your_crayons = ~[banana_mania, beaver, bittersweet];
1198 let our_crayons = my_crayons + your_crayons;
1201 The `+=` operator also works as expected, provided the assignee
1202 lives in a mutable slot.
1205 # enum crayon { almond, antique_brass, apricot,
1206 # aquamarine, asparagus, atomic_tangerine,
1207 # banana_mania, beaver, bittersweet };
1209 let mut my_crayons = ~[almond, antique_brass, apricot];
1210 let your_crayons = ~[banana_mania, beaver, bittersweet];
1212 my_crayons += your_crayons;
1217 The `~str` type in Rust is represented exactly the same way as a unique
1218 vector of immutable bytes (`~[u8]`). This sequence of bytes is
1219 interpreted as an UTF-8 encoded sequence of characters. This has the
1220 advantage that UTF-8 encoded I/O (which should really be the default
1221 for modern systems) is very fast, and that strings have, for most
1222 intents and purposes, a nicely compact representation. It has the
1223 disadvantage that you only get constant-time access by byte, not by
1228 let que: u8 = huh[4]; // indexing a string returns a `u8`
1229 assert que == '?' as u8;
1232 A lot of algorithms don't need constant-time indexed access (they
1233 iterate over all characters, which `str::chars` helps with), and
1234 for those that do, many don't need actual characters, and can operate
1235 on bytes. For algorithms that do really need to index by character,
1236 there are core library functions available.
1238 > ***Note:*** like vectors, strings will soon be allocatable in
1239 > the local heap and on the stack, in addition to the exchange heap.
1241 ## Vector and string methods
1243 Both vectors and strings support a number of useful
1244 [methods](#implementation). While we haven't covered methods yet,
1245 most vector functionality is provided by methods, so let's have a
1246 brief look at a few common ones.
1249 # import io::println;
1251 # almond, antique_brass, apricot,
1252 # aquamarine, asparagus, atomic_tangerine,
1253 # banana_mania, beaver, bittersweet
1255 # fn unwrap_crayon(c: crayon) -> int { 0 }
1256 # fn eat_crayon_wax(i: int) { }
1257 # fn store_crayon_in_nasal_cavity(i: uint, c: crayon) { }
1258 # fn crayon_to_str(c: crayon) -> ~str { ~"" }
1260 let crayons = ~[almond, antique_brass, apricot];
1262 // Check the length of the vector
1263 assert crayons.len() == 3;
1264 assert !crayons.is_empty();
1266 // Iterate over a vector
1267 for crayons.each |crayon| {
1268 let delicious_crayon_wax = unwrap_crayon(crayon);
1269 eat_crayon_wax(delicious_crayon_wax);
1272 // Map vector elements
1273 let crayon_names = crayons.map(crayon_to_str);
1274 let favorite_crayon_name = crayon_names[0];
1276 // Remove whitespace from before and after the string
1277 let new_favorite_crayon_name = favorite_crayon_name.trim();
1279 if favorite_crayon_name.len() > 5 {
1280 // Create a substring
1281 println(favorite_crayon_name.substr(0, 5));
1287 Named functions, like those we've seen so far, may not refer to local
1288 variables declared outside the function - they do not "close over
1289 their environment". For example, you couldn't write the following:
1295 return foo; // `bar` cannot refer to `foo`
1299 Rust also supports _closures_, functions that can access variables in
1300 the enclosing scope.
1303 # import println = io::println;
1304 fn call_closure_with_ten(b: fn(int)) { b(10); }
1306 let captured_var = 20;
1307 let closure = |arg| println(fmt!("captured_var=%d, arg=%d", captured_var, arg));
1309 call_closure_with_ten(closure);
1312 Closures begin with the argument list between bars and are followed by
1313 a single expression. The types of the arguments are generally omitted,
1314 as is the return type, because the compiler can almost always infer
1315 them. In the rare case where the compiler needs assistance though, the
1316 arguments and return types may be annotated.
1319 # type mygoodness = fn(~str) -> ~str; type what_the = int;
1320 let bloop = |well, oh: mygoodness| -> what_the { fail oh(well) };
1323 There are several forms of closure, each with its own role. The most
1324 common, called a _stack closure_, has type `fn&` and can directly
1325 access local variables in the enclosing scope.
1329 (~[1, 2, 3]).map(|x| if x > max { max = x });
1332 Stack closures are very efficient because their environment is
1333 allocated on the call stack and refers by pointer to captured
1334 locals. To ensure that stack closures never outlive the local
1335 variables to which they refer, they can only be used in argument
1336 position and cannot be stored in structures nor returned from
1337 functions. Despite the limitations stack closures are used
1338 pervasively in Rust code.
1342 When you need to store a closure in a data structure, a stack closure
1343 will not do, since the compiler will refuse to let you store it. For
1344 this purpose, Rust provides a type of closure that has an arbitrary
1345 lifetime, written `fn@` (boxed closure, analogous to the `@` pointer
1346 type described earlier).
1348 A boxed closure does not directly access its environment, but merely
1349 copies out the values that it closes over into a private data
1350 structure. This means that it can not assign to these variables, and
1351 will not 'see' updates to them.
1353 This code creates a closure that adds a given string to its argument,
1354 returns it from a function, and then calls it:
1359 fn mk_appender(suffix: ~str) -> fn@(~str) -> ~str {
1360 return fn@(s: ~str) -> ~str { s + suffix };
1364 let shout = mk_appender(~"!");
1365 io::println(shout(~"hey ho, let's go"));
1369 This example uses the long closure syntax, `fn@(s: ~str) ...`,
1370 making the fact that we are declaring a box closure explicit. In
1371 practice boxed closures are usually defined with the short closure
1372 syntax introduced earlier, in which case the compiler will infer
1373 the type of closure. Thus our boxed closure example could also
1377 fn mk_appender(suffix: ~str) -> fn@(~str) -> ~str {
1378 return |s| s + suffix;
1384 Unique closures, written `fn~` in analogy to the `~` pointer type,
1385 hold on to things that can safely be sent between
1386 processes. They copy the values they close over, much like boxed
1387 closures, but they also 'own' themāmeaning no other code can access
1388 them. Unique closures are used in concurrent code, particularly
1389 for spawning [tasks](#tasks).
1391 ## Closure compatibility
1393 A nice property of Rust closures is that you can pass any kind of
1394 closure (as long as the arguments and return types match) to functions
1395 that expect a `fn()`. Thus, when writing a higher-order function that
1396 wants to do nothing with its function argument beyond calling it, you
1397 should almost always specify the type of that argument as `fn()`, so
1398 that callers have the flexibility to pass whatever they want.
1401 fn call_twice(f: fn()) { f(); f(); }
1402 call_twice(|| { ~"I am an inferred stack closure"; } );
1403 call_twice(fn&() { ~"I am also a stack closure"; } );
1404 call_twice(fn@() { ~"I am a boxed closure"; });
1405 call_twice(fn~() { ~"I am a unique closure"; });
1406 fn bare_function() { ~"I am a plain function"; }
1407 call_twice(bare_function);
1412 Closures in Rust are frequently used in combination with higher-order
1413 functions to simulate control structures like `if` and
1414 `loop`. Consider this function that iterates over a vector of
1415 integers, applying an operator to each:
1418 fn each(v: ~[int], op: fn(int)) {
1427 As a caller, if we use a closure to provide the final operator
1428 argument, we can write it in a way that has a pleasant, block-like
1432 # fn each(v: ~[int], op: fn(int)) {}
1433 # fn do_some_work(i: int) { }
1434 each(~[1, 2, 3], |n| {
1440 This is such a useful pattern that Rust has a special form of function
1441 call that can be written more like a built-in control structure:
1444 # fn each(v: ~[int], op: fn(int)) {}
1445 # fn do_some_work(i: int) { }
1446 do each(~[1, 2, 3]) |n| {
1452 The call is prefixed with the keyword `do` and, instead of writing the
1453 final closure inside the argument list it is moved outside of the
1454 parenthesis where it looks visually more like a typical block of
1455 code. The `do` expression is purely syntactic sugar for a call that
1456 takes a final closure argument.
1458 `do` is often used for task spawning.
1464 debug!("I'm a task, whatever");
1468 That's nice, but look at all those bars and parentheses - that's two empty
1469 argument lists back to back. Wouldn't it be great if they weren't
1473 # import task::spawn;
1479 Empty argument lists can be omitted from `do` expressions.
1483 Most iteration in Rust is done with `for` loops. Like `do`,
1484 `for` is a nice syntax for doing control flow with closures.
1485 Additionally, within a `for` loop, `break`, `again`, and `return`
1486 work just as they do with `while` and `loop`.
1488 Consider again our `each` function, this time improved to
1489 break early when the iteratee returns `false`:
1492 fn each(v: ~[int], op: fn(int) -> bool) {
1503 And using this function to iterate over a vector:
1506 # import each = vec::each;
1507 # import println = io::println;
1508 each(~[2, 4, 8, 5, 16], |n| {
1510 println(~"found odd number!");
1516 With `for`, functions like `each` can be treated more
1517 like builtin looping structures. When calling `each`
1518 in a `for` loop, instead of returning `false` to break
1519 out of the loop, you just write `break`. To skip ahead
1520 to the next iteration, write `again`.
1523 # import each = vec::each;
1524 # import println = io::println;
1525 for each(~[2, 4, 8, 5, 16]) |n| {
1527 println(~"found odd number!");
1533 As an added bonus, you can use the `return` keyword, which is not
1534 normally allowed in closures, in a block that appears as the body of a
1535 `for` loop ā this will cause a return to happen from the outer
1536 function, not just the loop body.
1539 # import each = vec::each;
1540 fn contains(v: ~[int], elt: int) -> bool {
1542 if (x == elt) { return true; }
1548 `for` syntax only works with stack closures.
1552 ## Generic functions
1554 Throughout this tutorial, we've been defining functions that act only on
1555 single data types. It's a burden to define such functions again and again for
1556 every type they apply to. Thus, Rust allows functions and datatypes to have
1560 fn map<T, U>(vector: &[T], function: fn(T) -> U) -> ~[U] {
1561 let mut accumulator = ~[];
1562 for vector.each |element| {
1563 vec::push(accumulator, function(element));
1569 When defined with type parameters, this function can be applied to any
1570 type of vector, as long as the type of `function`'s argument and the
1571 type of the vector's content agree with each other.
1573 Inside a generic function, the names of the type parameters
1574 (capitalized by convention) stand for opaque types. You can't look
1575 inside them, but you can pass them around.
1577 ## Generic datatypes
1579 Generic `type`, `struct`, and `enum` declarations follow the same pattern:
1592 These declarations produce valid types like `Stack<u8>` and `Maybe<int>`.
1596 Perhaps surprisingly, the 'copy' (duplicate) operation is not defined
1597 for all Rust types. Resource types (classes with destructors) cannot be
1598 copied, and neither can any type whose copying would require copying a
1599 resource (such as records or unique boxes containing a resource).
1601 This complicates handling of generic functions. If you have a type
1602 parameter `T`, can you copy values of that type? In Rust, you can't,
1603 unless you explicitly declare that type parameter to have copyable
1604 'kind'. A kind is a type of type.
1607 // This does not compile
1608 fn head_bad<T>(v: ~[T]) -> T { v[0] }
1610 fn head<T: copy>(v: ~[T]) -> T { v[0] }
1613 When instantiating a generic function, you can only instantiate it
1614 with types that fit its kinds. So you could not apply `head` to a
1615 resource type. Rust has several kinds that can be used as type bounds:
1617 * `copy` - Copyable types. All types are copyable unless they
1618 are classes with destructors or otherwise contain
1619 classes with destructors.
1620 * `send` - Sendable types. All types are sendable unless they
1621 contain shared boxes, closures, or other local-heap-allocated
1623 * `const` - Constant types. These are types that do not contain
1624 mutable fields nor shared boxes.
1626 > ***Note:*** Rust type kinds are syntactically very similar to
1627 > [traits](#traits) when used as type bounds, and can be
1628 > conveniently thought of as built-in traits. In the future type
1629 > kinds will actually be traits that the compiler has special
1632 # Modules and crates
1634 The Rust namespace is divided into modules. Each source file starts
1635 with its own module.
1639 The `mod` keyword can be used to open a new, local module. In the
1640 example below, `chicken` lives in the module `farm`, so, unless you
1641 explicitly import it, you must refer to it by its long name,
1646 fn chicken() -> ~str { ~"cluck cluck" }
1647 fn cow() -> ~str { ~"mooo" }
1650 io::println(farm::chicken());
1654 Modules can be nested to arbitrary depth.
1658 The unit of independent compilation in Rust is the crate. Libraries
1659 tend to be packaged as crates, and your own programs may consist of
1662 When compiling a single `.rs` file, the file acts as the whole crate.
1663 You can compile it with the `--lib` compiler switch to create a shared
1664 library, or without, provided that your file contains a `fn main`
1665 somewhere, to create an executable.
1667 It is also possible to include multiple files in a crate. For this
1668 purpose, you create a `.rc` crate file, which references any number of
1669 `.rs` code files. A crate file could look like this:
1672 #[link(name = "farm", vers = "2.5", author = "mjh")];
1673 #[crate_type = "lib"];
1679 Compiling this file will cause `rustc` to look for files named
1680 `cow.rs`, `chicken.rs`, `horse.rs` in the same directory as the `.rc`
1681 file, compile them all together, and, depending on the presence of the
1682 `crate_type = "lib"` attribute, output a shared library or an executable.
1683 (If the line `#[crate_type = "lib"];` was omitted, `rustc` would create an
1686 The `#[link(...)]` part provides meta information about the module,
1687 which other crates can use to load the right module. More about that
1690 To have a nested directory structure for your source files, you can
1691 nest mods in your `.rc` file:
1700 The compiler will now look for `poultry/chicken.rs` and
1701 `poultry/turkey.rs`, and export their content in `poultry::chicken`
1702 and `poultry::turkey`. You can also provide a `poultry.rs` to add
1703 content to the `poultry` module itself.
1705 ## Using other crates
1707 Having compiled a crate that contains the `#[crate_type = "lib"]` attribute,
1708 you can use it in another crate with a `use` directive. We've already seen
1709 `use std` in several of the examples, which loads in the [standard library][std].
1711 [std]: http://doc.rust-lang.org/doc/std/index/General.html
1713 `use` directives can appear in a crate file, or at the top level of a
1714 single-file `.rs` crate. They will cause the compiler to search its
1715 library search path (which you can extend with `-L` switch) for a Rust
1716 crate library with the right name.
1718 It is possible to provide more specific information when using an
1722 use myfarm (name = "farm", vers = "2.7");
1725 When a comma-separated list of name/value pairs is given after `use`,
1726 these are matched against the attributes provided in the `link`
1727 attribute of the crate file, and a crate is only used when the two
1728 match. A `name` value can be given to override the name used to search
1729 for the crate. So the above would import the `farm` crate under the
1730 local name `myfarm`.
1732 Our example crate declared this set of `link` attributes:
1735 #[link(name = "farm", vers = "2.5", author = "mjh")];
1738 The version does not match the one provided in the `use` directive, so
1739 unless the compiler can find another crate with the right version
1740 somewhere, it will complain that no matching crate was found.
1744 A set of basic library routines, mostly related to built-in datatypes
1745 and the task system, are always implicitly linked and included in any
1748 This library is documented [here][core].
1750 [core]: http://doc.rust-lang.org/doc/core
1752 ## A minimal example
1754 Now for something that you can actually compile yourself. We have
1759 #[link(name = "mylib", vers = "1.0")];
1760 fn world() -> ~str { ~"world" }
1767 fn main() { io::println(~"hello " + mylib::world()); }
1770 Now compile and run like this (adjust to your platform if necessary):
1773 > rustc --lib mylib.rs
1774 > rustc main.rs -L .
1781 When using identifiers from other modules, it can get tiresome to
1782 qualify them with the full module path every time (especially when
1783 that path is several modules deep). Rust allows you to import
1784 identifiers at the top of a file, module, or block.
1790 println(~"that was easy");
1794 It is also possible to import just the name of a module (`import
1795 std::list;`, then use `list::find`), to import all identifiers exported
1796 by a given module (`import io::*`), or to import a specific set
1797 of identifiers (`import math::{min, max, pi}`).
1799 You can rename an identifier when importing using the `=` operator:
1802 import prnt = io::println;
1807 By default, a module exports everything that it defines. This can be
1808 restricted with `export` directives at the top of the module or file.
1812 export encrypt, decrypt;
1813 const super_secret_number: int = 10;
1814 fn encrypt(n: int) -> int { n + super_secret_number }
1815 fn decrypt(n: int) -> int { n - super_secret_number }
1819 This defines a rock-solid encryption algorithm. Code outside of the
1820 module can refer to the `enc::encrypt` and `enc::decrypt` identifiers
1821 just fine, but it does not have access to `enc::super_secret_number`.
1825 Rust uses three different namespaces: one for modules, one for types,
1826 and one for values. This means that this code is valid:
1831 fn buffalo<buffalo: copy>(buffalo: buffalo) -> buffalo { buffalo }
1834 let buffalo: buffalo::buffalo = 1;
1835 buffalo::buffalo::<buffalo::buffalo>(buffalo::buffalo(buffalo));
1839 You don't want to write things like that, but it *is* very practical
1840 to not have to worry about name clashes between types, values, and
1841 modules. This allows us to have a module `core::str`, for example, even
1842 though `str` is a built-in type name.
1846 The resolution process in Rust simply goes up the chain of contexts,
1847 looking for the name in each context. Nested functions and modules
1848 create new contexts inside their parent function or module. A file
1849 that's part of a bigger crate will have that crate's context as its
1852 Identifiers can shadow each other. In this program, `x` is of type
1863 An `import` directive will only import into the namespaces for which
1864 identifiers are actually found. Consider this example:
1868 mod foo { fn bar() {} }
1875 When resolving the type name `bar` in the `const` definition, the
1876 resolver will first look at the module context for `baz`. This has an
1877 import named `bar`, but that's a function, not a type, So it continues
1878 to the top level and finds a type named `bar` defined there.
1880 Normally, multiple definitions of the same identifier in a scope are
1881 disallowed. Local variables defined with `let` are an exception to
1882 thisāmultiple `let` directives can redefine the same variable in a
1883 single scope. When resolving the name of such a variable, the most
1884 recent definition is used.
1894 This makes it possible to rebind a variable without actually mutating
1895 it, which is mostly useful for destructuring (which can rebind, but
1900 Functions are the programmer's primary tool of abstraction, but there are
1901 cases in which they are insufficient, because the programmer wants to
1902 abstract over concepts not represented as values. Consider the following
1906 # enum t { special_a(uint), special_b(uint) };
1908 # let input_1 = special_a(0), input_2 = special_a(0);
1910 special_a(x) => { return x; }
1915 special_b(x) => { return x; }
1922 This code could become tiresome if repeated many times. However, there is
1923 no reasonable function that could be written to solve this problem. In such a
1924 case, it's possible to define a macro to solve the problem. Macros are
1925 lightweight custom syntax extensions, themselves defined using the
1926 `macro_rules!` syntax extension:
1929 # enum t { special_a(uint), special_b(uint) };
1931 # let input_1 = special_a(0), input_2 = special_a(0);
1932 macro_rules! early_return(
1933 ($inp:expr $sp:ident) => ( //invoke it like `(input_5 special_e)`
1935 $sp(x) => { return x; }
1941 early_return!(input_1 special_a);
1943 early_return!(input_2 special_b);
1948 Macros are defined in pattern-matching style:
1950 ## Invocation syntax
1952 On the left-hand-side of the `=>` is the macro invocation syntax. It is
1953 free-form, excepting the following rules:
1955 1. It must be surrounded in parentheses.
1956 2. `$` has special meaning.
1957 3. The `()`s, `[]`s, and `{}`s it contains must balance. For example, `([)` is
1960 To take as an argument a fragment of Rust code, write `$` followed by a name
1961 (for use on the right-hand side), followed by a `:`, followed by the sort of
1962 fragment to match (the most common ones are `ident`, `expr`, `ty`, `pat`, and
1963 `block`). Anything not preceeded by a `$` is taken literally. The standard
1964 rules of tokenization apply,
1966 So `($x:ident => (($e:expr)))`, though excessively fancy, would create a macro
1967 that could be invoked like `my_macro!(i=>(( 2+2 )))`.
1969 ## Transcription syntax
1971 The right-hand side of the `=>` follows the same rules as the left-hand side,
1972 except that `$` need only be followed by the name of the syntactic fragment
1975 The right-hand side must be surrounded by delimiters of some kind, and must be
1976 an expression; currently, user-defined macros can only be invoked in
1977 expression position (even though `macro_rules!` itself can be in item
1984 Going back to the motivating example, suppose that we wanted each invocation
1985 of `early_return` to potentially accept multiple "special" identifiers. The
1986 syntax `$(...)*` accepts zero or more occurences of its contents, much like
1987 the Kleene star operator in regular expressions. It also supports a separator
1988 token (a comma-separated list could be written `$(...),*`), and `+` instead of
1989 `*` to mean "at least one".
1992 # enum t { special_a(uint),special_b(uint),special_c(uint),special_d(uint)};
1994 # let input_1 = special_a(0), input_2 = special_a(0);
1995 macro_rules! early_return(
1996 ($inp:expr, [ $($sp:ident)|+ ]) => (
1999 $sp(x) => { return x; }
2006 early_return!(input_1, [special_a|special_c|special_d]);
2008 early_return!(input_2, [special_b]);
2015 As the above example demonstrates, `$(...)*` is also valid on the right-hand
2016 side of a macro definition. The behavior of Kleene star in transcription,
2017 especially in cases where multiple stars are nested, and multiple different
2018 names are involved, can seem somewhat magical and intuitive at first. The
2019 system that interprets them is called "Macro By Example". The two rules to
2020 keep in mind are (1) the behavior of `$(...)*` is to walk through one "layer"
2021 of repetitions for all of the `$name`s it contains in lockstep, and (2) each
2022 `$name` must be under at least as many `$(...)*`s as it was matched against.
2023 If it is under more, it'll will be repeated, as appropriate.
2025 ## Parsing limitations
2027 The parser used by the macro system is reasonably powerful, but the parsing of
2028 Rust syntax is restricted in two ways:
2030 1. The parser will always parse as much as possible. For example, if the comma
2031 were omitted from the syntax of `early_return!` above, `input_1 [` would've
2032 been interpreted as the beginning of an array index. In fact, invoking the
2033 macro would have been impossible.
2034 2. The parser must have eliminated all ambiguity by the time it reaches a
2035 `$name:fragment_specifier`. This most often affects them when they occur in
2036 the beginning of, or immediately after, a `$(...)*`; requiring a distinctive
2037 token in front can solve the problem.
2041 Macros, as currently implemented, are not for the faint of heart. Even
2042 ordinary syntax errors can be more difficult to debug when they occur inside
2043 a macro, and errors caused by parse problems in generated code can be very
2044 tricky. Invoking the `log_syntax!` macro can help elucidate intermediate
2045 states, using `trace_macros!(true)` will automatically print those
2046 intermediate states out, and using `--pretty expanded` as an argument to the
2047 compiler will show the result of expansion.
2051 Traits are Rust's take on value polymorphismāthe thing that
2052 object-oriented languages tend to solve with methods and inheritance.
2053 For example, writing a function that can operate on multiple types of
2056 > ***Note:*** This feature is very new, and will need a few extensions to be
2057 > applicable to more advanced use cases.
2061 A trait consists of a set of methods. A method is a function that
2062 can be applied to a `self` value and a number of arguments, using the
2063 dot notation: `self.foo(arg1, arg2)`.
2065 For example, we could declare the trait `to_str` for things that
2066 can be converted to a string, with a single method of the same name:
2070 fn to_str() -> ~str;
2076 To actually implement a trait for a given type, the `impl` form
2077 is used. This defines implementations of `to_str` for the `int` and
2081 # trait to_str { fn to_str() -> ~str; }
2083 fn to_str() -> ~str { int::to_str(self, 10u) }
2086 fn to_str() -> ~str { self }
2090 Given these, we may call `1.to_str()` to get `~"1"`, or
2091 `(~"foo").to_str()` to get `~"foo"` again. This is basically a form of
2092 static overloadingāwhen the Rust compiler sees the `to_str` method
2093 call, it looks for an implementation that matches the type with a
2094 method that matches the name, and simply calls that.
2096 ## Bounded type parameters
2098 The useful thing about value polymorphism is that it does not have to
2099 be static. If object-oriented languages only let you call a method on
2100 an object when they knew exactly which sub-type it had, that would not
2101 get you very far. To be able to call methods on types that aren't
2102 known at compile time, it is possible to specify 'bounds' for type
2106 # trait to_str { fn to_str() -> ~str; }
2107 fn comma_sep<T: to_str>(elts: ~[T]) -> ~str {
2108 let mut result = ~"", first = true;
2109 for elts.each |elt| {
2110 if first { first = false; }
2111 else { result += ~", "; }
2112 result += elt.to_str();
2118 The syntax for this is similar to the syntax for specifying that a
2119 parameter type has to be copyable (which is, in principle, another
2120 kind of bound). By declaring `T` as conforming to the `to_str`
2121 trait, it becomes possible to call methods from that trait on
2122 values of that type inside the function. It will also cause a
2123 compile-time error when anyone tries to call `comma_sep` on an array
2124 whose element type does not have a `to_str` implementation in scope.
2126 ## Polymorphic traits
2128 Traits may contain type parameters. This defines a trait for
2129 generalized sequence types:
2136 impl<T> ~[T]: seq<T> {
2137 fn len() -> uint { vec::len(self) }
2139 for self.each |elt| { b(elt); }
2144 Note that the implementation has to explicitly declare the type
2145 parameter that it binds, `T`, before using it to specify its trait type. This is
2146 needed because it could also, for example, specify an implementation
2147 of `seq<int>`āthe `of` clause *refers* to a type, rather than defining
2150 The type parameters bound by a trait are in scope in each of the
2151 method declarations. So, re-declaring the type parameter
2152 `T` as an explicit type parameter for `len` -- in either the trait or
2153 the impl -- would be a compile-time error.
2155 ## The `self` type in traits
2157 In a trait, `self` is a special type that you can think of as a
2158 type parameter. An implementation of the trait for any given type
2159 `T` replaces the `self` type parameter with `T`. The following
2160 trait describes types that support an equality operation:
2164 fn equals(&&other: self) -> bool;
2168 fn equals(&&other: int) -> bool { other == self }
2172 Notice that `equals` takes an `int` argument, rather than a `self` argument, in
2173 an implementation for type `int`.
2175 ## Casting to a trait type
2177 The above allows us to define functions that polymorphically act on
2178 values of *an* unknown type that conforms to a given trait.
2179 However, consider this function:
2182 # type circle = int; type rectangle = int;
2183 # trait drawable { fn draw(); }
2184 # impl int: drawable { fn draw() {} }
2185 # fn new_circle() -> int { 1 }
2186 fn draw_all<T: drawable>(shapes: ~[T]) {
2187 for shapes.each |shape| { shape.draw(); }
2189 # let c: circle = new_circle();
2193 You can call that on an array of circles, or an array of squares
2194 (assuming those have suitable `drawable` traits defined), but not
2195 on an array containing both circles and squares.
2197 When this is needed, a trait name can be used as a type, causing
2198 the function to be written simply like this:
2201 # trait drawable { fn draw(); }
2202 fn draw_all(shapes: ~[drawable]) {
2203 for shapes.each |shape| { shape.draw(); }
2207 There is no type parameter anymore (since there isn't a single type
2208 that we're calling the function on). Instead, the `drawable` type is
2209 used to refer to a type that is a reference-counted box containing a
2210 value for which a `drawable` implementation exists, combined with
2211 information on where to find the methods for this implementation. This
2212 is very similar to the 'vtables' used in most object-oriented
2215 To construct such a value, you use the `as` operator to cast a value
2219 # type circle = int; type rectangle = int;
2220 # trait drawable { fn draw(); }
2221 # impl int: drawable { fn draw() {} }
2222 # fn new_circle() -> int { 1 }
2223 # fn new_rectangle() -> int { 2 }
2224 # fn draw_all(shapes: ~[drawable]) {}
2225 let c: circle = new_circle();
2226 let r: rectangle = new_rectangle();
2227 draw_all(~[c as drawable, r as drawable]);
2230 This will store the value into a box, along with information about the
2231 implementation (which is looked up in the scope of the cast). The
2232 `drawable` type simply refers to such boxes, and calling methods on it
2233 always works, no matter what implementations are in scope.
2235 Note that the allocation of a box is somewhat more expensive than
2236 simply using a type parameter and passing in the value as-is, and much
2237 more expensive than statically resolved method calls.
2239 ## Trait-less implementations
2241 If you only intend to use an implementation for static overloading,
2242 and there is no trait available that it conforms to, you are free
2243 to leave off the `of` clause. However, this is only possible when you
2244 are defining an implementation in the same module as the receiver
2245 type, and the receiver type is a named type (i.e., an enum or a
2246 class); [single-variant enums](#single_variant_enum) are a common
2249 # Interacting with foreign code
2251 One of Rust's aims, as a system programming language, is to
2252 interoperate well with C code.
2254 We'll start with an example. It's a bit bigger than usual, and
2255 contains a number of new concepts. We'll go over it one piece at a
2258 This is a program that uses OpenSSL's `SHA1` function to compute the
2259 hash of its first command-line argument, which it then converts to a
2260 hexadecimal string and prints to standard output. If you have the
2261 OpenSSL libraries installed, it should 'just work'.
2265 import libc::c_uint;
2268 fn SHA1(src: *u8, sz: c_uint, out: *u8) -> *u8;
2271 fn as_hex(data: ~[u8]) -> ~str {
2273 for data.each |byte| { acc += fmt!("%02x", byte as uint); }
2277 fn sha1(data: ~str) -> ~str unsafe {
2278 let bytes = str::to_bytes(data);
2279 let hash = crypto::SHA1(vec::unsafe::to_ptr(bytes),
2280 vec::len(bytes) as c_uint, ptr::null());
2281 return as_hex(vec::unsafe::from_buf(hash, 20u));
2284 fn main(args: ~[~str]) {
2285 io::println(sha1(args[1]));
2291 Before we can call `SHA1`, we have to declare it. That is what this
2292 part of the program is responsible for:
2296 fn SHA1(src: *u8, sz: uint, out: *u8) -> *u8;
2300 An `extern` module declaration containing function signatures introduces
2301 the functions listed as _foreign functions_, that are implemented in some
2302 other language (usually C) and accessed through Rust's foreign function
2303 interface (FFI). An extern module like this is called a foreign module, and
2304 implicitly tells the compiler to link with a library with the same name as
2305 the module, and that it will find the foreign functions in that library.
2307 In this case, it'll change the name `crypto` to a shared library name
2308 in a platform-specific way (`libcrypto.so` on Linux, for example), and
2309 link that in. If you want the module to have a different name from the
2310 actual library, you can use the `"link_name"` attribute, like:
2313 #[link_name = "crypto"]
2314 extern mod something {
2315 fn SHA1(src: *u8, sz: uint, out: *u8) -> *u8;
2319 ## Foreign calling conventions
2321 Most foreign code will be C code, which usually uses the `cdecl` calling
2322 convention, so that is what Rust uses by default when calling foreign
2323 functions. Some foreign functions, most notably the Windows API, use other
2324 calling conventions, so Rust provides a way to hint to the compiler which
2325 is expected by using the `"abi"` attribute:
2328 #[cfg(target_os = "win32")]
2330 extern mod kernel32 {
2331 fn SetEnvironmentVariableA(n: *u8, v: *u8) -> int;
2335 The `"abi"` attribute applies to a foreign module (it can not be applied
2336 to a single function within a module), and must be either `"cdecl"`
2337 or `"stdcall"`. Other conventions may be defined in the future.
2341 The foreign `SHA1` function is declared to take three arguments, and
2345 # extern mod crypto {
2346 fn SHA1(src: *u8, sz: libc::c_uint, out: *u8) -> *u8;
2350 When declaring the argument types to a foreign function, the Rust
2351 compiler has no way to check whether your declaration is correct, so
2352 you have to be careful. If you get the number or types of the
2353 arguments wrong, you're likely to get a segmentation fault. Or,
2354 probably even worse, your code will work on one platform, but break on
2357 In this case, `SHA1` is defined as taking two `unsigned char*`
2358 arguments and one `unsigned long`. The rust equivalents are `*u8`
2359 unsafe pointers and an `uint` (which, like `unsigned long`, is a
2360 machine-word-sized type).
2362 Unsafe pointers can be created through various functions in the
2363 standard lib, usually with `unsafe` somewhere in their name. You can
2364 dereference an unsafe pointer with `*` operator, but use
2365 cautionāunlike Rust's other pointer types, unsafe pointers are
2366 completely unmanaged, so they might point at invalid memory, or be
2371 The `sha1` function is the most obscure part of the program.
2374 # mod crypto { fn SHA1(src: *u8, sz: uint, out: *u8) -> *u8 { out } }
2375 # fn as_hex(data: ~[u8]) -> ~str { ~"hi" }
2376 fn sha1(data: ~str) -> ~str {
2378 let bytes = str::to_bytes(data);
2379 let hash = crypto::SHA1(vec::unsafe::to_ptr(bytes),
2380 vec::len(bytes), ptr::null());
2381 return as_hex(vec::unsafe::from_buf(hash, 20u));
2386 Firstly, what does the `unsafe` keyword at the top of the function
2387 mean? `unsafe` is a block modifierāit declares the block following it
2388 to be known to be unsafe.
2390 Some operations, like dereferencing unsafe pointers or calling
2391 functions that have been marked unsafe, are only allowed inside unsafe
2392 blocks. With the `unsafe` keyword, you're telling the compiler 'I know
2393 what I'm doing'. The main motivation for such an annotation is that
2394 when you have a memory error (and you will, if you're using unsafe
2395 constructs), you have some idea where to lookāit will most likely be
2396 caused by some unsafe code.
2398 Unsafe blocks isolate unsafety. Unsafe functions, on the other hand,
2399 advertise it to the world. An unsafe function is written like this:
2402 unsafe fn kaboom() { ~"I'm harmless!"; }
2405 This function can only be called from an unsafe block or another
2410 The standard library defines a number of helper functions for dealing
2411 with unsafe data, casting between types, and generally subverting
2412 Rust's safety mechanisms.
2414 Let's look at our `sha1` function again.
2417 # mod crypto { fn SHA1(src: *u8, sz: uint, out: *u8) -> *u8 { out } }
2418 # fn as_hex(data: ~[u8]) -> ~str { ~"hi" }
2419 # fn x(data: ~str) -> ~str {
2421 let bytes = str::to_bytes(data);
2422 let hash = crypto::SHA1(vec::unsafe::to_ptr(bytes),
2423 vec::len(bytes), ptr::null());
2424 return as_hex(vec::unsafe::from_buf(hash, 20u));
2429 The `str::to_bytes` function is perfectly safe: it converts a string to
2430 a `[u8]`. This byte array is then fed to `vec::unsafe::to_ptr`, which
2431 returns an unsafe pointer to its contents.
2433 This pointer will become invalid as soon as the vector it points into
2434 is cleaned up, so you should be very careful how you use it. In this
2435 case, the local variable `bytes` outlives the pointer, so we're good.
2437 Passing a null pointer as the third argument to `SHA1` makes it use a
2438 static buffer, and thus save us the effort of allocating memory
2439 ourselves. `ptr::null` is a generic function that will return an
2440 unsafe null pointer of the correct type (Rust generics are awesome
2441 like thatāthey can take the right form depending on the type that they
2442 are expected to return).
2444 Finally, `vec::unsafe::from_buf` builds up a new `[u8]` from the
2445 unsafe pointer that was returned by `SHA1`. SHA1 digests are always
2446 twenty bytes long, so we can pass `20u` for the length of the new
2449 ## Passing structures
2451 C functions often take pointers to structs as arguments. Since Rust
2452 records are binary-compatible with C structs, Rust programs can call
2453 such functions directly.
2455 This program uses the POSIX function `gettimeofday` to get a
2456 microsecond-resolution timer.
2460 import libc::c_ulonglong;
2462 type timeval = {mut tv_sec: c_ulonglong,
2463 mut tv_usec: c_ulonglong};
2466 fn gettimeofday(tv: *timeval, tz: *()) -> i32;
2468 fn unix_time_in_microseconds() -> u64 unsafe {
2469 let x = {mut tv_sec: 0 as c_ulonglong, mut tv_usec: 0 as c_ulonglong};
2470 lib_c::gettimeofday(ptr::addr_of(x), ptr::null());
2471 return (x.tv_sec as u64) * 1000_000_u64 + (x.tv_usec as u64);
2474 # fn main() { assert fmt!("%?", unix_time_in_microseconds()) != ~""; }
2477 The `#[nolink]` attribute indicates that there's no foreign library to
2478 link in. The standard C library is already linked with Rust programs.
2480 A `timeval`, in C, is a struct with two 32-bit integers. Thus, we
2481 define a record type with the same contents, and declare
2482 `gettimeofday` to take a pointer to such a record.
2484 The second argument to `gettimeofday` (the time zone) is not used by
2485 this program, so it simply declares it to be a pointer to the nil
2486 type. Since all null pointers have the same representation regardless of
2487 their referent type, this is safe.
2491 Rust supports a system of lightweight tasks, similar to what is found
2492 in Erlang or other actor systems. Rust tasks communicate via messages
2493 and do not share data. However, it is possible to send data without
2494 copying it by making use of [the exchange heap](#unique-boxes), which
2495 allow the sending task to release ownership of a value, so that the
2496 receiving task can keep on using it.
2498 > ***Note:*** As Rust evolves, we expect the task API to grow and
2499 > change somewhat. The tutorial documents the API as it exists today.
2503 Spawning a task is done using the various spawn functions in the
2504 module `task`. Let's begin with the simplest one, `task::spawn()`:
2510 let some_value = 22;
2513 println(~"This executes in the child task.");
2514 println(fmt!("%d", some_value));
2518 The argument to `task::spawn()` is a [unique
2519 closure](#unique-closures) of type `fn~()`, meaning that it takes no
2520 arguments and generates no return value. The effect of `task::spawn()`
2521 is to fire up a child task that will execute the closure in parallel
2526 Now that we have spawned a child task, it would be nice if we could
2527 communicate with it. This is done using *pipes*. Pipes are simply a
2528 pair of endpoints, with one for sending messages and another for
2529 receiving messages. The easiest way to create a pipe is to use
2530 `pipes::stream`. Imagine we wish to perform two expensive
2531 computations in parallel. We might write something like:
2535 import pipes::{stream, Port, Chan};
2537 let (chan, port) = stream();
2540 let result = some_expensive_computation();
2544 some_other_expensive_computation();
2545 let result = port.recv();
2547 # fn some_expensive_computation() -> int { 42 }
2548 # fn some_other_expensive_computation() {}
2551 Let's walk through this code line-by-line. The first line creates a
2552 stream for sending and receiving integers:
2555 # import pipes::stream;
2556 let (chan, port) = stream();
2559 This port is where we will receive the message from the child task
2560 once it is complete. The channel will be used by the child to send a
2561 message to the port. The next statement actually spawns the child:
2564 # import task::{spawn};
2565 # import comm::{Port, Chan};
2566 # fn some_expensive_computation() -> int { 42 }
2567 # let port = Port();
2568 # let chan = port.chan();
2570 let result = some_expensive_computation();
2575 This child will perform the expensive computation send the result
2576 over the channel. (Under the hood, `chan` was captured by the
2577 closure that forms the body of the child task. This capture is
2578 allowed because channels are sendable.)
2580 Finally, the parent continues by performing
2581 some other expensive computation and then waiting for the child's result
2582 to arrive on the port:
2585 # import pipes::{stream, Port, Chan};
2586 # fn some_other_expensive_computation() {}
2587 # let (chan, port) = stream::<int>();
2589 some_other_expensive_computation();
2590 let result = port.recv();
2593 ## Creating a task with a bi-directional communication path
2595 A very common thing to do is to spawn a child task where the parent
2596 and child both need to exchange messages with each other. The
2597 function `std::comm::DuplexStream()` supports this pattern. We'll
2598 look briefly at how it is used.
2600 To see how `spawn_conversation()` works, we will create a child task
2601 that receives `uint` messages, converts them to a string, and sends
2602 the string in response. The child terminates when `0` is received.
2603 Here is the function that implements the child task:
2606 # import std::comm::DuplexStream;
2607 # import pipes::{Port, Chan};
2608 fn stringifier(channel: DuplexStream<~str, uint>) {
2609 let mut value: uint;
2611 value = channel.recv();
2612 channel.send(uint::to_str(value, 10u));
2613 if value == 0u { break; }
2618 The implementation of `DuplexStream` supports both sending and
2619 receiving. The `stringifier` function takes a `DuplexStream` that can
2620 send strings (the first type parameter) and receive `uint` messages
2621 (the second type parameter). The body itself simply loops, reading
2622 from the channel and then sending its response back. The actual
2623 response itself is simply the strified version of the received value,
2624 `uint::to_str(value)`.
2626 Here is the code for the parent task:
2629 # import std::comm::DuplexStream;
2630 # import pipes::{Port, Chan};
2631 # import task::spawn;
2632 # fn stringifier(channel: DuplexStream<~str, uint>) {
2633 # let mut value: uint;
2635 # value = channel.recv();
2636 # channel.send(uint::to_str(value, 10u));
2637 # if value == 0u { break; }
2642 let (from_child, to_child) = DuplexStream();
2645 stringifier(to_child);
2648 from_child.send(22u);
2649 assert from_child.recv() == ~"22";
2651 from_child.send(23u);
2652 from_child.send(0u);
2654 assert from_child.recv() == ~"23";
2655 assert from_child.recv() == ~"0";
2660 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
2661 and child can send and receive data to and from the other.
2665 The Rust language has a facility for testing built into the language.
2666 Tests can be interspersed with other code, and annotated with the
2667 `#[test]` attribute.
2670 # // FIXME: xfailed because test_twice is a #[test] function it's not
2671 # // getting compiled
2674 fn twice(x: int) -> int { x + x }
2680 assert twice(i) == 2 * i;
2686 When you compile the program normally, the `test_twice` function will
2687 not be included. To compile and run such tests, compile with the
2688 `--test` flag, and then run the result:
2691 > rustc --test twice.rs
2694 test test_twice ... ok
2695 result: ok. 1 passed; 0 failed; 0 ignored
2698 Or, if we change the file to fail, for example by replacing `x + x`
2703 test test_twice ... FAILED
2706 result: FAILED. 0 passed; 1 failed; 0 ignored
2709 You can pass a command-line argument to a program compiled with
2710 `--test` to run only the tests whose name matches the given string. If
2711 we had, for example, test functions `test_twice`, `test_once_1`, and
2712 `test_once_2`, running our program with `./twice test_once` would run
2713 the latter two, and running it with `./twice test_once_2` would run
2716 To indicate that a test is supposed to fail instead of pass, you can
2717 give it a `#[should_fail]` attribute.
2722 fn divide(a: float, b: float) -> float {
2723 if b == 0f { fail; }
2729 fn divide_by_zero() { divide(1f, 0f); }
2734 To disable a test completely, add an `#[ignore]` attribute. Running a
2735 test runner (the program compiled with `--test`) with an `--ignored`
2736 command-line flag will cause it to also run the tests labelled as
2739 A program compiled as a test runner will have the configuration flag
2740 `test` defined, so that you can add code that won't be included in a
2741 normal compile with the `#[cfg(test)]` attribute (see [conditional
2742 compilation](#attributes)).