]> git.lizzy.rs Git - rust.git/blob - doc/tutorial.md
6d0ddca47bec50ec83b97b8a6ebc5bd68d1cca27
[rust.git] / doc / tutorial.md
1 % Rust Language Tutorial
2
3 # Introduction
4
5 ## Scope
6
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).
13
14 ## Language overview
15
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.
24
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:
28
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
33   not share memory.
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
39   called _traits_.
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.
44
45 ## First impressions
46
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.
49
50 ~~~~
51 fn boring_old_factorial(n: int) -> int {
52     let mut result = 1, i = 1;
53     while i <= n {
54         result *= i;
55         i += 1;
56     }
57     return result;
58 }
59 ~~~~
60
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).
66
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.
71
72 ## Conventions
73
74 Throughout the tutorial, words that indicate language keywords or
75 identifiers defined in the example code are displayed in `code font`.
76
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.
82
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.
86
87 # Getting started
88
89 ## Installation
90
91 The Rust compiler currently must be built from a [tarball][]. We hope
92 to be distributing binary packages for various operating systems in
93 the future.
94
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
98 builds require that:
99
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
106
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.
110
111 To build from source you will also need the following prerequisite
112 packages:
113
114   * g++ 4.4 or clang++ 3.x
115   * python 2.6 or later
116   * perl 5.0 or later
117   * gnu make 3.81 or later
118   * curl
119
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.
124
125 ~~~~ {.notrust}
126 $ wget http://dl.rust-lang.org/dist/rust-0.4.tar.gz
127 $ tar -xzf rust-0.4.tar.gz
128 $ cd rust-0.4
129 $ ./configure
130 $ make && make install
131 ~~~~
132
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.
138
139 When complete, `make install` will place the following programs into
140 `/usr/local/bin`:
141
142   * `rustc`, the Rust compiler
143   * `rustdoc`, the API-documentation tool
144   * `cargo`, the Rust package manager
145
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
148
149 ## Compiling your first program
150
151 Rust program files are, by convention, given the extension `.rs`. Say
152 we have a file `hello.rs` containing this program:
153
154 ~~~~
155 fn main() {
156     io::println("hello world!");
157 }
158 ~~~~
159
160 If the Rust compiler was installed successfully, running `rustc
161 hello.rs` will produce a binary called `hello` (or `hello.exe`).
162
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:
166
167 ~~~~ {.notrust}
168 hello.rs:2:4: 2:16 error: unresolved name: io::print_it
169 hello.rs:2     io::print_it("hello world!");
170                ^~~~~~~~~~~~
171 ~~~~
172
173 The Rust compiler tries to provide useful information when it runs
174 into an error.
175
176 ## Anatomy of a Rust program
177
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.
183
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).
188
189 [std]: http://doc.rust-lang.org/doc/std
190
191 ## Editing Rust code
192
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).
198
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.
201
202 # Syntax Basics
203
204 ## Braces
205
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.
211
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:
217
218 ~~~~
219 # fn it_works() {}
220 # fn abort() {}
221 fn main() {
222     while true {
223         /* Ensure that basic math works. */
224         if 2*20 > 30 {
225             // Everything is OK.
226             it_works();
227         } else {
228             abort();
229         }
230         break;
231     }
232 }
233 ~~~~
234
235 ## Expression syntax
236
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:
242
243 ~~~~
244 # let item = "salad";
245 let price;
246 if item == "salad" {
247     price = 3.50;
248 } else if item == "muffin" {
249     price = 2.25;
250 } else {
251     price = 2.00;
252 }
253 ~~~~
254
255 But, in Rust, you don't have to repeat the name `price`:
256
257 ~~~~
258 # let item = "salad";
259 let price = if item == "salad" { 3.50 }
260             else if item == "muffin" { 2.25 }
261             else { 2.00 };
262 ~~~~
263
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
268 expression.
269
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
274 was taken.
275
276 This feature also works for function bodies. This function returns a boolean:
277
278 ~~~~
279 fn is_four(x: int) -> bool { x == 4 }
280 ~~~~
281
282 In short, everything that's not a declaration (`let` for variables,
283 `fn` for functions, et cetera) is an expression.
284
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.
294
295 ## Identifiers
296
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
302 letter.
303
304 The double-colon (`::`) is used as a module separator, so
305 `io::println` means 'the thing named `println` in the module
306 named `io`.
307
308 ## Variable declaration
309
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`:
314
315 ~~~~
316 const REPEAT: int = 5;
317 fn main() {
318     let hi = "Hi!";
319     let mut count = 0;
320     while count < REPEAT {
321         io::println(hi);
322         count += 1;
323     }
324 }
325 ~~~~
326
327 Local variables may shadow earlier declarations, making the earlier variables
328 inaccessible.
329
330 ~~~~
331 let my_favorite_value: float = 57.8;
332 let my_favorite_value: int = my_favorite_value as int;
333 ~~~~
334
335 ## Types
336
337 The basic types are written like this:
338
339 `()`
340   : Nil, the type that has only a single value.
341
342 `bool`
343   : Boolean type, with values `true` and `false`.
344
345 `int`
346   : A machine-pointer-sized integer.
347
348 `uint`
349   : A machine-pointer-sized unsigned integer.
350
351 `i8`, `i16`, `i32`, `i64`
352   : Signed integers with a specific size (in bits).
353
354 `u8`, `u16`, `u32`, `u64`
355   : Unsigned integers with a specific size.
356
357 `float`
358   : The largest floating-point type efficiently supported on the target
359     machine.
360
361 `f32`, `f64`
362   : Floating-point types with a specific size.
363
364 `char`
365   : A Unicode character (32 bits).
366
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):
369
370 `[T * N]`
371   : Vector (like an array in other languages) with N elements.
372
373 `[mut T * N]`
374   : Mutable vector with N elements.
375
376 `(T1, T2)`
377   : Tuple type. Any arity above 1 is supported.
378
379 `@T`, `~T`, `&T`
380   : Pointer types. See [Boxes and pointers](#boxes-and-pointers) for an explanation of what `@`, `~`, and `&` mean.
381
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
385 of:
386
387 `fn(arg1: T1, arg2: T2) -> T3`
388   : Function types.
389
390 `str`
391   : String type (in UTF-8).
392
393 `[T]`
394   : Vector with unknown size (also called a slice).
395
396 `[mut T]`
397   : Mutable vector with unknown size.
398
399 Types can be given names with `type` declarations:
400
401 ~~~~
402 type MonsterSize = uint;
403 ~~~~
404
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
410 synonym.
411
412 ## Using types
413
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.
418
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
424 annotation:
425
426 ~~~~
427 // The type of this vector will be inferred based on its use.
428 let x = [];
429 # vec::map(x, fn&(_y: &int) -> int { *_y });
430 // Explicitly say this is a vector of zero integers.
431 let y: [int * 0] = [];
432 ~~~~
433
434 ## Numeric literals
435
436 Integers can be written in decimal (`144`), hexadecimal (`0x90`), and
437 binary (`0b10010000`) base.
438
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:
445
446 ~~~~
447 let x = 50;
448 log(error, x); // x is an int
449 let y = 100u;
450 log(error, y); // y is an uint
451 ~~~~
452
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.
456
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.
460
461 ## Other literals
462
463 The nil literal is written just like the type: `()`. The keywords
464 `true` and `false` produce the boolean literals.
465
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.
469
470 String literals allow the same escape sequences. They are written
471 between double quotes (`"hello"`). Rust strings may contain newlines.
472
473 ## Operators
474
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.
479
480 Note that, if applied to an integer value, `!` flips all the bits (like `~` in
481 C).
482
483 The comparison operators are the traditional `==`, `!=`, `<`, `>`,
484 `<=`, and `>=`. Short-circuiting (lazy) boolean operators are written
485 `&&` (and) and `||` (or).
486
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.
491
492 ~~~~
493 let x: float = 4.0;
494 let y: uint = x as uint;
495 assert y == 4u;
496 ~~~~
497
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).
502
503 ## Syntax extensions
504
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
510 time.
511
512 ~~~~
513 io::println(fmt!("%s is %d", ~"the answer", 42));
514 ~~~~
515
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.
519
520 [pf]: http://en.cppreference.com/w/cpp/io/c/fprintf
521
522 You can define your own syntax extensions with the macro system, which is out
523 of scope of this tutorial.
524
525 # Control structures
526
527 ## Conditionals
528
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:
532
533 ~~~~
534 if false {
535     io::println(~"that's odd");
536 } else if true {
537     io::println(~"right");
538 } else {
539     io::println(~"neither true nor false");
540 }
541 ~~~~
542
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
546 end of the block:
547
548 ~~~~
549 fn signum(x: int) -> int {
550     if x < 0 { -1 }
551     else if x > 0 { 1 }
552     else { return 0 }
553 }
554 ~~~~
555
556 ## Pattern matching
557
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.
562
563 ~~~~
564 # let my_number = 1;
565 match my_number {
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")
570 }
571 ~~~~
572
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.
576
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.
582
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
586 commas are optional.
587
588 ~~~
589 # let my_number = 1;
590 match my_number {
591   0 => {
592     io::println("zero")
593   }
594   _ => {
595     io::println("something else")
596   }
597 }
598 ~~~
599
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.
603
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:
607
608 ~~~~
609 use float::consts::pi;
610 fn angle(vector: (float, float)) -> float {
611     match vector {
612       (0f, y) if y < 0f => 1.5 * pi,
613       (0f, y) => 0.5 * pi,
614       (x, y) => float::atan(y / x)
615     }
616 }
617 ~~~~
618
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.
624
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.
629
630 ## Let
631
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:
635
636 ~~~~
637 # fn get_tuple_of_two_ints() -> (int, int) { (1, 1) }
638 let (a, b) = get_tuple_of_two_ints();
639 ~~~~
640
641 This will introduce two new variables, `a` and `b`, bound to the
642 content of the tuple.
643
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
646 not allowed.
647
648 ## Loops
649
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.
654
655 ~~~~
656 let mut cake_amount = 8;
657 while cake_amount > 0 {
658     cake_amount -= 1;
659 }
660 ~~~~
661
662 `loop` is the preferred way of writing `while true`:
663
664 ~~~~
665 let mut x = 5;
666 loop {
667     x += x - 3;
668     if x % 5 == 0 { break; }
669     io::println(int::str(x));
670 }
671 ~~~~
672
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.
675
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
678 in a moment.
679
680 # Functions
681
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)).
685
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.
689
690 ~~~~
691 fn repeat(string: &str, count: int) -> ~str {
692     let mut result = ~"";
693     for count.times {
694         result += string;
695     }
696     return result;
697 }
698 ~~~~
699
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
703 expression.
704
705 ~~~~
706 # const copernicus: int = 0;
707 fn int_to_str(i: int) -> ~str {
708     if i == copernicus {
709         return ~"tube sock";
710     } else {
711         return ~"violin";
712     }
713 }
714 ~~~~
715
716 ~~~~
717 # const copernicus: int = 0;
718 fn int_to_str(i: int) -> ~str {
719     if i == copernicus { ~"tube sock" }
720     else { ~"violin" }
721 }
722 ~~~~
723
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.
727
728 ~~~~
729 fn do_nothing_the_hard_way() -> () { return (); }
730
731 fn do_nothing_the_easy_way() { }
732 ~~~~
733
734 # Basic datatypes
735
736 The core datatypes of Rust are structs, enums (tagged unions, algebraic data
737 types), and tuples. They are immutable by default.
738
739 ~~~~
740 struct Point { x: float, y: float }
741
742 enum Shape {
743     Circle(Point, float),
744     Rectangle(Point, Point)
745 }
746 ~~~~
747
748 ## Structs
749
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 }`.
754
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`).
758
759 Fields that you want to mutate must be explicitly marked `mut`.
760
761 ~~~~
762 struct Stack {
763     content: ~[int],
764     mut head: uint
765 }
766 ~~~~
767
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.
770
771 ## Struct patterns
772
773 Structs can be destructured in `match` patterns. The basic syntax is
774 `Name {fieldname: pattern, ...}`:
775 ~~~~
776 # struct Point { x: float, y: float }
777 # let mypoint = Point { x: 0.0, y: 0.0 };
778 match mypoint {
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()); }
781 }
782 ~~~~
783
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.
788
789 ## Enums
790
791 Enums are datatypes that have several alternate representations. For
792 example, consider the type shown earlier:
793
794 ~~~~
795 # struct Point { x: float, y: float }
796 enum Shape {
797     Circle(Point, float),
798     Rectangle(Point, Point)
799 }
800 ~~~~
801
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.
807
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
812 create a new circle.
813
814 Enum variants need not have type parameters. This, for example, is
815 equivalent to a C enum:
816
817 ~~~~
818 enum Direction {
819     North,
820     East,
821     South,
822     West
823 }
824 ~~~~
825
826 This will define `North`, `East`, `South`, and `West` as constants,
827 all of which have type `Direction`.
828
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
831 to an integer value:
832
833 ~~~~
834 enum Color {
835   Red = 0xff0000,
836   Green = 0x00ff00,
837   Blue = 0x0000ff
838 }
839 ~~~~
840
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.
845
846 When an enum is C-like the `as` cast operator can be used to get the
847 discriminator's value.
848
849 <a name="single_variant_enum"></a>
850
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:
854
855 ~~~~
856 enum GizmoId = int;
857 ~~~~
858
859 That is a shorthand for this:
860
861 ~~~~
862 enum GizmoId { GizmoId(int) }
863 ~~~~
864
865 Enum types like this can have their content extracted with the
866 dereference (`*`) unary operator:
867
868 ~~~~
869 # enum GizmoId = int;
870 let my_gizmo_id = GizmoId(10);
871 let id_int: int = *my_gizmo_id;
872 ~~~~
873
874 ## Enum patterns
875
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`:
879
880 ~~~~
881 # type Point = {x: float, y: float};
882 # enum Shape { Circle(Point, float), Rectangle(Point, Point) }
883 fn area(sh: Shape) -> float {
884     match sh {
885         Circle(_, size) => float::consts::pi * size * size,
886         Rectangle({x, y}, {x: x2, y: y2}) => (x2 - x) * (y2 - y)
887     }
888 }
889 ~~~~
890
891 Another example, matching nullary enum variants:
892
893 ~~~~
894 # type Point = {x: float, y: float};
895 # enum Direction { North, East, South, West }
896 fn point_from_direction(dir: Direction) -> Point {
897     match dir {
898         North => {x:  0f, y:  1f},
899         East  => {x:  1f, y:  0f},
900         South => {x:  0f, y: -1f},
901         West  => {x: -1f, y:  0f}
902     }
903 }
904 ~~~~
905
906 ## Tuples
907
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).
912
913 ~~~~
914 let mytup: (int, int, float) = (10, 20, 30.0);
915 match mytup {
916   (a, b, c) => log(info, a + b + (c as int))
917 }
918 ~~~~
919
920 # The Rust memory model
921
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.
927
928 Rust has three competing goals that inform its view of memory:
929
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
937   allocation strategy
938 * Concurrency: Rust must maintain memory safety guarantees, even for
939   code running in parallel
940
941 ## How performance considerations influence the memory model
942
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.
951
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.
958
959 ## How concurrency considerations influence the memory model
960
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.
965
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.
972
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
982 expensive copies.
983
984 ## What to be aware of
985
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.
992
993 # Boxes and pointers
994
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.
1001
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.
1006
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.
1012
1013 All pointer types can be dereferenced with the `*` unary operator.
1014
1015 ## Shared boxes
1016
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
1022 box.
1023
1024 ~~~~
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
1028 ~~~~
1029
1030 Shared boxes never cross task boundaries.
1031
1032 > ***Note:*** shared boxes are currently reclaimed through reference
1033 > counting and cycle collection, but we will switch to a tracing
1034 > garbage collector.
1035
1036 ## Unique boxes
1037
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.
1042
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.
1046
1047 ~~~~
1048 let x = ~10;
1049 let y = x; // error: copying a non-implicitly copyable type
1050 ~~~~
1051
1052 If you really want to copy a unique box you must say so explicitly.
1053
1054 ~~~~
1055 let x = ~10;
1056 let y = copy x;
1057 ~~~~
1058
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).
1064
1065 ~~~~
1066 let x = ~10;
1067 let y <- x;
1068 ~~~~
1069
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.
1074
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.
1079
1080 ## Borrowed pointers
1081
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.
1088
1089 ~~~~
1090 # fn work_with_foo_by_pointer(f: &~str) { }
1091 let foo = ~"foo";
1092 work_with_foo_by_pointer(&foo);
1093 ~~~~
1094
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.
1098
1099 ~~~~ {.ignore}
1100 let foo_ptr;
1101 {
1102     let foo = ~"foo";
1103     foo_ptr = &foo;
1104 }
1105 ~~~~
1106
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).
1112
1113 ## Mutability
1114
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.
1118
1119 ~~~~
1120 fn increase_contents(pt: @mut int) {
1121     *pt += 1;
1122 }
1123 ~~~~
1124
1125 # Vectors
1126
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.
1130
1131 ~~~
1132 enum Crayon {
1133     Almond, AntiqueBrass, Apricot,
1134     Aquamarine, Asparagus, AtomicTangerine,
1135     BananaMania, Beaver, Bittersweet
1136 }
1137
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];
1144 ~~~
1145
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.
1150 >
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.
1155
1156 Vector literals are enclosed in square brackets and dereferencing is
1157 also done with square brackets (zero-based):
1158
1159 ~~~~
1160 # enum Crayon { Almond, AntiqueBrass, Apricot,
1161 #               Aquamarine, Asparagus, AtomicTangerine,
1162 #               BananaMania, Beaver, Bittersweet };
1163 # fn draw_scene(c: Crayon) { }
1164
1165 let crayons = ~[BananaMania, Beaver, Bittersweet];
1166 match crayons[0] {
1167     Bittersweet => draw_scene(crayons[0]),
1168     _ => ()
1169 }
1170 ~~~~
1171
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).
1176
1177 ~~~~
1178 # enum Crayon { Almond, AntiqueBrass, Apricot,
1179 #               Aquamarine, Asparagus, AtomicTangerine,
1180 #               BananaMania, Beaver, Bittersweet };
1181
1182 let crayons = ~[mut BananaMania, Beaver, Bittersweet];
1183 crayons[0] = AtomicTangerine;
1184 ~~~~
1185
1186 The `+` operator means concatenation when applied to vector types.
1187
1188 ~~~~
1189 # enum Crayon { Almond, AntiqueBrass, Apricot,
1190 #               Aquamarine, Asparagus, AtomicTangerine,
1191 #               BananaMania, Beaver, Bittersweet };
1192
1193 let my_crayons = ~[Almond, AntiqueBrass, Apricot];
1194 let your_crayons = ~[BananaMania, Beaver, Bittersweet];
1195
1196 let our_crayons = my_crayons + your_crayons;
1197 ~~~~
1198
1199 The `+=` operator also works as expected, provided the assignee
1200 lives in a mutable slot.
1201
1202 ~~~~
1203 # enum Crayon { Almond, AntiqueBrass, Apricot,
1204 #               Aquamarine, Asparagus, AtomicTangerine,
1205 #               BananaMania, Beaver, Bittersweet };
1206
1207 let mut my_crayons = ~[Almond, AntiqueBrass, Apricot];
1208 let your_crayons = ~[BananaMania, Beaver, Bittersweet];
1209
1210 my_crayons += your_crayons;
1211 ~~~~
1212
1213 ## Vector and string methods
1214
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.
1219
1220 ~~~
1221 # use io::println;
1222 # enum Crayon {
1223 #     Almond, AntiqueBrass, Apricot,
1224 #     Aquamarine, Asparagus, AtomicTangerine,
1225 #     BananaMania, Beaver, Bittersweet
1226 # }
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 { ~"" }
1231
1232 let crayons = ~[Almond, AntiqueBrass, Apricot];
1233
1234 // Check the length of the vector
1235 assert crayons.len() == 3;
1236 assert !crayons.is_empty();
1237
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);
1242 }
1243
1244 // Map vector elements
1245 let crayon_names = crayons.map(|v| crayon_to_str(*v));
1246 let favorite_crayon_name = crayon_names[0];
1247
1248 // Remove whitespace from before and after the string
1249 let new_favorite_crayon_name = favorite_crayon_name.trim();
1250
1251 if favorite_crayon_name.len() > 5 {
1252    // Create a substring
1253    println(favorite_crayon_name.substr(0, 5));
1254 }
1255 ~~~
1256
1257 # Closures
1258
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:
1262
1263 ~~~~ {.ignore}
1264 let foo = 10;
1265
1266 fn bar() -> int {
1267    return foo; // `bar` cannot refer to `foo`
1268 }
1269 ~~~~
1270
1271 Rust also supports _closures_, functions that can access variables in
1272 the enclosing scope.
1273
1274 ~~~~
1275 # use println = io::println;
1276 fn call_closure_with_ten(b: fn(int)) { b(10); }
1277
1278 let captured_var = 20;
1279 let closure = |arg| println(fmt!("captured_var=%d, arg=%d", captured_var, arg));
1280
1281 call_closure_with_ten(closure);
1282 ~~~~
1283
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.
1289
1290 ~~~~
1291 # type mygoodness = fn(~str) -> ~str; type what_the = int;
1292 let bloop = |well, oh: mygoodness| -> what_the { fail oh(well) };
1293 ~~~~
1294
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.
1298
1299 ~~~~
1300 let mut max = 0;
1301 (~[1, 2, 3]).map(|x| if *x > max { max = *x });
1302 ~~~~
1303
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.
1311
1312 ## Shared closures
1313
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).
1319
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.
1324
1325 This code creates a closure that adds a given string to its argument,
1326 returns it from a function, and then calls it:
1327
1328 ~~~~
1329 extern mod std;
1330
1331 fn mk_appender(suffix: ~str) -> fn@(~str) -> ~str {
1332     return fn@(s: ~str) -> ~str { s + suffix };
1333 }
1334
1335 fn main() {
1336     let shout = mk_appender(~"!");
1337     io::println(shout(~"hey ho, let's go"));
1338 }
1339 ~~~~
1340
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
1346 be written:
1347
1348 ~~~~
1349 fn mk_appender(suffix: ~str) -> fn@(~str) -> ~str {
1350     return |s| s + suffix;
1351 }
1352 ~~~~
1353
1354 ## Unique closures
1355
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).
1362
1363 ## Closure compatibility
1364
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.
1371
1372 ~~~~
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);
1380 ~~~~
1381
1382 ## Do syntax
1383
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:
1388
1389 ~~~~
1390 fn each(v: ~[int], op: fn(v: &int)) {
1391    let mut n = 0;
1392    while n < v.len() {
1393        op(&v[n]);
1394        n += 1;
1395    }
1396 }
1397 ~~~~
1398
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.
1406
1407 ~~~~
1408 # fn each(v: ~[int], op: fn(v: &int)) { }
1409 # fn do_some_work(i: int) { }
1410 each(~[1, 2, 3], |n| {
1411     debug!("%i", *n);
1412     do_some_work(*n);
1413 });
1414 ~~~~
1415
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:
1418
1419 ~~~~
1420 # fn each(v: ~[int], op: fn(v: &int)) { }
1421 # fn do_some_work(i: int) { }
1422 do each(~[1, 2, 3]) |n| {
1423     debug!("%i", *n);
1424     do_some_work(*n);
1425 }
1426 ~~~~
1427
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.
1433
1434 `do` is often used for task spawning.
1435
1436 ~~~~
1437 use task::spawn;
1438
1439 do spawn() || {
1440     debug!("I'm a task, whatever");
1441 }
1442 ~~~~
1443
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
1446 there?
1447
1448 ~~~~
1449 # use task::spawn;
1450 do spawn {
1451    debug!("Kablam!");
1452 }
1453 ~~~~
1454
1455 Empty argument lists can be omitted from `do` expressions.
1456
1457 ## For loops
1458
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`.
1463
1464 Consider again our `each` function, this time improved to
1465 break early when the iteratee returns `false`:
1466
1467 ~~~~
1468 fn each(v: ~[int], op: fn(v: &int) -> bool) {
1469    let mut n = 0;
1470    while n < v.len() {
1471        if !op(&v[n]) {
1472            break;
1473        }
1474        n += 1;
1475    }
1476 }
1477 ~~~~
1478
1479 And using this function to iterate over a vector:
1480
1481 ~~~~
1482 # use each = vec::each;
1483 # use println = io::println;
1484 each(~[2, 4, 8, 5, 16], |n| {
1485     if *n % 2 != 0 {
1486         println(~"found odd number!");
1487         false
1488     } else { true }
1489 });
1490 ~~~~
1491
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`.
1497
1498 ~~~~
1499 # use each = vec::each;
1500 # use println = io::println;
1501 for each(~[2, 4, 8, 5, 16]) |n| {
1502     if *n % 2 != 0 {
1503         println(~"found odd number!");
1504         break;
1505     }
1506 }
1507 ~~~~
1508
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.
1513
1514 ~~~~
1515 # use each = vec::each;
1516 fn contains(v: ~[int], elt: int) -> bool {
1517     for each(v) |x| {
1518         if (*x == elt) { return true; }
1519     }
1520     false
1521 }
1522 ~~~~
1523
1524 `for` syntax only works with stack closures.
1525
1526 # Generics
1527
1528 ## Generic functions
1529
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
1533 type parameters.
1534
1535 ~~~~
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));
1540     }
1541     return accumulator;
1542 }
1543 ~~~~
1544
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.
1548
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.
1557
1558 ## Generic datatypes
1559
1560 Generic `type`, `struct`, and `enum` declarations follow the same pattern:
1561
1562 ~~~~
1563 struct Stack<T> {
1564     elements: ~[mut T]
1565 }
1566
1567 enum Maybe<T> {
1568     Just(T),
1569     Nothing
1570 }
1571 ~~~~
1572
1573 These declarations produce valid types like `Stack<u8>` and `Maybe<int>`.
1574
1575 ## Kinds
1576
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).
1581
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.
1586
1587 ~~~~ {.ignore}
1588 // This does not compile
1589 fn head_bad<T>(v: ~[T]) -> T { v[0] }
1590 // This does
1591 fn head<T: Copy>(v: ~[T]) -> T { v[0] }
1592 ~~~~
1593
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:
1597
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
1603   types.
1604 * `Const` - Constant types. These are types that do not contain
1605   mutable fields nor shared boxes.
1606
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
1611 > knowledge about.
1612
1613 # Traits
1614
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
1618 collections.
1619
1620 > ***Note:*** This feature is very new, and will need a few extensions to be
1621 > applicable to more advanced use cases.
1622
1623 ## Declaration
1624
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)`.
1628
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:
1631
1632 ~~~~
1633 trait ToStr {
1634     fn to_str() -> ~str;
1635 }
1636 ~~~~
1637
1638 ## Implementation
1639
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
1642 `~str` types.
1643
1644 ~~~~
1645 # trait ToStr { fn to_str() -> ~str; }
1646 impl int: ToStr {
1647     fn to_str() -> ~str { int::to_str(self, 10u) }
1648 }
1649 impl ~str: ToStr {
1650     fn to_str() -> ~str { self }
1651 }
1652 ~~~~
1653
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.
1659
1660 ## Bounded type parameters
1661
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
1667 parameters.
1668
1669 ~~~~
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();
1677     }
1678     return result;
1679 }
1680 ~~~~
1681
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.
1689
1690 ## Polymorphic traits
1691
1692 Traits may contain type parameters. A trait for
1693 generalized sequence types is:
1694
1695 ~~~~
1696 trait Seq<T> {
1697     fn len() -> uint;
1698     fn iter(b: fn(v: &T));
1699 }
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); }
1704     }
1705 }
1706 ~~~~
1707
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.
1710
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.
1715
1716 ## The `self` type in traits
1717
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:
1722
1723 ~~~~
1724 trait Eq {
1725   fn equals(&&other: self) -> bool;
1726 }
1727
1728 impl int: Eq {
1729   fn equals(&&other: int) -> bool { other == self }
1730 }
1731 ~~~~
1732
1733 Notice that `equals` takes an `int` argument, rather than a `self` argument, in
1734 an implementation for type `int`.
1735
1736 ## Casting to a trait type
1737
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:
1741
1742 ~~~~
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(); }
1749 }
1750 # let c: Circle = new_circle();
1751 # draw_all(~[c]);
1752 ~~~~
1753
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.
1757
1758 When this is needed, a trait name can be used as a type, causing
1759 the function to be written simply like this:
1760
1761 ~~~~
1762 # trait Drawable { fn draw(); }
1763 fn draw_all(shapes: ~[Drawable]) {
1764     for shapes.each |shape| { shape.draw(); }
1765 }
1766 ~~~~
1767
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
1774 languages.
1775
1776 To construct such a value, you use the `as` operator to cast a value
1777 to a trait type:
1778
1779 ~~~~
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]);
1789 ~~~~
1790
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.
1795
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.
1799
1800 ## Trait-less implementations
1801
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
1808 choice.
1809
1810 # Modules and crates
1811
1812 The Rust namespace is divided into modules. Each source file starts
1813 with its own module.
1814
1815 ## Local modules
1816
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,
1820 `farm::chicken`.
1821
1822 ~~~~
1823 #[legacy_exports]
1824 mod farm {
1825     fn chicken() -> ~str { ~"cluck cluck" }
1826     fn cow() -> ~str { ~"mooo" }
1827 }
1828 fn main() {
1829     io::println(farm::chicken());
1830 }
1831 ~~~~
1832
1833 Modules can be nested to arbitrary depth.
1834
1835 ## Crates
1836
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
1839 one or more crates.
1840
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.
1845
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:
1849
1850 ~~~~ {.ignore}
1851 #[link(name = "farm", vers = "2.5", author = "mjh")];
1852 #[crate_type = "lib"];
1853 mod cow;
1854 mod chicken;
1855 mod horse;
1856 ~~~~
1857
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
1863 executable.)
1864
1865 The `#[link(...)]` part provides meta information about the module,
1866 which other crates can use to load the right module. More about that
1867 later.
1868
1869 To have a nested directory structure for your source files, you can
1870 nest mods in your `.rc` file:
1871
1872 ~~~~ {.ignore}
1873 mod poultry {
1874     mod chicken;
1875     mod turkey;
1876 }
1877 ~~~~
1878
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.
1883
1884 ## Using other crates
1885
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].
1890
1891 [std]: http://doc.rust-lang.org/doc/std/index/General.html
1892
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.
1897
1898 It is possible to provide more specific information when using an
1899 external crate.
1900
1901 ~~~~ {.ignore}
1902 extern mod myfarm (name = "farm", vers = "2.7");
1903 ~~~~
1904
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`.
1911
1912 Our example crate declared this set of `link` attributes:
1913
1914 ~~~~ {.ignore}
1915 #[link(name = "farm", vers = "2.5", author = "mjh")];
1916 ~~~~
1917
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.
1921
1922 ## The core library
1923
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
1926 Rust program.
1927
1928 This library is documented [here][core].
1929
1930 [core]: http://doc.rust-lang.org/doc/core
1931
1932 ## A minimal example
1933
1934 Now for something that you can actually compile yourself. We have
1935 these two files:
1936
1937 ~~~~
1938 // mylib.rs
1939 #[link(name = "mylib", vers = "1.0")];
1940 fn world() -> ~str { ~"world" }
1941 ~~~~
1942
1943 ~~~~ {.ignore}
1944 // main.rs
1945 extern mod mylib;
1946 fn main() { io::println(~"hello " + mylib::world()); }
1947 ~~~~
1948
1949 Now compile and run like this (adjust to your platform if necessary):
1950
1951 ~~~~ {.notrust}
1952 > rustc --lib mylib.rs
1953 > rustc main.rs -L .
1954 > ./main
1955 "hello world"
1956 ~~~~
1957
1958 ## Importing
1959
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.
1964
1965 ~~~~
1966 extern mod std;
1967 use io::println;
1968 fn main() {
1969     println(~"that was easy");
1970 }
1971 ~~~~
1972
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}`).
1977
1978 You can rename an identifier when importing using the `=` operator:
1979
1980 ~~~~
1981 use prnt = io::println;
1982 ~~~~
1983
1984 ## Exporting
1985
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.
1988
1989 ~~~~
1990 mod enc {
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 }
1995 }
1996 ~~~~
1997
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`.
2001
2002 ## Namespaces
2003
2004 Rust uses three different namespaces: one for modules, one for types,
2005 and one for values. This means that this code is valid:
2006
2007 ~~~~
2008 #[legacy_exports]
2009 mod buffalo {
2010     type buffalo = int;
2011     fn buffalo<buffalo>(+buffalo: buffalo) -> buffalo { buffalo }
2012 }
2013 fn main() {
2014     let buffalo: buffalo::buffalo = 1;
2015     buffalo::buffalo::<buffalo::buffalo>(buffalo::buffalo(buffalo));
2016 }
2017 ~~~~
2018
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
2021 modules.
2022
2023 ## Resolution
2024
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
2029 parent context.
2030
2031 Identifiers can shadow each other. In this program, `x` is of type
2032 `int`:
2033
2034 ~~~~
2035 type MyType = ~str;
2036 fn main() {
2037     type MyType = int;
2038     let x: MyType;
2039 }
2040 ~~~~
2041
2042 An `use` directive will only import into the namespaces for which
2043 identifiers are actually found. Consider this example:
2044
2045 ~~~~
2046 mod foo { fn bar() {} }
2047 fn baz() {
2048     let bar = 10u;
2049
2050     {
2051         use foo::bar;
2052         let quux = bar;
2053     }
2054 }
2055 ~~~~
2056
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
2061 there.
2062
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.
2068
2069 ~~~~
2070 fn main() {
2071     let x = 10;
2072     let x = x + 10;
2073     assert x == 20;
2074 }
2075 ~~~~
2076
2077 This makes it possible to rebind a variable without actually mutating
2078 it, which is mostly useful for destructuring (which can rebind, but
2079 not assign).
2080
2081 # Tasks
2082
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.
2089
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.
2092
2093 ## Spawning a task
2094
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()`:
2097
2098 ~~~~
2099 use task::spawn;
2100 use io::println;
2101
2102 let some_value = 22;
2103
2104 do spawn {
2105     println(~"This executes in the child task.");
2106     println(fmt!("%d", some_value));
2107 }
2108 ~~~~
2109
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
2114 with the creator.
2115
2116 ## Communication
2117
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:
2124
2125 ~~~~
2126 use task::spawn;
2127 use pipes::{stream, Port, Chan};
2128
2129 let (chan, port) = stream();
2130
2131 do spawn {
2132     let result = some_expensive_computation();
2133     chan.send(result);
2134 }
2135
2136 some_other_expensive_computation();
2137 let result = port.recv();
2138
2139 # fn some_expensive_computation() -> int { 42 }
2140 # fn some_other_expensive_computation() {}
2141 ~~~~
2142
2143 Let's walk through this code line-by-line.  The first line creates a
2144 stream for sending and receiving integers:
2145
2146 ~~~~ {.ignore}
2147 # use pipes::stream;
2148 let (chan, port) = stream();
2149 ~~~~
2150
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:
2154
2155 ~~~~
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();
2161 do spawn {
2162     let result = some_expensive_computation();
2163     chan.send(result);
2164 }
2165 ~~~~
2166
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.)
2171
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:
2175
2176 ~~~~
2177 # use pipes::{stream, Port, Chan};
2178 # fn some_other_expensive_computation() {}
2179 # let (chan, port) = stream::<int>();
2180 # chan.send(0);
2181 some_other_expensive_computation();
2182 let result = port.recv();
2183 ~~~~
2184
2185 ## Creating a task with a bi-directional communication path
2186
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.
2191
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:
2196
2197 ~~~~
2198 # use std::comm::DuplexStream;
2199 # use pipes::{Port, Chan};
2200 fn stringifier(channel: &DuplexStream<~str, uint>) {
2201     let mut value: uint;
2202     loop {
2203         value = channel.recv();
2204         channel.send(uint::to_str(value, 10u));
2205         if value == 0u { break; }
2206     }
2207 }
2208 ~~~~
2209
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)`.
2217
2218 Here is the code for the parent task:
2219
2220 ~~~~
2221 # use std::comm::DuplexStream;
2222 # use pipes::{Port, Chan};
2223 # use task::spawn;
2224 # fn stringifier(channel: &DuplexStream<~str, uint>) {
2225 #     let mut value: uint;
2226 #     loop {
2227 #         value = channel.recv();
2228 #         channel.send(uint::to_str(value, 10u));
2229 #         if value == 0u { break; }
2230 #     }
2231 # }
2232 # fn main() {
2233
2234 let (from_child, to_child) = DuplexStream();
2235
2236 do spawn || {
2237     stringifier(&to_child);
2238 };
2239
2240 from_child.send(22u);
2241 assert from_child.recv() == ~"22";
2242
2243 from_child.send(23u);
2244 from_child.send(0u);
2245
2246 assert from_child.recv() == ~"23";
2247 assert from_child.recv() == ~"0";
2248
2249 # }
2250 ~~~~
2251
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.
2254
2255 # Testing
2256
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.
2260
2261 ~~~~{.xfail-test}
2262 # // FIXME: xfailed because test_twice is a #[test] function it's not
2263 # // getting compiled
2264 extern mod std;
2265
2266 fn twice(x: int) -> int { x + x }
2267
2268 #[test]
2269 fn test_twice() {
2270     let mut i = -100;
2271     while i < 100 {
2272         assert twice(i) == 2 * i;
2273         i += 1;
2274     }
2275 }
2276 ~~~~
2277
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:
2281
2282 ~~~~ {.notrust}
2283 > rustc --test twice.rs
2284 > ./twice
2285 running 1 tests
2286 test test_twice ... ok
2287 result: ok. 1 passed; 0 failed; 0 ignored
2288 ~~~~
2289
2290 Or, if we change the file to fail, for example by replacing `x + x`
2291 with `x + 1`:
2292
2293 ~~~~ {.notrust}
2294 running 1 tests
2295 test test_twice ... FAILED
2296 failures:
2297     test_twice
2298 result: FAILED. 0 passed; 1 failed; 0 ignored
2299 ~~~~
2300
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
2306 only the last.
2307
2308 To indicate that a test is supposed to fail instead of pass, you can
2309 give it a `#[should_fail]` attribute.
2310
2311 ~~~~
2312 extern mod std;
2313
2314 fn divide(a: float, b: float) -> float {
2315     if b == 0f { fail; }
2316     a / b
2317 }
2318
2319 #[test]
2320 #[should_fail]
2321 fn divide_by_zero() { divide(1f, 0f); }
2322
2323 # fn main() { }
2324 ~~~~
2325
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
2329 ignored.
2330
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)).