# SOME DESCRIPTIVE TITLE # Copyright (C) YEAR Free Software Foundation, Inc. # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2013-07-07 21:10+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #. type: Plain text #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4 #: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4 doc/tut.md:4 msgid "# Introduction" msgstr "" #. type: Plain text #: doc/rust.md:1231 doc/tutorial.md:2179 msgid "" "In type-parameterized functions, methods of the supertrait may be called on " "values of subtrait-bound type parameters. Refering to the previous example " "of `trait Circle : Shape`:" msgstr "" #. type: Plain text #: doc/rust.md:1240 doc/tutorial.md:2188 #, no-wrap msgid "" "~~~\n" "# trait Shape { fn area(&self) -> float; }\n" "# trait Circle : Shape { fn radius(&self) -> float; }\n" "fn radius_times_area(c: T) -> float {\n" " // `c` is both a Circle and a Shape\n" " c.radius() * c.area()\n" "}\n" "~~~\n" msgstr "" #. type: Plain text #: doc/rust.md:1242 doc/tutorial.md:2190 msgid "Likewise, supertrait methods may also be called on trait objects." msgstr "" #. type: Plain text #: doc/tutorial.md:2 doc/tut.md:2 msgid "% The Rust Language Tutorial" msgstr "" #. type: Plain text #: doc/tutorial.md:13 msgid "" "Rust is a programming language with a focus on type safety, memory safety, " "concurrency and performance. It is intended for writing large-scale, high-" "performance software that is free from several classes of common errors. " "Rust has a sophisticated memory model that encourages efficient data " "structures and safe concurrency patterns, forbidding invalid memory accesses " "that would otherwise cause segmentation faults. It is statically typed and " "compiled ahead of time." msgstr "" #. type: Plain text #: doc/tutorial.md:17 msgid "" "As a multi-paradigm language, Rust supports writing code in procedural, " "functional and object-oriented styles. Some of its pleasant high-level " "features include:" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:30 msgid "" "**Type inference.** Type annotations on local variable declarations are " "optional." msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:30 msgid "" "**Safe task-based concurrency.** Rust's lightweight tasks do not share " "memory, instead communicating through messages." msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:30 msgid "" "**Higher-order functions.** Efficient and flexible closures provide " "iteration and other control structures" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:30 msgid "" "**Pattern matching and algebraic data types.** Pattern matching on Rust's " "enumeration types (a more powerful version of C's enums, similar to " "algebraic data types in functional languages) is a compact and expressive " "way to encode program logic." msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:30 msgid "" "**Polymorphism.** Rust has type-parametric functions and types, type classes " "and OO-style interfaces." msgstr "" #. type: Plain text #: doc/tutorial.md:32 msgid "## Scope" msgstr "" #. type: Plain text #: doc/tutorial.md:38 msgid "" "This is an introductory tutorial for the Rust programming language. It " "covers the fundamentals of the language, including the syntax, the type " "system and memory model, generics, and modules. [Additional tutorials](#what-" "next) cover specific language features in greater depth." msgstr "" #. type: Plain text #: doc/tutorial.md:42 msgid "" "This tutorial assumes that the reader is already familiar with one or more " "languages in the C family. Understanding of pointers and general memory " "management techniques will help." msgstr "" #. type: Plain text #: doc/tutorial.md:44 msgid "## Conventions" msgstr "" #. type: Plain text #: doc/tutorial.md:47 msgid "" "Throughout the tutorial, language keywords and identifiers defined in " "example code are displayed in `code font`." msgstr "" #. type: Plain text #: doc/tutorial.md:53 msgid "" "Code snippets are indented, and also shown in a monospaced font. Not all " "snippets constitute whole programs. For brevity, we'll often show fragments " "of programs that don't compile on their own. To try them out, you might have " "to wrap them in `fn main() { ... }`, and make sure they don't contain " "references to names that aren't actually defined." msgstr "" #. type: Plain text #: doc/tutorial.md:57 msgid "" "> ***Warning:*** Rust is a language under ongoing development. Notes > about " "potential changes to the language, implementation > deficiencies, and other " "caveats appear offset in blockquotes." msgstr "" #. type: Plain text #: doc/tutorial.md:59 msgid "# Getting started" msgstr "" #. type: Plain text #: doc/tutorial.md:63 msgid "" "The Rust compiler currently must be built from a [tarball], unless you are " "on Windows, in which case using the [installer][win-exe] is recommended." msgstr "" #. type: Plain text #: doc/tutorial.md:69 msgid "" "Since the Rust compiler is written in Rust, it must be built by a " "precompiled \"snapshot\" version of itself (made in an earlier state of " "development). As such, source builds require a connection to the Internet, " "to fetch snapshots, and an OS that can execute the available snapshot " "binaries." msgstr "" #. type: Plain text #: doc/tutorial.md:71 msgid "Snapshot binaries are currently built and tested on several platforms:" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:75 msgid "Windows (7, Server 2008 R2), x86 only" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:75 msgid "Linux (various distributions), x86 and x86-64" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:75 msgid "OSX 10.6 (\"Snow Leopard\") or greater, x86 and x86-64" msgstr "" #. type: Plain text #: doc/tutorial.md:78 msgid "" "You may find that other platforms work, but these are our \"tier 1\" " "supported build environments that are most likely to work." msgstr "" #. type: Plain text #: doc/tutorial.md:85 msgid "" "> ***Note:*** Windows users should read the detailed > \"[getting started]" "[wiki-start]\" notes on the wiki. Even when using > the binary installer, " "the Windows build requires a MinGW installation, > the precise details of " "which are not discussed here. Finally, `rustc` may > need to be [referred to " "as `rustc.exe`][bug-3319]. It's a bummer, we > know." msgstr "" #. type: Plain text #: doc/tutorial.md:88 msgid "" "[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]:" "\thttps://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust" msgstr "" #. type: Plain text #: doc/tutorial.md:91 msgid "" "To build from source you will also need the following prerequisite packages:" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:97 msgid "g++ 4.4 or clang++ 3.x" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:97 msgid "python 2.6 or later (but not 3.x)" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:97 msgid "perl 5.0 or later" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:97 msgid "gnu make 3.81 or later" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:97 msgid "curl" msgstr "" #. type: Plain text #: doc/tutorial.md:100 msgid "" "If you've fulfilled those prerequisites, something along these lines should " "work." msgstr "" #. type: Plain text #: doc/tutorial.md:108 msgid "" "~~~~ {.notrust} $ curl -O http://static.rust-lang.org/dist/rust-0.7.tar.gz $ " "tar -xzf rust-0.7.tar.gz $ cd rust-0.7 $ ./configure $ make && make install " "~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:114 msgid "" "You may need to use `sudo make install` if you do not normally have " "permission to modify the destination directory. The install locations can be " "adjusted by passing a `--prefix` argument to `configure`. Various other " "options are also supported: pass `--help` for more information on them." msgstr "" #. type: Plain text #: doc/tutorial.md:120 msgid "" "When complete, `make install` will place several programs into `/usr/local/" "bin`: `rustc`, the Rust compiler; `rustdoc`, the API-documentation tool; " "`rustpkg`, the Rust package manager; `rusti`, the Rust REPL; and `rust`, a " "tool which acts both as a unified interface for them, and for a few common " "command line scenarios." msgstr "" #. type: Plain text #: doc/tutorial.md:124 msgid "" "[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-" "developing-Rust [tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz " "[win-exe]: http://static.rust-lang.org/dist/rust-0.7-install.exe" msgstr "" #. type: Plain text #: doc/tutorial.md:126 msgid "## Compiling your first program" msgstr "" #. type: Plain text #: doc/tutorial.md:129 msgid "" "Rust program files are, by convention, given the extension `.rs`. Say we " "have a file `hello.rs` containing this program:" msgstr "" #. type: Plain text #: doc/tutorial.md:135 #, no-wrap msgid "" "~~~~\n" "fn main() {\n" " println(\"hello?\");\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:139 msgid "" "If the Rust compiler was installed successfully, running `rustc hello.rs` " "will produce an executable called `hello` (or `hello.exe` on Windows) which, " "upon running, will likely do exactly what you expect." msgstr "" #. type: Plain text #: doc/tutorial.md:144 msgid "" "The Rust compiler tries to provide useful information when it encounters an " "error. If you introduce an error into the program (for example, by changing " "`println` to some nonexistent function), and then compile it, you'll see an " "error message like this:" msgstr "" #. type: Plain text #: doc/tutorial.md:150 #, no-wrap msgid "" "~~~~ {.notrust}\n" "hello.rs:2:4: 2:16 error: unresolved name: print_with_unicorns\n" "hello.rs:2 print_with_unicorns(\"hello?\");\n" " ^~~~~~~~~~~~~~~~~~~~~~~\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:157 msgid "" "In its simplest form, a Rust program is a `.rs` file with some types and " "functions defined in it. If it has a `main` function, it can be compiled to " "an executable. Rust does not allow code that's not a declaration to appear " "at the top level of the file: all statements must live inside a function. " "Rust programs can also be compiled as libraries, and included in other " "programs." msgstr "" #. type: Plain text #: doc/tutorial.md:159 msgid "## Using the rust tool" msgstr "" #. type: Plain text #: doc/tutorial.md:164 msgid "" "While using `rustc` directly to generate your executables, and then running " "them manually is a perfectly valid way to test your code, for smaller " "projects, prototypes, or if you're a beginner, it might be more convenient " "to use the `rust` tool." msgstr "" #. type: Plain text #: doc/tutorial.md:170 msgid "" "The `rust` tool provides central access to the other rust tools, as well as " "handy shortcuts for directly running source files. For example, if you have " "a file `foo.rs` in your current directory, `rust run foo.rs` would attempt " "to compile it and, if successful, directly run the resulting binary." msgstr "" #. type: Plain text #: doc/tutorial.md:173 msgid "" "To get a list of all available commands, simply call `rust` without any " "argument." msgstr "" #. type: Plain text #: doc/tutorial.md:175 msgid "## Editing Rust code" msgstr "" #. type: Plain text #: doc/tutorial.md:185 msgid "" "There are vim highlighting and indentation scripts in the Rust source " "distribution under `src/etc/vim/`. There is an emacs mode under `src/etc/" "emacs/` called `rust-mode`, but do read the instructions included in that " "directory. In particular, if you are running emacs 24, then using emacs's " "internal package manager to install `rust-mode` is the easiest way to keep " "it up to date. There is also a package for Sublime Text 2, available both " "[standalone][sublime] and through [Sublime Package Control][sublime-pkg], " "and support for Kate under `src/etc/kate`." msgstr "" #. type: Plain text #: doc/tutorial.md:189 msgid "" "There is ctags support via `src/etc/ctags.rust`, but many other tools and " "editors are not yet supported. If you end up writing a Rust mode for your " "favorite editor, let us know so that we can link to it." msgstr "" #. type: Plain text #: doc/tutorial.md:192 msgid "" "[sublime]: http://github.com/dbp/sublime-rust [sublime-pkg]: http://wbond." "net/sublime_packages/package_control" msgstr "" #. type: Plain text #: doc/tutorial.md:194 msgid "# Syntax basics" msgstr "" #. type: Plain text #: doc/tutorial.md:202 msgid "" "Assuming you've programmed in any C-family language (C++, Java, JavaScript, " "C#, or PHP), Rust will feel familiar. Code is arranged in blocks delineated " "by curly braces; there are control structures for branching and looping, " "like the familiar `if` and `while`; function calls are written `myfunc(arg1, " "arg2)`; operators are written the same and mostly have the same precedence " "as in C; comments are again like C; module names are separated with double-" "colon (`::`) as with C++." msgstr "" #. type: Plain text #: doc/tutorial.md:207 msgid "" "The main surface difference to be aware of is that the condition at the head " "of control structures like `if` and `while` does not require parentheses, " "while their bodies *must* be wrapped in braces. Single-statement, unbraced " "bodies are not allowed." msgstr "" #. type: Plain text #: doc/tutorial.md:220 #, no-wrap msgid "" "~~~~\n" "# mod universe { pub fn recalibrate() -> bool { true } }\n" "fn main() {\n" " /* A simple loop */\n" " loop {\n" " // A tricky calculation\n" " if universe::recalibrate() {\n" " return;\n" " }\n" " }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:224 msgid "" "The `let` keyword introduces a local variable. Variables are immutable by " "default. To introduce a local variable that you can re-assign later, use " "`let mut` instead." msgstr "" #. type: Plain text #: doc/tutorial.md:228 msgid "~~~~ let hi = \"hi\"; let mut count = 0;" msgstr "" #. type: Plain text #: doc/tutorial.md:234 #, no-wrap msgid "" "while count < 10 {\n" " println(fmt!(\"count: %?\", count));\n" " count += 1;\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:238 msgid "" "Although Rust can almost always infer the types of local variables, you can " "specify a variable's type by following it with a colon, then the type name. " "Static items, on the other hand, always require a type annotation." msgstr "" #. type: Plain text #: doc/tutorial.md:244 msgid "" "~~~~ static MONSTER_FACTOR: float = 57.8; let monster_size = MONSTER_FACTOR " "* 10.0; let monster_size: int = 50; ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:253 msgid "" "Local variables may shadow earlier declarations, as in the previous example: " "`monster_size` was first declared as a `float`, and then a second " "`monster_size` was declared as an `int`. If you were to actually compile " "this example, though, the compiler would determine that the first " "`monster_size` is unused and issue a warning (because this situation is " "likely to indicate a programmer error). For occasions where unused variables " "are intentional, their names may be prefixed with an underscore to silence " "the warning, like `let _monster_size = 50;`." msgstr "" #. type: Plain text #: doc/tutorial.md:259 msgid "" "Rust identifiers start with an alphabetic character or an underscore, and " "after that may contain any sequence of alphabetic characters, numbers, or " "underscores. The preferred style is to write function, variable, and module " "names with lowercase letters, using underscores where they help readability, " "while writing types in camel case." msgstr "" #. type: Plain text #: doc/tutorial.md:264 #, no-wrap msgid "" "~~~\n" "let my_variable = 100;\n" "type MyType = int; // primitive types are _not_ camel case\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:266 msgid "## Expressions and semicolons" msgstr "" #. type: Plain text #: doc/tutorial.md:272 msgid "" "Though it isn't apparent in all code, there is a fundamental difference " "between Rust's syntax and predecessors like C. Many constructs that are " "statements in C are expressions in Rust, allowing code to be more concise. " "For example, you might write a piece of code like this:" msgstr "" #. type: Plain text #: doc/tutorial.md:284 #, no-wrap msgid "" "~~~~\n" "# let item = \"salad\";\n" "let price;\n" "if item == \"salad\" {\n" " price = 3.50;\n" "} else if item == \"muffin\" {\n" " price = 2.25;\n" "} else {\n" " price = 2.00;\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:286 msgid "But, in Rust, you don't have to repeat the name `price`:" msgstr "" #. type: Plain text #: doc/tutorial.md:298 #, no-wrap msgid "" "~~~~\n" "# let item = \"salad\";\n" "let price =\n" " if item == \"salad\" {\n" " 3.50\n" " } else if item == \"muffin\" {\n" " 2.25\n" " } else {\n" " 2.00\n" " };\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:304 msgid "" "Both pieces of code are exactly equivalent: they assign a value to `price` " "depending on the condition that holds. Note that there are no semicolons in " "the blocks of the second snippet. This is important: the lack of a semicolon " "after the last statement in a braced block gives the whole block the value " "of that last expression." msgstr "" #. type: Plain text #: doc/tutorial.md:310 msgid "" "Put another way, the semicolon in Rust *ignores the value of an " "expression*. Thus, if the branches of the `if` had looked like `{ 4; }`, " "the above example would simply assign `()` (nil or void) to `price`. But " "without the semicolon, each branch has a different value, and `price` gets " "the value of the branch that was taken." msgstr "" #. type: Plain text #: doc/tutorial.md:315 msgid "" "In short, everything that's not a declaration (declarations are `let` for " "variables; `fn` for functions; and any top-level named items such as [traits]" "(#traits), [enum types](#enums), and [constants](#constants)) is an " "expression, including function bodies." msgstr "" #. type: Plain text #: doc/tutorial.md:323 #, no-wrap msgid "" "~~~~\n" "fn is_four(x: int) -> bool {\n" " // No need for a return statement. The result of the expression\n" " // is used as the return value.\n" " x == 4\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:325 msgid "## Primitive types and literals" msgstr "" #. type: Plain text #: doc/tutorial.md:332 msgid "" "There are general signed and unsigned integer types, `int` and `uint`, as " "well as 8-, 16-, 32-, and 64-bit variants, `i8`, `u16`, etc. Integers can " "be written in decimal (`144`), hexadecimal (`0x90`), or binary " "(`0b10010000`) base. Each integral type has a corresponding literal suffix " "that can be used to indicate the type of a literal: `i` for `int`, `u` for " "`uint`, `i8` for the `i8` type." msgstr "" #. type: Plain text #: doc/tutorial.md:338 msgid "" "In the absence of an integer literal suffix, Rust will infer the integer " "type based on type annotations and function signatures in the surrounding " "program. In the absence of any type information at all, Rust will assume " "that an unsuffixed integer literal has type `int`." msgstr "" #. type: Plain text #: doc/tutorial.md:345 #, no-wrap msgid "" "~~~~\n" "let a = 1; // a is an int\n" "let b = 10i; // b is an int, due to the 'i' suffix\n" "let c = 100u; // c is a uint\n" "let d = 1000i32; // d is an i32\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:350 msgid "" "There are three floating-point types: `float`, `f32`, and `f64`. Floating-" "point numbers are written `0.0`, `1e6`, or `2.1e-4`. Like integers, " "floating-point literals are inferred to the correct type. Suffixes `f`, " "`f32`, and `f64` can be used to create literals of a specific type." msgstr "" #. type: Plain text #: doc/tutorial.md:352 msgid "The keywords `true` and `false` produce literals of type `bool`." msgstr "" #. type: Plain text #: doc/tutorial.md:359 msgid "" "Characters, the `char` type, are four-byte Unicode codepoints, whose " "literals are written between single quotes, as in `'x'`. Just like C, Rust " "understands a number of character escapes, using the backslash character, " "such as `\\n`, `\\r`, and `\\t`. String literals, written between double " "quotes, allow the same escape sequences. More on strings [later](#vectors-" "and-strings)." msgstr "" #. type: Plain text #: doc/tutorial.md:361 msgid "The nil type, written `()`, has a single value, also written `()`." msgstr "" #. type: Plain text #: doc/tutorial.md:363 msgid "## Operators" msgstr "" #. type: Plain text #: doc/tutorial.md:368 msgid "" "Rust's set of operators contains very few surprises. Arithmetic is done with " "`*`, `/`, `%`, `+`, and `-` (multiply, quotient, remainder, add, and " "subtract). `-` is also a unary prefix operator that negates numbers. As in " "C, the bitwise operators `>>`, `<<`, `&`, `|`, and `^` are also supported." msgstr "" #. type: Plain text #: doc/tutorial.md:371 msgid "" "Note that, if applied to an integer value, `!` flips all the bits (like `~` " "in C)." msgstr "" #. type: Plain text #: doc/tutorial.md:375 msgid "" "The comparison operators are the traditional `==`, `!=`, `<`, `>`, `<=`, and " "`>=`. Short-circuiting (lazy) boolean operators are written `&&` (and) and " "`||` (or)." msgstr "" #. type: Plain text #: doc/tutorial.md:380 msgid "" "For type casting, Rust uses the binary `as` operator. It takes an " "expression on the left side and a type on the right side and will, if a " "meaningful conversion exists, convert the result of the expression to the " "given type." msgstr "" #. type: Plain text #: doc/tutorial.md:386 msgid "" "~~~~ let x: float = 4.0; let y: uint = x as uint; assert!(y == 4u); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:388 msgid "## Syntax extensions" msgstr "" #. type: Plain text #: doc/tutorial.md:395 #, no-wrap msgid "" "*Syntax extensions* are special forms that are not built into the language,\n" "but are instead provided by the libraries. To make it clear to the reader when\n" "a name refers to a syntax extension, the names of all syntax extensions end\n" "with `!`. The standard library defines a few syntax extensions, the most\n" "useful of which is `fmt!`, a `sprintf`-style text formatter that you will\n" "often see in examples.\n" msgstr "" #. type: Plain text #: doc/tutorial.md:399 msgid "" "`fmt!` supports most of the directives that [printf][pf] supports, but " "unlike printf, will give you a compile-time error when the types of the " "directives don't match the types of the arguments." msgstr "" #. type: Plain text #: doc/tutorial.md:402 msgid "~~~~ # let mystery_object = ();" msgstr "" #. type: Plain text #: doc/tutorial.md:404 msgid "println(fmt!(\"%s is %d\", \"the answer\", 43));" msgstr "" #. type: Plain text #: doc/tutorial.md:408 msgid "" "// %? will conveniently print any type println(fmt!(\"what is this thing: %?" "\", mystery_object)); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:410 msgid "[pf]: http://en.cppreference.com/w/cpp/io/c/fprintf" msgstr "" #. type: Plain text #: doc/tutorial.md:412 msgid "" "You can define your own syntax extensions with the macro system. For " "details, see the [macro tutorial][macros]." msgstr "" #. type: Plain text #: doc/tutorial.md:414 msgid "[macros]: tutorial-macros.html" msgstr "" #. type: Plain text #: doc/tutorial.md:416 msgid "# Control structures" msgstr "" #. type: Plain text #: doc/tutorial.md:418 msgid "## Conditionals" msgstr "" #. type: Plain text #: doc/tutorial.md:422 msgid "" "We've seen `if` expressions a few times already. To recap, braces are " "compulsory, an `if` can have an optional `else` clause, and multiple `if`/" "`else` constructs can be chained together:" msgstr "" #. type: Plain text #: doc/tutorial.md:432 #, no-wrap msgid "" "~~~~\n" "if false {\n" " println(\"that's odd\");\n" "} else if true {\n" " println(\"right\");\n" "} else {\n" " println(\"neither true nor false\");\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:437 msgid "" "The condition given to an `if` construct *must* be of type `bool` (no " "implicit conversion happens). If the arms are blocks that have a value, this " "value must be of the same type for every arm in which control reaches the " "end of the block:" msgstr "" #. type: Plain text #: doc/tutorial.md:445 #, no-wrap msgid "" "~~~~\n" "fn signum(x: int) -> int {\n" " if x < 0 { -1 }\n" " else if x > 0 { 1 }\n" " else { return 0 }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:447 msgid "## Pattern matching" msgstr "" #. type: Plain text #: doc/tutorial.md:453 msgid "" "Rust's `match` construct is a generalized, cleaned-up version of C's " "`switch` construct. You provide it with a value and a number of *arms*, each " "labelled with a pattern, and the code compares the value against each " "pattern in order until one matches. The matching pattern executes its " "corresponding arm." msgstr "" #. type: Plain text #: doc/tutorial.md:463 #, no-wrap msgid "" "~~~~\n" "# let my_number = 1;\n" "match my_number {\n" " 0 => println(\"zero\"),\n" " 1 | 2 => println(\"one or two\"),\n" " 3..10 => println(\"three to ten\"),\n" " _ => println(\"something else\")\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:467 msgid "" "Unlike in C, there is no \"falling through\" between arms: only one arm " "executes, and it doesn't have to explicitly `break` out of the construct " "when it is finished." msgstr "" #. type: Plain text #: doc/tutorial.md:477 msgid "" "A `match` arm consists of a *pattern*, then an arrow `=>`, followed by an " "*action* (expression). Literals are valid patterns and match only their own " "value. A single arm may match multiple different patterns by combining them " "with the pipe operator (`|`), so long as every pattern binds the same set of " "variables. Ranges of numeric literal patterns can be expressed with two " "dots, as in `M..N`. The underscore (`_`) is a wildcard pattern that matches " "any single value. The asterisk (`*`) is a different wildcard that can match " "one or more fields in an `enum` variant." msgstr "" #. type: Plain text #: doc/tutorial.md:482 msgid "" "The patterns in a match arm are followed by a fat arrow, `=>`, then an " "expression to evaluate. Each case is separated by commas. It's often " "convenient to use a block expression for each case, in which case the commas " "are optional." msgstr "" #. type: Plain text #: doc/tutorial.md:490 #, no-wrap msgid "" "~~~\n" "# let my_number = 1;\n" "match my_number {\n" " 0 => { println(\"zero\") }\n" " _ => { println(\"something else\") }\n" "}\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:495 msgid "" "`match` constructs must be *exhaustive*: they must have an arm covering " "every possible case. For example, the typechecker would reject the previous " "example if the arm with the wildcard pattern was omitted." msgstr "" #. type: Plain text #: doc/tutorial.md:499 msgid "" "A powerful application of pattern matching is *destructuring*: matching in " "order to bind names to the contents of data types." msgstr "" #. type: Plain text #: doc/tutorial.md:503 msgid "" "> ***Note:*** The following code makes use of tuples (`(float, float)`) " "which > are explained in section 5.3. For now you can think of tuples as a " "list of > items." msgstr "" #. type: Plain text #: doc/tutorial.md:515 #, no-wrap msgid "" "~~~~\n" "# use std::float;\n" "fn angle(vector: (float, float)) -> float {\n" " let pi = float::consts::pi;\n" " match vector {\n" " (0f, y) if y < 0f => 1.5 * pi,\n" " (0f, y) => 0.5 * pi,\n" " (x, y) => float::atan(y / x)\n" " }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:521 msgid "" "A variable name in a pattern matches any value, *and* binds that name to the " "value of the matched value inside of the arm's action. Thus, `(0f, y)` " "matches any tuple whose first element is zero, and binds `y` to the second " "element. `(x, y)` matches any two-element tuple, and binds both elements to " "variables." msgstr "" #. type: Plain text #: doc/tutorial.md:528 msgid "" "Any `match` arm can have a guard clause (written `if EXPR`), called a " "*pattern guard*, which is an expression of type `bool` that determines, " "after the pattern is found to match, whether the arm is taken or not. The " "variables bound by the pattern are in scope in this guard expression. The " "first arm in the `angle` example shows an example of a pattern guard." msgstr "" #. type: Plain text #: doc/tutorial.md:533 msgid "" "You've already seen simple `let` bindings, but `let` is a little fancier " "than you've been led to believe. It, too, supports destructuring patterns. " "For example, you can write this to extract the fields from a tuple, " "introducing two variables at once: `a` and `b`." msgstr "" #. type: Plain text #: doc/tutorial.md:538 msgid "" "~~~~ # fn get_tuple_of_two_ints() -> (int, int) { (1, 1) } let (a, b) = " "get_tuple_of_two_ints(); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:542 msgid "" "Let bindings only work with _irrefutable_ patterns: that is, patterns that " "can never fail to match. This excludes `let` from matching literals and most " "`enum` variants." msgstr "" #. type: Plain text #: doc/tutorial.md:544 msgid "## Loops" msgstr "" #. type: Plain text #: doc/tutorial.md:549 msgid "" "`while` denotes a loop that iterates as long as its given condition (which " "must have type `bool`) evaluates to `true`. Inside a loop, the keyword " "`break` aborts the loop, and `loop` aborts the current iteration and " "continues with the next." msgstr "" #. type: Plain text #: doc/tutorial.md:556 #, no-wrap msgid "" "~~~~\n" "let mut cake_amount = 8;\n" "while cake_amount > 0 {\n" " cake_amount -= 1;\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:558 msgid "" "`loop` denotes an infinite loop, and is the preferred way of writing `while " "true`:" msgstr "" #. type: Plain text #: doc/tutorial.md:568 #, no-wrap msgid "" "~~~~\n" "# use std::int;\n" "let mut x = 5;\n" "loop {\n" " x += x - 3;\n" " if x % 5 == 0 { break; }\n" " println(int::to_str(x));\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:571 msgid "" "This code prints out a weird sequence of numbers and stops as soon as it " "finds one that can be divided by five." msgstr "" #. type: Plain text #: doc/tutorial.md:576 msgid "" "Rust also has a `for` construct. It's different from C's `for` and it works " "best when iterating over collections. See the section on [closures]" "(#closures) to find out how to use `for` and higher-order functions for " "enumerating elements of a collection." msgstr "" #. type: Plain text #: doc/tutorial.md:578 msgid "# Data structures" msgstr "" #. type: Plain text #: doc/tutorial.md:580 msgid "## Structs" msgstr "" #. type: Plain text #: doc/tutorial.md:585 msgid "" "Rust struct types must be declared before they are used using the `struct` " "syntax: `struct Name { field1: T1, field2: T2 [, ...] }`, where `T1`, " "`T2`, ... denote types. To construct a struct, use the same syntax, but " "leave off the `struct`: for example: `Point { x: 1.0, y: 2.0 }`." msgstr "" #. type: Plain text #: doc/tutorial.md:589 msgid "" "Structs are quite similar to C structs and are even laid out the same way in " "memory (so you can read from a Rust struct in C, and vice-versa). Use the " "dot operator to access struct fields, as in `mypoint.x`." msgstr "" #. type: Plain text #: doc/tutorial.md:596 #, no-wrap msgid "" "~~~~\n" "struct Point {\n" " x: float,\n" " y: float\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:600 msgid "" "Inherited mutability means that any field of a struct may be mutable, if the " "struct is in a mutable slot (or a field of a struct in a mutable slot, and " "so forth)." msgstr "" #. type: Plain text #: doc/tutorial.md:604 msgid "" "With a value (say, `mypoint`) of such a type in a mutable location, you can " "do `mypoint.y += 1.0`. But in an immutable location, such an assignment to a " "struct without inherited mutability would result in a type error." msgstr "" #. type: Plain text #: doc/tutorial.md:609 msgid "" "~~~~ {.xfail-test} # struct Point { x: float, y: float } let mut mypoint = " "Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };" msgstr "" #. type: Plain text #: doc/tutorial.md:613 msgid "" "mypoint.y += 1.0; // mypoint is mutable, and its fields as well origin.y += " "1.0; // ERROR: assigning to immutable field ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:616 msgid "" "`match` patterns destructure structs. The basic syntax is `Name { fieldname: " "pattern, ... }`:" msgstr "" #. type: Plain text #: doc/tutorial.md:625 #, no-wrap msgid "" "~~~~\n" "# struct Point { x: float, y: float }\n" "# let mypoint = Point { x: 0.0, y: 0.0 };\n" "match mypoint {\n" " Point { x: 0.0, y: yy } => { println(yy.to_str()); }\n" " Point { x: xx, y: yy } => { println(xx.to_str() + \" \" + yy.to_str()); }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:632 msgid "" "In general, the field names of a struct do not have to appear in the same " "order they appear in the type. When you are not interested in all the fields " "of a struct, a struct pattern may end with `, _` (as in `Name { field1, _ }" "`) to indicate that you're ignoring all other fields. Additionally, struct " "fields have a shorthand matching form that simply reuses the field name as " "the binding name." msgstr "" #. type: Plain text #: doc/tutorial.md:640 #, no-wrap msgid "" "~~~\n" "# struct Point { x: float, y: float }\n" "# let mypoint = Point { x: 0.0, y: 0.0 };\n" "match mypoint {\n" " Point { x, _ } => { println(x.to_str()) }\n" "}\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:642 msgid "## Enums" msgstr "" #. type: Plain text #: doc/tutorial.md:645 msgid "" "Enums are datatypes that have several alternate representations. For " "example, consider the type shown earlier:" msgstr "" #. type: Plain text #: doc/tutorial.md:653 #, no-wrap msgid "" "~~~~\n" "# struct Point { x: float, y: float }\n" "enum Shape {\n" " Circle(Point, float),\n" " Rectangle(Point, Point)\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:659 msgid "" "A value of this type is either a `Circle`, in which case it contains a " "`Point` struct and a float, or a `Rectangle`, in which case it contains two " "`Point` structs. The run-time representation of such a value includes an " "identifier of the actual form that it holds, much like the \"tagged union\" " "pattern in C, but with better static guarantees." msgstr "" #. type: Plain text #: doc/tutorial.md:665 msgid "" "The above declaration will define a type `Shape` that can refer to such " "shapes, and two functions, `Circle` and `Rectangle`, which can be used to " "construct values of the type (taking arguments of the specified types). So " "`Circle(Point { x: 0f, y: 0f }, 10f)` is the way to create a new circle." msgstr "" #. type: Plain text #: doc/tutorial.md:668 msgid "" "Enum variants need not have parameters. This `enum` declaration, for " "example, is equivalent to a C enum:" msgstr "" #. type: Plain text #: doc/tutorial.md:677 #, no-wrap msgid "" "~~~~\n" "enum Direction {\n" " North,\n" " East,\n" " South,\n" " West\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:680 msgid "" "This declaration defines `North`, `East`, `South`, and `West` as constants, " "all of which have type `Direction`." msgstr "" #. type: Plain text #: doc/tutorial.md:684 msgid "" "When an enum is C-like (that is, when none of the variants have parameters), " "it is possible to explicitly set the discriminator values to a constant " "value:" msgstr "" #. type: Plain text #: doc/tutorial.md:692 #, no-wrap msgid "" "~~~~\n" "enum Color {\n" " Red = 0xff0000,\n" " Green = 0x00ff00,\n" " Blue = 0x0000ff\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:697 msgid "" "If an explicit discriminator is not specified for a variant, the value " "defaults to the value of the previous variant plus one. If the first variant " "does not have a discriminator, it defaults to 0. For example, the value of " "`North` is 0, `East` is 1, `South` is 2, and `West` is 3." msgstr "" #. type: Plain text #: doc/tutorial.md:700 msgid "" "When an enum is C-like, you can apply the `as` cast operator to convert it " "to its discriminator value as an `int`." msgstr "" #. type: Plain text #: doc/tutorial.md:704 msgid "" "For enum types with multiple variants, destructuring is the only way to get " "at their contents. All variant constructors can be used as patterns, as in " "this definition of `area`:" msgstr "" #. type: Plain text #: doc/tutorial.md:716 #, no-wrap msgid "" "~~~~\n" "# use std::float;\n" "# struct Point {x: float, y: float}\n" "# enum Shape { Circle(Point, float), Rectangle(Point, Point) }\n" "fn area(sh: Shape) -> float {\n" " match sh {\n" " Circle(_, size) => float::consts::pi * size * size,\n" " Rectangle(Point { x, y }, Point { x: x2, y: y2 }) => (x2 - x) * (y2 - y)\n" " }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:721 msgid "" "You can write a lone `_` to ignore an individual field, and can ignore all " "fields of a variant like: `Circle(*)`. As in their introduction form, " "nullary enum patterns are written without parentheses." msgstr "" #. type: Plain text #: doc/tutorial.md:734 #, no-wrap msgid "" "~~~~\n" "# struct Point { x: float, y: float }\n" "# enum Direction { North, East, South, West }\n" "fn point_from_direction(dir: Direction) -> Point {\n" " match dir {\n" " North => Point { x: 0f, y: 1f },\n" " East => Point { x: 1f, y: 0f },\n" " South => Point { x: 0f, y: -1f },\n" " West => Point { x: -1f, y: 0f }\n" " }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:736 msgid "Enum variants may also be structs. For example:" msgstr "" #. type: Plain text #: doc/tutorial.md:754 #, no-wrap msgid "" "~~~~\n" "# use std::float;\n" "# struct Point { x: float, y: float }\n" "# fn square(x: float) -> float { x * x }\n" "enum Shape {\n" " Circle { center: Point, radius: float },\n" " Rectangle { top_left: Point, bottom_right: Point }\n" "}\n" "fn area(sh: Shape) -> float {\n" " match sh {\n" " Circle { radius: radius, _ } => float::consts::pi * square(radius),\n" " Rectangle { top_left: top_left, bottom_right: bottom_right } => {\n" " (bottom_right.x - top_left.x) * (bottom_right.y - top_left.y)\n" " }\n" " }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:756 msgid "## Tuples" msgstr "" #. type: Plain text #: doc/tutorial.md:761 msgid "" "Tuples in Rust behave exactly like structs, except that their fields do not " "have names. Thus, you cannot access their fields with dot notation. Tuples " "can have any arity except for 0 (though you may consider unit, `()`, as the " "empty tuple if you like)." msgstr "" #. type: Plain text #: doc/tutorial.md:768 #, no-wrap msgid "" "~~~~\n" "let mytup: (int, int, float) = (10, 20, 30.0);\n" "match mytup {\n" " (a, b, c) => info!(a + b + (c as int))\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:770 msgid "## Tuple structs" msgstr "" #. type: Plain text #: doc/tutorial.md:775 msgid "" "Rust also has _tuple structs_, which behave like both structs and tuples, " "except that, unlike tuples, tuple structs have names (so `Foo(1, 2)` has a " "different type from `Bar(1, 2)`), and tuple structs' _fields_ do not have " "names." msgstr "" #. type: Plain text #: doc/tutorial.md:784 #, no-wrap msgid "" "For example:\n" "~~~~\n" "struct MyTup(int, int, float);\n" "let mytup: MyTup = MyTup(10, 20, 30.0);\n" "match mytup {\n" " MyTup(a, b, c) => info!(a + b + (c as int))\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:786 msgid "" msgstr "" #. type: Plain text #: doc/tutorial.md:791 msgid "" "There is a special case for tuple structs with a single field, which are " "sometimes called \"newtypes\" (after Haskell's \"newtype\" feature). These " "are used to define new types in such a way that the new name is not just a " "synonym for an existing type but is rather its own distinct type." msgstr "" #. type: Plain text #: doc/tutorial.md:795 msgid "~~~~ struct GizmoId(int); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:798 msgid "" "For convenience, you can extract the contents of such a struct with the " "dereference (`*`) unary operator:" msgstr "" #. type: Plain text #: doc/tutorial.md:804 msgid "" "~~~~ # struct GizmoId(int); let my_gizmo_id: GizmoId = GizmoId(10); let " "id_int: int = *my_gizmo_id; ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:807 msgid "" "Types like this can be useful to differentiate between data that have the " "same type but must be used in different ways." msgstr "" #. type: Plain text #: doc/tutorial.md:812 msgid "~~~~ struct Inches(int); struct Centimeters(int); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:815 msgid "" "The above definitions allow for a simple way for programs to avoid confusing " "numbers that correspond to different units." msgstr "" #. type: Plain text #: doc/tutorial.md:817 msgid "# Functions" msgstr "" #. type: Plain text #: doc/tutorial.md:825 msgid "" "We've already seen several function definitions. Like all other static " "declarations, such as `type`, functions can be declared both at the top " "level and inside other functions (or in modules, which we'll come back to " "[later](#modules-and-crates)). The `fn` keyword introduces a function. A " "function has an argument list, which is a parenthesized list of `expr: type` " "pairs separated by commas. An arrow `->` separates the argument list and the " "function's return type." msgstr "" #. type: Plain text #: doc/tutorial.md:831 #, no-wrap msgid "" "~~~~\n" "fn line(a: int, b: int, x: int) -> int {\n" " return a * x + b;\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:836 msgid "" "The `return` keyword immediately returns from the body of a function. It is " "optionally followed by an expression to return. A function can also return a " "value by having its top-level block produce an expression." msgstr "" #. type: Plain text #: doc/tutorial.md:842 #, no-wrap msgid "" "~~~~\n" "fn line(a: int, b: int, x: int) -> int {\n" " a * x + b\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:849 msgid "" "It's better Rust style to write a return value this way instead of writing " "an explicit `return`. The utility of `return` comes in when returning early " "from a function. Functions that do not return a value are said to return " "nil, `()`, and both the return type and the return value may be omitted from " "the definition. The following two functions are equivalent." msgstr "" #. type: Plain text #: doc/tutorial.md:852 msgid "~~~~ fn do_nothing_the_hard_way() -> () { return (); }" msgstr "" #. type: Plain text #: doc/tutorial.md:855 msgid "fn do_nothing_the_easy_way() { } ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:857 msgid "" "Ending the function with a semicolon like so is equivalent to returning `()`." msgstr "" #. type: Plain text #: doc/tutorial.md:861 msgid "" "~~~~ fn line(a: int, b: int, x: int) -> int { a * x + b } fn oops(a: int, b: " "int, x: int) -> () { a * x + b; }" msgstr "" #. type: Plain text #: doc/tutorial.md:865 msgid "assert!(8 == line(5, 3, 1)); assert!(() == oops(5, 3, 1)); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:869 msgid "" "As with `match` expressions and `let` bindings, function arguments support " "pattern destructuring. Like `let`, argument patterns must be irrefutable, as " "in this example that unpacks the first value from a tuple and returns it." msgstr "" #. type: Plain text #: doc/tutorial.md:873 msgid "~~~ fn first((value, _): (int, float)) -> int { value } ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:875 doc/tutorial-ffi.md:143 msgid "# Destructors" msgstr "" #. type: Plain text #: doc/tutorial.md:879 msgid "" "A *destructor* is a function responsible for cleaning up the resources used " "by an object when it is no longer accessible. Destructors can be defined to " "handle the release of resources like files, sockets and heap memory." msgstr "" #. type: Plain text #: doc/tutorial.md:883 msgid "" "Objects are never accessible after their destructor has been called, so " "there are no dynamic failures from accessing freed resources. When a task " "fails, the destructors of all objects in the task are called." msgstr "" #. type: Plain text #: doc/tutorial.md:885 msgid "" "The `~` sigil represents a unique handle for a memory allocation on the heap:" msgstr "" #. type: Plain text #: doc/tutorial.md:893 #, no-wrap msgid "" "~~~~\n" "{\n" " // an integer allocated on the heap\n" " let y = ~10;\n" "}\n" "// the destructor frees the heap memory as soon as `y` goes out of scope\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:897 msgid "" "Rust includes syntax for heap memory allocation in the language since it's " "commonly used, but the same semantics can be implemented by a type with a " "custom destructor." msgstr "" #. type: Plain text #: doc/tutorial.md:899 msgid "# Ownership" msgstr "" #. type: Plain text #: doc/tutorial.md:904 msgid "" "Rust formalizes the concept of object ownership to delegate management of an " "object's lifetime to either a variable or a task-local garbage collector. An " "object's owner is responsible for managing the lifetime of the object by " "calling the destructor, and the owner determines whether the object is " "mutable." msgstr "" #. type: Plain text #: doc/tutorial.md:910 msgid "" "Ownership is recursive, so mutability is inherited recursively and a " "destructor destroys the contained tree of owned objects. Variables are top-" "level owners and destroy the contained object when they go out of scope. A " "box managed by the garbage collector starts a new ownership tree, and the " "destructor is called when it is collected." msgstr "" #. type: Plain text #: doc/tutorial.md:914 msgid "" "~~~~ // the struct owns the objects contained in the `x` and `y` fields " "struct Foo { x: int, y: ~int }" msgstr "" #. type: Plain text #: doc/tutorial.md:921 #, no-wrap msgid "" "{\n" " // `a` is the owner of the struct, and thus the owner of the struct's fields\n" " let a = Foo { x: 5, y: ~10 };\n" "}\n" "// when `a` goes out of scope, the destructor for the `~int` in the struct's\n" "// field is called\n" msgstr "" #. type: Plain text #: doc/tutorial.md:926 msgid "" "// `b` is mutable, and the mutability is inherited by the objects it owns " "let mut b = Foo { x: 5, y: ~10 }; b.x = 10; ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:932 msgid "" "If an object doesn't contain garbage-collected boxes, it consists of a " "single ownership tree and is given the `Owned` trait which allows it to be " "sent between tasks. Custom destructors can only be implemented directly on " "types that are `Owned`, but garbage-collected boxes can still *contain* " "types with custom destructors." msgstr "" #. type: Plain text #: doc/tutorial.md:934 msgid "# Boxes" msgstr "" #. type: Plain text #: doc/tutorial.md:941 msgid "" "Many modern languages represent values as pointers to heap memory by " "default. In contrast, Rust, like C and C++, represents such types directly. " "Another way to say this is that aggregate data in Rust are *unboxed*. This " "means that if you `let x = Point { x: 1f, y: 1f };`, you are creating a " "struct on the stack. If you then copy it into a data structure, you copy the " "entire struct, not just a pointer." msgstr "" #. type: Plain text #: doc/tutorial.md:946 msgid "" "For small structs like `Point`, this is usually more efficient than " "allocating memory and indirecting through a pointer. But for big structs, or " "mutable state, it can be useful to have a single copy on the stack or on the " "heap, and refer to that through a pointer." msgstr "" #. type: Plain text #: doc/tutorial.md:948 msgid "## Owned boxes" msgstr "" #. type: Plain text #: doc/tutorial.md:951 msgid "" "An owned box (`~`) is a uniquely owned allocation on the heap. It inherits " "the mutability and lifetime of the owner as it would if there was no box:" msgstr "" #. type: Plain text #: doc/tutorial.md:956 msgid "~~~~ let x = 5; // immutable let mut y = 5; // mutable y += 2;" msgstr "" #. type: Plain text #: doc/tutorial.md:961 msgid "" "let x = ~5; // immutable let mut y = ~5; // mutable *y += 2; // the * " "operator is needed to access the contained value ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:966 msgid "" "The purpose of an owned box is to add a layer of indirection in order to " "create recursive data structures or cheaply pass around an object larger " "than a pointer. Since an owned box has a unique owner, it can only be used " "to represent a tree data structure." msgstr "" #. type: Plain text #: doc/tutorial.md:969 msgid "" "The following struct won't compile, because the lack of indirection would " "mean it has an infinite size:" msgstr "" #. type: Plain text #: doc/tutorial.md:975 #, no-wrap msgid "" "~~~~ {.xfail-test}\n" "struct Foo {\n" " child: Option\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:979 msgid "" "> ***Note:*** The `Option` type is an enum that represents an *optional* " "value. > It's comparable to a nullable pointer in many other languages, but " "stores the > contained value unboxed." msgstr "" #. type: Plain text #: doc/tutorial.md:983 msgid "" "Adding indirection with an owned pointer allocates the child outside of the " "struct on the heap, which makes it a finite size and won't result in a " "compile-time error:" msgstr "" #. type: Plain text #: doc/tutorial.md:989 #, no-wrap msgid "" "~~~~\n" "struct Foo {\n" " child: Option<~Foo>\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:991 msgid "## Managed boxes" msgstr "" #. type: Plain text #: doc/tutorial.md:999 msgid "" "A managed box (`@`) is a heap allocation with the lifetime managed by a task-" "local garbage collector. It will be destroyed at some point after there are " "no references left to the box, no later than the end of the task. Managed " "boxes lack an owner, so they start a new ownership tree and don't inherit " "mutability. They do own the contained object, and mutability is defined by " "the type of the shared box (`@` or `@mut`). An object containing a managed " "box is not `Owned`, and can't be sent between tasks." msgstr "" #. type: Plain text #: doc/tutorial.md:1002 msgid "~~~~ let a = @5; // immutable" msgstr "" #. type: Plain text #: doc/tutorial.md:1005 msgid "let mut b = @5; // mutable variable, immutable box b = @10;" msgstr "" #. type: Plain text #: doc/tutorial.md:1008 msgid "let c = @mut 5; // immutable variable, mutable box *c = 10;" msgstr "" #. type: Plain text #: doc/tutorial.md:1013 msgid "" "let mut d = @mut 5; // mutable variable, mutable box *d += 5; d = @mut 15; " "~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1018 msgid "" "A mutable variable and an immutable variable can refer to the same box, " "given that their types are compatible. Mutability of a box is a property of " "its type, however, so for example a mutable handle to an immutable box " "cannot be assigned a reference to a mutable box." msgstr "" #. type: Plain text #: doc/tutorial.md:1022 #, no-wrap msgid "" "~~~~\n" "let a = @1; // immutable box\n" "let b = @mut 2; // mutable box\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1025 #, no-wrap msgid "" "let mut c : @int; // declare a variable with type managed immutable int\n" "let mut d : @mut int; // and one of type managed mutable int\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1029 #, no-wrap msgid "" "c = a; // box type is the same, okay\n" "d = b; // box type is the same, okay\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1034 #, no-wrap msgid "" "~~~~ {.xfail-test}\n" "// but b cannot be assigned to c, or a to d\n" "c = b; // error\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1036 msgid "# Move semantics" msgstr "" #. type: Plain text #: doc/tutorial.md:1042 msgid "" "Rust uses a shallow copy for parameter passing, assignment and returning " "values from functions. A shallow copy is considered a move of ownership if " "the ownership tree of the copied value includes an owned box or a type with " "a custom destructor. After a value has been moved, it can no longer be used " "from the source location and will not be destroyed there." msgstr "" #. type: Plain text #: doc/tutorial.md:1048 msgid "" "~~~~ let x = ~5; let y = x.clone(); // y is a newly allocated box let z = " "x; // no new memory allocated, x can no longer be used ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1051 msgid "" "Since in owned boxes mutability is a property of the owner, not the box, " "mutable boxes may become immutable when they are moved, and vice-versa." msgstr "" #. type: Plain text #: doc/tutorial.md:1058 msgid "" "~~~~ let r = ~13; let mut s = r; // box becomes mutable *s += 1; let t = " "s; // box becomes immutable ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1060 msgid "# Borrowed pointers" msgstr "" #. type: Plain text #: doc/tutorial.md:1066 msgid "" "Rust's borrowed pointers are a general purpose reference type. In contrast " "with owned boxes, where the holder of an owned box is the owner of the " "pointed-to memory, borrowed pointers never imply ownership. A pointer can be " "borrowed to any object, and the compiler verifies that it cannot outlive the " "lifetime of the object." msgstr "" #. type: Plain text #: doc/tutorial.md:1068 msgid "As an example, consider a simple struct type, `Point`:" msgstr "" #. type: Plain text #: doc/tutorial.md:1075 #, no-wrap msgid "" "~~~\n" "struct Point {\n" " x: float,\n" " y: float\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1079 msgid "" "We can use this simple definition to allocate points in many different ways. " "For example, in this code, each of these three local variables contains a " "point, but allocated in a different location:" msgstr "" #. type: Plain text #: doc/tutorial.md:1086 #, no-wrap msgid "" "~~~\n" "# struct Point { x: float, y: float }\n" "let on_the_stack : Point = Point { x: 3.0, y: 4.0 };\n" "let managed_box : @Point = @Point { x: 5.0, y: 1.0 };\n" "let owned_box : ~Point = ~Point { x: 7.0, y: 9.0 };\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1098 msgid "" "Suppose we want to write a procedure that computes the distance between any " "two points, no matter where they are stored. For example, we might like to " "compute the distance between `on_the_stack` and `managed_box`, or between " "`managed_box` and `owned_box`. One option is to define a function that takes " "two arguments of type pointthat is, it takes the points by value. But this " "will cause the points to be copied when we call the function. For points, " "this is probably not so bad, but often copies are expensive or, worse, if " "there are mutable fields, they can change the semantics of your program. So " "wed like to define a function that takes the points by pointer. We can use " "borrowed pointers to do this:" msgstr "" #. type: Plain text #: doc/tutorial.md:1108 #, no-wrap msgid "" "~~~\n" "# struct Point { x: float, y: float }\n" "# fn sqrt(f: float) -> float { 0f }\n" "fn compute_distance(p1: &Point, p2: &Point) -> float {\n" " let x_d = p1.x - p2.x;\n" " let y_d = p1.y - p2.y;\n" " sqrt(x_d * x_d + y_d * y_d)\n" "}\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1110 doc/tutorial-borrowed-ptr.md:72 msgid "Now we can call `compute_distance()` in various ways:" msgstr "" #. type: Plain text #: doc/tutorial.md:1120 #, no-wrap msgid "" "~~~\n" "# struct Point{ x: float, y: float };\n" "# let on_the_stack : Point = Point { x: 3.0, y: 4.0 };\n" "# let managed_box : @Point = @Point { x: 5.0, y: 1.0 };\n" "# let owned_box : ~Point = ~Point { x: 7.0, y: 9.0 };\n" "# fn compute_distance(p1: &Point, p2: &Point) -> float { 0f }\n" "compute_distance(&on_the_stack, managed_box);\n" "compute_distance(managed_box, owned_box);\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1127 msgid "" "Here the `&` operator is used to take the address of the variable " "`on_the_stack`; this is because `on_the_stack` has the type `Point` (that " "is, a struct value) and we have to take its address to get a value. We also " "call this _borrowing_ the local variable `on_the_stack`, because we are " "creating an alias: that is, another route to the same data." msgstr "" #. type: Plain text #: doc/tutorial.md:1133 msgid "" "In the case of the boxes `managed_box` and `owned_box`, however, no explicit " "action is necessary. The compiler will automatically convert a box like " "`@point` or `~point` to a borrowed pointer like `&point`. This is another " "form of borrowing; in this case, the contents of the managed/owned box are " "being lent out." msgstr "" #. type: Plain text #: doc/tutorial.md:1142 msgid "" "Whenever a value is borrowed, there are some limitations on what you can do " "with the original. For example, if the contents of a variable have been lent " "out, you cannot send that variable to another task, nor will you be " "permitted to take actions that might cause the borrowed value to be freed or " "to change its type. This rule should make intuitive sense: you must wait for " "a borrowed value to be returned (that is, for the borrowed pointer to go out " "of scope) before you can make full use of it again." msgstr "" #. type: Plain text #: doc/tutorial.md:1145 msgid "" "For a more in-depth explanation of borrowed pointers, read the [borrowed " "pointer tutorial][borrowtut]." msgstr "" #. type: Plain text #: doc/tutorial.md:1147 msgid "[borrowtut]: tutorial-borrowed-ptr.html" msgstr "" #. type: Plain text #: doc/tutorial.md:1149 msgid "## Freezing" msgstr "" #. type: Plain text #: doc/tutorial.md:1152 msgid "" "Borrowing an immutable pointer to an object freezes it and prevents " "mutation. `Owned` objects have freezing enforced statically at compile-time." msgstr "" #. type: Plain text #: doc/tutorial.md:1160 #, no-wrap msgid "" "~~~~\n" "let mut x = 5;\n" "{\n" " let y = &x; // x is now frozen, it cannot be modified\n" "}\n" "// x is now unfrozen again\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1164 msgid "" "Mutable managed boxes handle freezing dynamically when any of their contents " "are borrowed, and the task will fail if an attempt to modify them is made " "while they are frozen:" msgstr "" #. type: Plain text #: doc/tutorial.md:1174 #, no-wrap msgid "" "~~~~\n" "let x = @mut 5;\n" "let y = x;\n" "{\n" " let z = &*y; // the managed box is now frozen\n" " // modifying it through x or y will cause a task failure\n" "}\n" "// the box is now unfrozen again\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1176 msgid "# Dereferencing pointers" msgstr "" #. type: Plain text #: doc/tutorial.md:1179 msgid "" "Rust uses the unary star operator (`*`) to access the contents of a box or " "pointer, similarly to C." msgstr "" #. type: Plain text #: doc/tutorial.md:1184 msgid "~~~ let managed = @10; let owned = ~20; let borrowed = &30;" msgstr "" #. type: Plain text #: doc/tutorial.md:1187 msgid "let sum = *managed + *owned + *borrowed; ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1191 msgid "" "Dereferenced mutable pointers may appear on the left hand side of " "assignments. Such an assignment modifies the value that the pointer points " "to." msgstr "" #. type: Plain text #: doc/tutorial.md:1195 msgid "~~~ let managed = @mut 10; let mut owned = ~20;" msgstr "" #. type: Plain text #: doc/tutorial.md:1198 msgid "let mut value = 30; let borrowed = &mut value;" msgstr "" #. type: Plain text #: doc/tutorial.md:1203 #, no-wrap msgid "" "*managed = *owned + 10;\n" "*owned = *borrowed + 100;\n" "*borrowed = *managed + 1000;\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1207 msgid "" "Pointers have high operator precedence, but lower precedence than the dot " "operator used for field and method access. This precedence order can " "sometimes make code awkward and parenthesis-filled." msgstr "" #. type: Plain text #: doc/tutorial.md:1217 msgid "" "~~~ # struct Point { x: float, y: float } # enum Shape { Rectangle(Point, " "Point) } # impl Shape { fn area(&self) -> int { 0 } } let start = @Point " "{ x: 10f, y: 20f }; let end = ~Point { x: (*start).x + 100f, y: (*start).y + " "100f }; let rect = &Rectangle(*start, *end); let area = (*rect).area(); ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1221 msgid "" "To combat this ugliness the dot operator applies _automatic pointer " "dereferencing_ to the receiver (the value on the left-hand side of the dot), " "so in most cases, explicitly dereferencing the receiver is not necessary." msgstr "" #. type: Plain text #: doc/tutorial.md:1231 msgid "" "~~~ # struct Point { x: float, y: float } # enum Shape { Rectangle(Point, " "Point) } # impl Shape { fn area(&self) -> int { 0 } } let start = @Point " "{ x: 10f, y: 20f }; let end = ~Point { x: start.x + 100f, y: start.y + " "100f }; let rect = &Rectangle(*start, *end); let area = rect.area(); ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1235 msgid "" "You can write an expression that dereferences any number of pointers " "automatically. For example, if you feel inclined, you could write something " "silly like" msgstr "" #. type: Plain text #: doc/tutorial.md:1241 msgid "" "~~~ # struct Point { x: float, y: float } let point = &@~Point { x: 10f, y: " "20f }; println(fmt!(\"%f\", point.x)); ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1243 msgid "The indexing operator (`[]`) also auto-dereferences." msgstr "" #. type: Plain text #: doc/tutorial.md:1245 msgid "# Vectors and strings" msgstr "" #. type: Plain text #: doc/tutorial.md:1250 msgid "" "A vector is a contiguous section of memory containing zero or more values of " "the same type. Like other types in Rust, vectors can be stored on the stack, " "the local heap, or the exchange heap. Borrowed pointers to vectors are also " "called 'slices'." msgstr "" #. type: Plain text #: doc/tutorial.md:1260 #, no-wrap msgid "" "~~~\n" "# enum Crayon {\n" "# Almond, AntiqueBrass, Apricot,\n" "# Aquamarine, Asparagus, AtomicTangerine,\n" "# BananaMania, Beaver, Bittersweet,\n" "# Black, BlizzardBlue, Blue\n" "# }\n" "// A fixed-size stack vector\n" "let stack_crayons: [Crayon, ..3] = [Almond, AntiqueBrass, Apricot];\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1263 msgid "" "// A borrowed pointer to stack-allocated vector let stack_crayons: &[Crayon] " "= &[Aquamarine, Asparagus, AtomicTangerine];" msgstr "" #. type: Plain text #: doc/tutorial.md:1266 msgid "" "// A local heap (managed) vector of crayons let local_crayons: @[Crayon] = " "@[BananaMania, Beaver, Bittersweet];" msgstr "" #. type: Plain text #: doc/tutorial.md:1270 msgid "" "// An exchange heap (owned) vector of crayons let exchange_crayons: " "~[Crayon] = ~[Black, BlizzardBlue, Blue]; ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1272 msgid "The `+` operator means concatenation when applied to vector types." msgstr "" #. type: Plain text #: doc/tutorial.md:1277 #, no-wrap msgid "" "~~~~\n" "# enum Crayon { Almond, AntiqueBrass, Apricot,\n" "# Aquamarine, Asparagus, AtomicTangerine,\n" "# BananaMania, Beaver, Bittersweet };\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1280 msgid "" "let my_crayons = ~[Almond, AntiqueBrass, Apricot]; let your_crayons = " "~[BananaMania, Beaver, Bittersweet];" msgstr "" #. type: Plain text #: doc/tutorial.md:1283 msgid "" "// Add two vectors to create a new one let our_crayons = my_crayons + " "your_crayons;" msgstr "" #. type: Plain text #: doc/tutorial.md:1288 msgid "" "// .push_all() will append to a vector, provided it lives in a mutable slot " "let mut my_crayons = my_crayons; my_crayons.push_all(your_crayons); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1293 msgid "" "> ***Note:*** The above examples of vector addition use owned > vectors. " "Some operations on slices and stack vectors are > not yet well-supported. " "Owned vectors are often the most > usable." msgstr "" #. type: Plain text #: doc/tutorial.md:1295 msgid "Square brackets denote indexing into a vector:" msgstr "" #. type: Plain text #: doc/tutorial.md:1307 #, no-wrap msgid "" "~~~~\n" "# enum Crayon { Almond, AntiqueBrass, Apricot,\n" "# Aquamarine, Asparagus, AtomicTangerine,\n" "# BananaMania, Beaver, Bittersweet };\n" "# fn draw_scene(c: Crayon) { }\n" "let crayons: [Crayon, ..3] = [BananaMania, Beaver, Bittersweet];\n" "match crayons[0] {\n" " Bittersweet => draw_scene(crayons[0]),\n" " _ => ()\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1309 msgid "A vector can be destructured using pattern matching:" msgstr "" #. type: Plain text #: doc/tutorial.md:1319 #, no-wrap msgid "" "~~~~\n" "let numbers: [int, ..3] = [1, 2, 3];\n" "let score = match numbers {\n" " [] => 0,\n" " [a] => a * 10,\n" " [a, b] => a * 6 + b * 4,\n" " [a, b, c, ..rest] => a * 5 + b * 3 + c * 2 + rest.len() as int\n" "};\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1323 msgid "" "The elements of a vector _inherit the mutability of the vector_, and as " "such, individual elements may not be reassigned when the vector lives in an " "immutable slot." msgstr "" #. type: Plain text #: doc/tutorial.md:1329 #, no-wrap msgid "" "~~~ {.xfail-test}\n" "# enum Crayon { Almond, AntiqueBrass, Apricot,\n" "# Aquamarine, Asparagus, AtomicTangerine,\n" "# BananaMania, Beaver, Bittersweet };\n" "let crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1332 msgid "crayons[0] = Apricot; // ERROR: Can't assign to immutable vector ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1334 msgid "Moving it into a mutable slot makes the elements assignable." msgstr "" #. type: Plain text #: doc/tutorial.md:1340 #, no-wrap msgid "" "~~~\n" "# enum Crayon { Almond, AntiqueBrass, Apricot,\n" "# Aquamarine, Asparagus, AtomicTangerine,\n" "# BananaMania, Beaver, Bittersweet };\n" "let crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1343 msgid "" "// Put the vector into a mutable slot let mut mutable_crayons = crayons;" msgstr "" #. type: Plain text #: doc/tutorial.md:1347 msgid "// Now it's mutable to the bone mutable_crayons[0] = Apricot; ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1350 msgid "" "This is a simple example of Rust's _dual-mode data structures_, also " "referred to as _freezing and thawing_." msgstr "" #. type: Plain text #: doc/tutorial.md:1358 msgid "" "Strings are implemented with vectors of `u8`, though they have a distinct " "type. They support most of the same allocation options as vectors, though " "the string literal without a storage sigil (for example, `\"foo\"`) is " "treated differently than a comparable vector (`[foo]`). Whereas plain " "vectors are stack-allocated fixed-length vectors, plain strings are borrowed " "pointers to read-only (static) memory. All strings are immutable." msgstr "" #. type: Plain text #: doc/tutorial.md:1362 msgid "" "~~~ // A plain string is a slice to read-only (static) memory let " "stack_crayons: &str = \"Almond, AntiqueBrass, Apricot\";" msgstr "" #. type: Plain text #: doc/tutorial.md:1365 msgid "" "// The same thing, but with the `&` let stack_crayons: &str = &\"Aquamarine, " "Asparagus, AtomicTangerine\";" msgstr "" #. type: Plain text #: doc/tutorial.md:1368 msgid "" "// A local heap (managed) string let local_crayons: @str = @\"BananaMania, " "Beaver, Bittersweet\";" msgstr "" #. type: Plain text #: doc/tutorial.md:1372 msgid "" "// An exchange heap (owned) string let exchange_crayons: ~str = ~\"Black, " "BlizzardBlue, Blue\"; ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1376 msgid "" "Both vectors and strings support a number of useful [methods](#functions-and-" "methods), defined in [`std::vec`] and [`std::str`]. Here are some examples." msgstr "" #. type: Plain text #: doc/tutorial.md:1379 msgid "[`std::vec`]: std/vec.html [`std::str`]: std/str.html" msgstr "" #. type: Plain text #: doc/tutorial.md:1390 #, no-wrap msgid "" "~~~\n" "# enum Crayon {\n" "# Almond, AntiqueBrass, Apricot,\n" "# Aquamarine, Asparagus, AtomicTangerine,\n" "# BananaMania, Beaver, Bittersweet\n" "# }\n" "# fn unwrap_crayon(c: Crayon) -> int { 0 }\n" "# fn eat_crayon_wax(i: int) { }\n" "# fn store_crayon_in_nasal_cavity(i: uint, c: Crayon) { }\n" "# fn crayon_to_str(c: Crayon) -> &str { \"\" }\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1392 msgid "let crayons = [Almond, AntiqueBrass, Apricot];" msgstr "" #. type: Plain text #: doc/tutorial.md:1396 msgid "" "// Check the length of the vector assert!(crayons.len() == 3); assert!(!" "crayons.is_empty());" msgstr "" #. type: Plain text #: doc/tutorial.md:1403 #, no-wrap msgid "" "// Iterate over a vector, obtaining a pointer to each element\n" "// (`for` is explained in the next section)\n" "for crayons.iter().advance |crayon| {\n" " let delicious_crayon_wax = unwrap_crayon(*crayon);\n" " eat_crayon_wax(delicious_crayon_wax);\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1407 msgid "" "// Map vector elements let crayon_names = crayons.map(|v| " "crayon_to_str(*v)); let favorite_crayon_name = crayon_names[0];" msgstr "" #. type: Plain text #: doc/tutorial.md:1410 msgid "" "// Remove whitespace from before and after the string let " "new_favorite_crayon_name = favorite_crayon_name.trim();" msgstr "" #. type: Plain text #: doc/tutorial.md:1416 #, no-wrap msgid "" "if favorite_crayon_name.len() > 5 {\n" " // Create a substring\n" " println(favorite_crayon_name.slice_chars(0, 5));\n" "}\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1418 msgid "# Closures" msgstr "" #. type: Plain text #: doc/tutorial.md:1423 msgid "" "Named functions, like those we've seen so far, may not refer to local " "variables declared outside the function: they do not close over their " "environment (sometimes referred to as \"capturing\" variables in their " "environment). For example, you couldn't write the following:" msgstr "" #. type: Plain text #: doc/tutorial.md:1426 msgid "~~~~ {.ignore} let foo = 10;" msgstr "" #. type: Plain text #: doc/tutorial.md:1431 #, no-wrap msgid "" "fn bar() -> int {\n" " return foo; // `bar` cannot refer to `foo`\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1434 msgid "" "Rust also supports _closures_, functions that can access variables in the " "enclosing scope." msgstr "" #. type: Plain text #: doc/tutorial.md:1437 msgid "~~~~ fn call_closure_with_ten(b: &fn(int)) { b(10); }" msgstr "" #. type: Plain text #: doc/tutorial.md:1440 msgid "" "let captured_var = 20; let closure = |arg| println(fmt!(\"captured_var=%d, " "arg=%d\", captured_var, arg));" msgstr "" #. type: Plain text #: doc/tutorial.md:1443 msgid "call_closure_with_ten(closure); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1449 msgid "" "Closures begin with the argument list between vertical bars and are followed " "by a single expression. Remember that a block, `{ ; ; ... }`, " "is considered a single expression: it evaluates to the result of the last " "expression it contains if that expression is not followed by a semicolon, " "otherwise the block evaluates to `()`." msgstr "" #. type: Plain text #: doc/tutorial.md:1454 msgid "" "The types of the arguments are generally omitted, as is the return type, " "because the compiler can almost always infer them. In the rare case where " "the compiler needs assistance, though, the arguments and return types may be " "annotated." msgstr "" #. type: Plain text #: doc/tutorial.md:1458 msgid "~~~~ let square = |x: int| -> uint { x * x as uint }; ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1462 msgid "" "There are several forms of closure, each with its own role. The most common, " "called a _stack closure_, has type `&fn` and can directly access local " "variables in the enclosing scope." msgstr "" #. type: Plain text #: doc/tutorial.md:1467 msgid "~~~~ let mut max = 0; [1, 2, 3].map(|x| if *x > max { max = *x }); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1476 msgid "" "Stack closures are very efficient because their environment is allocated on " "the call stack and refers by pointer to captured locals. To ensure that " "stack closures never outlive the local variables to which they refer, stack " "closures are not first-class. That is, they can only be used in argument " "position; they cannot be stored in data structures or returned from " "functions. Despite these limitations, stack closures are used pervasively in " "Rust code." msgstr "" #. type: Plain text #: doc/tutorial.md:1478 msgid "## Managed closures" msgstr "" #. type: Plain text #: doc/tutorial.md:1484 msgid "" "When you need to store a closure in a data structure, a stack closure will " "not do, since the compiler will refuse to let you store it. For this " "purpose, Rust provides a type of closure that has an arbitrary lifetime, " "written `@fn` (boxed closure, analogous to the `@` pointer type described " "earlier). This type of closure *is* first-class." msgstr "" #. type: Plain text #: doc/tutorial.md:1489 msgid "" "A managed closure does not directly access its environment, but merely " "copies out the values that it closes over into a private data structure. " "This means that it can not assign to these variables, and cannot observe " "updates to them." msgstr "" #. type: Plain text #: doc/tutorial.md:1492 msgid "" "This code creates a closure that adds a given string to its argument, " "returns it from a function, and then calls it:" msgstr "" #. type: Plain text #: doc/tutorial.md:1498 #, no-wrap msgid "" "~~~~\n" "fn mk_appender(suffix: ~str) -> @fn(~str) -> ~str {\n" " // The compiler knows that we intend this closure to be of type @fn\n" " return |s| s + suffix;\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1504 #, no-wrap msgid "" "fn main() {\n" " let shout = mk_appender(~\"!\");\n" " println(shout(~\"hey ho, let's go\"));\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1506 msgid "## Owned closures" msgstr "" #. type: Plain text #: doc/tutorial.md:1513 msgid "" "Owned closures, written `~fn` in analogy to the `~` pointer type, hold on to " "things that can safely be sent between processes. They copy the values they " "close over, much like managed closures, but they also own them: that is, no " "other code can access them. Owned closures are used in concurrent code, " "particularly for spawning [tasks][tasks]." msgstr "" #. type: Plain text #: doc/tutorial.md:1515 msgid "[tasks]: tutorial-tasks.html" msgstr "" #. type: Plain text #: doc/tutorial.md:1517 msgid "## Closure compatibility" msgstr "" #. type: Plain text #: doc/tutorial.md:1524 msgid "" "Rust closures have a convenient subtyping property: you can pass any kind of " "closure (as long as the arguments and return types match) to functions that " "expect a `&fn()`. Thus, when writing a higher-order function that only calls " "its function argument, and does nothing else with it, you should almost " "always declare the type of that argument as `&fn()`. That way, callers may " "pass any kind of closure." msgstr "" #. type: Plain text #: doc/tutorial.md:1532 msgid "" "~~~~ fn call_twice(f: &fn()) { f(); f(); } let closure = || { \"I'm a " "closure, and it doesn't matter what type I am\"; }; fn function() { \"I'm a " "normal function\"; } call_twice(closure); call_twice(function); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1536 msgid "" "> ***Note:*** Both the syntax and the semantics will be changing > in small " "ways. At the moment they can be unsound in some > scenarios, particularly " "with non-copyable types." msgstr "" #. type: Plain text #: doc/tutorial.md:1538 msgid "## Do syntax" msgstr "" #. type: Plain text #: doc/tutorial.md:1541 msgid "" "The `do` expression provides a way to treat higher-order functions " "(functions that take closures as arguments) as control structures." msgstr "" #. type: Plain text #: doc/tutorial.md:1544 msgid "" "Consider this function that iterates over a vector of integers, passing in a " "pointer to each integer in the vector:" msgstr "" #. type: Plain text #: doc/tutorial.md:1554 #, no-wrap msgid "" "~~~~\n" "fn each(v: &[int], op: &fn(v: &int)) {\n" " let mut n = 0;\n" " while n < v.len() {\n" " op(&v[n]);\n" " n += 1;\n" " }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1558 msgid "" "As a caller, if we use a closure to provide the final operator argument, we " "can write it in a way that has a pleasant, block-like structure." msgstr "" #. type: Plain text #: doc/tutorial.md:1566 #, no-wrap msgid "" "~~~~\n" "# fn each(v: &[int], op: &fn(v: &int)) { }\n" "# fn do_some_work(i: &int) { }\n" "each([1, 2, 3], |n| {\n" " do_some_work(n);\n" "});\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1569 msgid "" "This is such a useful pattern that Rust has a special form of function call " "that can be written more like a built-in control structure:" msgstr "" #. type: Plain text #: doc/tutorial.md:1577 #, no-wrap msgid "" "~~~~\n" "# fn each(v: &[int], op: &fn(v: &int)) { }\n" "# fn do_some_work(i: &int) { }\n" "do each([1, 2, 3]) |n| {\n" " do_some_work(n);\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1582 msgid "" "The call is prefixed with the keyword `do` and, instead of writing the final " "closure inside the argument list, it appears outside of the parentheses, " "where it looks more like a typical block of code." msgstr "" #. type: Plain text #: doc/tutorial.md:1587 msgid "" "`do` is a convenient way to create tasks with the `task::spawn` function. " "`spawn` has the signature `spawn(fn: ~fn())`. In other words, it is a " "function that takes an owned closure that takes no arguments." msgstr "" #. type: Plain text #: doc/tutorial.md:1590 msgid "~~~~ use std::task::spawn;" msgstr "" #. type: Plain text #: doc/tutorial.md:1595 #, no-wrap msgid "" "do spawn() || {\n" " debug!(\"I'm a task, whatever\");\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1599 msgid "" "Look at all those bars and parentheses -- that's two empty argument lists " "back to back. Since that is so unsightly, empty argument lists may be " "omitted from `do` expressions." msgstr "" #. type: Plain text #: doc/tutorial.md:1606 #, no-wrap msgid "" "~~~~\n" "# use std::task::spawn;\n" "do spawn {\n" " debug!(\"Kablam!\");\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1609 msgid "" "If you want to see the output of `debug!` statements, you will need to turn " "on `debug!` logging. To enable `debug!` logging, set the RUST_LOG " "environment variable to the name of your crate, which, for a file named `foo." "rs`, will be `foo` (e.g., with bash, `export RUST_LOG=foo`)." msgstr "" #. type: Plain text #: doc/tutorial.md:1611 msgid "# Methods" msgstr "" #. type: Plain text #: doc/tutorial.md:1617 msgid "" "Methods are like functions except that they always begin with a special " "argument, called `self`, which has the type of the method's receiver. The " "`self` argument is like `this` in C++ and many other languages. Methods are " "called with dot notation, as in `my_vec.len()`." msgstr "" #. type: Plain text #: doc/tutorial.md:1621 msgid "" "_Implementations_, written with the `impl` keyword, can define methods on " "most Rust types, including structs and enums. As an example, let's define a " "`draw` method on our `Shape` enum." msgstr "" #. type: Plain text #: doc/tutorial.md:1629 #, no-wrap msgid "" "~~~\n" "# fn draw_circle(p: Point, f: float) { }\n" "# fn draw_rectangle(p: Point, p: Point) { }\n" "struct Point {\n" " x: float,\n" " y: float\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1634 #, no-wrap msgid "" "enum Shape {\n" " Circle(Point, float),\n" " Rectangle(Point, Point)\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1643 #, no-wrap msgid "" "impl Shape {\n" " fn draw(&self) {\n" " match *self {\n" " Circle(p, f) => draw_circle(p, f),\n" " Rectangle(p1, p2) => draw_rectangle(p1, p2)\n" " }\n" " }\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1647 msgid "let s = Circle(Point { x: 1f, y: 2f }, 3f); s.draw(); ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1651 msgid "" "This defines an _implementation_ for `Shape` containing a single method, " "`draw`. In most respects the `draw` method is defined like any other " "function, except for the name `self`." msgstr "" #. type: Plain text #: doc/tutorial.md:1656 msgid "" "The type of `self` is the type on which the method is implemented, or a " "pointer thereof. As an argument it is written either `self`, `&self`, " "`@self`, or `~self`. A caller must in turn have a compatible pointer type " "to call the method." msgstr "" #. type: Plain text #: doc/tutorial.md:1671 #, no-wrap msgid "" "~~~\n" "# fn draw_circle(p: Point, f: float) { }\n" "# fn draw_rectangle(p: Point, p: Point) { }\n" "# struct Point { x: float, y: float }\n" "# enum Shape {\n" "# Circle(Point, float),\n" "# Rectangle(Point, Point)\n" "# }\n" "impl Shape {\n" " fn draw_borrowed(&self) { ... }\n" " fn draw_managed(@self) { ... }\n" " fn draw_owned(~self) { ... }\n" " fn draw_value(self) { ... }\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1673 msgid "let s = Circle(Point { x: 1f, y: 2f }, 3f);" msgstr "" #. type: Plain text #: doc/tutorial.md:1679 msgid "" "(@s).draw_managed(); (~s).draw_owned(); (&s).draw_borrowed(); s." "draw_value(); ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1683 msgid "" "Methods typically take a borrowed pointer self type, so the compiler will go " "to great lengths to convert a callee to a borrowed pointer." msgstr "" #. type: Plain text #: doc/tutorial.md:1701 #, no-wrap msgid "" "~~~\n" "# fn draw_circle(p: Point, f: float) { }\n" "# fn draw_rectangle(p: Point, p: Point) { }\n" "# struct Point { x: float, y: float }\n" "# enum Shape {\n" "# Circle(Point, float),\n" "# Rectangle(Point, Point)\n" "# }\n" "# impl Shape {\n" "# fn draw_borrowed(&self) { ... }\n" "# fn draw_managed(@self) { ... }\n" "# fn draw_owned(~self) { ... }\n" "# fn draw_value(self) { ... }\n" "# }\n" "# let s = Circle(Point { x: 1f, y: 2f }, 3f);\n" "// As with typical function arguments, managed and owned pointers\n" "// are automatically converted to borrowed pointers\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1704 msgid "(@s).draw_borrowed(); (~s).draw_borrowed();" msgstr "" #. type: Plain text #: doc/tutorial.md:1708 msgid "" "// Unlike typical function arguments, the self value will // automatically " "be referenced ... s.draw_borrowed();" msgstr "" #. type: Plain text #: doc/tutorial.md:1711 msgid "// ... and dereferenced (& &s).draw_borrowed();" msgstr "" #. type: Plain text #: doc/tutorial.md:1715 msgid "// ... and dereferenced and borrowed (&@~s).draw_borrowed(); ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1719 msgid "" "Implementations may also define standalone (sometimes called \"static\") " "methods. The absence of a `self` parameter distinguishes such methods. " "These methods are the preferred way to define constructor functions." msgstr "" #. type: Plain text #: doc/tutorial.md:1726 #, no-wrap msgid "" "~~~~ {.xfail-test}\n" "impl Circle {\n" " fn area(&self) -> float { ... }\n" " fn new(area: float) -> Circle { ... }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1728 msgid "" "To call such a method, just prefix it with the type name and a double colon:" msgstr "" #. type: Plain text #: doc/tutorial.md:1738 #, no-wrap msgid "" "~~~~\n" "# use std::float::consts::pi;\n" "# use std::float::sqrt;\n" "struct Circle { radius: float }\n" "impl Circle {\n" " fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } }\n" "}\n" "let c = Circle::new(42.5);\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1740 msgid "# Generics" msgstr "" #. type: Plain text #: doc/tutorial.md:1748 msgid "" "Throughout this tutorial, we've been defining functions that act only on " "specific data types. With type parameters we can also define functions whose " "arguments have generic types, and which can be invoked with a variety of " "types. Consider a generic `map` function, which takes a function `function` " "and a vector `vector` and returns a new vector consisting of the result of " "applying `function` to each element of `vector`:" msgstr "" #. type: Plain text #: doc/tutorial.md:1758 #, no-wrap msgid "" "~~~~\n" "fn map(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] {\n" " let mut accumulator = ~[];\n" " for vector.iter().advance |element| {\n" " accumulator.push(function(element));\n" " }\n" " return accumulator;\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1763 msgid "" "When defined with type parameters, as denoted by ``, this function can " "be applied to any type of vector, as long as the type of `function`'s " "argument and the type of the vector's contents agree with each other." msgstr "" #. type: Plain text #: doc/tutorial.md:1773 msgid "" "Inside a generic function, the names of the type parameters (capitalized by " "convention) stand for opaque types. All you can do with instances of these " "types is pass them around: you can't apply any operations to them or pattern-" "match on them. Note that instances of generic types are often passed by " "pointer. For example, the parameter `function()` is supplied with a pointer " "to a value of type `T` and not a value of type `T` itself. This ensures that " "the function works with the broadest set of types possible, since some types " "are expensive or illegal to copy and pass by value." msgstr "" #. type: Plain text #: doc/tutorial.md:1775 msgid "" "Generic `type`, `struct`, and `enum` declarations follow the same pattern:" msgstr "" #. type: Plain text #: doc/tutorial.md:1779 msgid "~~~~ # use std::hashmap::HashMap; type Set = HashMap;" msgstr "" #. type: Plain text #: doc/tutorial.md:1783 #, no-wrap msgid "" "struct Stack {\n" " elements: ~[T]\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1789 #, no-wrap msgid "" "enum Option {\n" " Some(T),\n" " None\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1792 msgid "" "These declarations can be instantiated to valid types like `Set`, " "`Stack`, and `Option`." msgstr "" #. type: Plain text #: doc/tutorial.md:1798 msgid "" "The last type in that example, `Option`, appears frequently in Rust code. " "Because Rust does not have null pointers (except in unsafe code), we need " "another way to write a function whose result isn't defined on every possible " "combination of arguments of the appropriate types. The usual way is to write " "a function that returns `Option` instead of `T`." msgstr "" #. type: Plain text #: doc/tutorial.md:1809 #, no-wrap msgid "" "~~~~\n" "# struct Point { x: float, y: float }\n" "# enum Shape { Circle(Point, float), Rectangle(Point, Point) }\n" "fn radius(shape: Shape) -> Option {\n" " match shape {\n" " Circle(_, radius) => Some(radius),\n" " Rectangle(*) => None\n" " }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1817 msgid "" "The Rust compiler compiles generic functions very efficiently by " "*monomorphizing* them. *Monomorphization* is a fancy name for a simple idea: " "generate a separate copy of each generic function at each call site, a copy " "that is specialized to the argument types and can thus be optimized " "specifically for them. In this respect, Rust's generics have similar " "performance characteristics to C++ templates." msgstr "" #. type: Plain text #: doc/tutorial.md:1819 msgid "## Traits" msgstr "" #. type: Plain text #: doc/tutorial.md:1829 msgid "" "Within a generic function the operations available on generic types are very " "limited. After all, since the function doesn't know what types it is " "operating on, it can't safely modify or query their values. This is where " "_traits_ come into play. Traits are Rust's most powerful tool for writing " "polymorphic code. Java developers will see them as similar to Java " "interfaces, and Haskellers will notice their similarities to type classes. " "Rust's traits are a form of *bounded polymorphism*: a trait is a way of " "limiting the set of possible types that a type parameter could refer to." msgstr "" #. type: Plain text #: doc/tutorial.md:1836 msgid "" "As motivation, let us consider copying in Rust. The `copy` operation is not " "defined for all Rust types. One reason is user-defined destructors: copying " "a type that has a destructor could result in the destructor running multiple " "times. Therefore, types with user-defined destructors cannot be copied, " "either implicitly or explicitly, and neither can types that own other types " "containing destructors." msgstr "" #. type: Plain text #: doc/tutorial.md:1840 msgid "" "This complicates handling of generic functions. If you have a type parameter " "`T`, can you copy values of that type? In Rust, you can't, and if you try to " "run the following code the compiler will complain." msgstr "" #. type: Plain text #: doc/tutorial.md:1847 #, no-wrap msgid "" "~~~~ {.xfail-test}\n" "// This does not compile\n" "fn head_bad(v: &[T]) -> T {\n" " v[0] // error: copying a non-copyable value\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1852 msgid "" "However, we can tell the compiler that the `head` function is only for " "copyable types: that is, those that have the `Copy` trait. In that case, we " "can explicitly create a second copy of the value we are returning using the " "`copy` keyword:" msgstr "" #. type: Plain text #: doc/tutorial.md:1859 #, no-wrap msgid "" "~~~~\n" "// This does\n" "fn head(v: &[T]) -> T {\n" " copy v[0]\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1867 msgid "" "This says that we can call `head` on any type `T` as long as that type " "implements the `Copy` trait. When instantiating a generic function, you can " "only instantiate it with types that implement the correct trait, so you " "could not apply `head` to a type with a destructor. (`Copy` is a special " "trait that is built in to the compiler, making it possible for the compiler " "to enforce this restriction.)" msgstr "" #. type: Plain text #: doc/tutorial.md:1871 msgid "" "While most traits can be defined and implemented by user code, three traits " "are automatically derived and implemented for all applicable types by the " "compiler, and may not be overridden:" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:1875 msgid "" "`Copy` - Types that can be copied, either implicitly, or explicitly with the " "`copy` operator. All types are copyable unless they have destructors or " "contain types with destructors." msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:1879 msgid "" "`Owned` - Owned types. Types are owned unless they contain managed boxes, " "managed closures, or borrowed pointers. Owned types may or may not be " "copyable." msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:1882 msgid "" "`Const` - Constant (immutable) types. These are types that do not contain " "mutable fields." msgstr "" #. type: Plain text #: doc/tutorial.md:1885 msgid "" "> ***Note:*** These three traits were referred to as 'kinds' in earlier > " "iterations of the language, and often still are." msgstr "" #. type: Plain text #: doc/tutorial.md:1891 msgid "" "Additionally, the `Drop` trait is used to define destructors. This trait " "defines one method called `drop`, which is automatically called when a value " "of the type that implements this trait is destroyed, either because the " "value went out of scope or because the garbage collector reclaimed it." msgstr "" #. type: Plain text #: doc/tutorial.md:1896 #, no-wrap msgid "" "~~~\n" "struct TimeBomb {\n" " explosivity: uint\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1905 #, no-wrap msgid "" "impl Drop for TimeBomb {\n" " fn drop(&self) {\n" " for self.explosivity.times {\n" " println(\"blam!\");\n" " }\n" " }\n" "}\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1908 msgid "" "It is illegal to call `drop` directly. Only code inserted by the compiler " "may call it." msgstr "" #. type: Plain text #: doc/tutorial.md:1910 msgid "## Declaring and implementing traits" msgstr "" #. type: Plain text #: doc/tutorial.md:1915 msgid "" "A trait consists of a set of methods, without bodies, or may be empty, as is " "the case with `Copy`, `Owned`, and `Const`. For example, we could declare " "the trait `Printable` for things that can be printed to the console, with a " "single method:" msgstr "" #. type: Plain text #: doc/tutorial.md:1921 #, no-wrap msgid "" "~~~~\n" "trait Printable {\n" " fn print(&self);\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1926 msgid "" "Traits may be implemented for specific types with [impls]. An impl that " "implements a trait includes the name of the trait at the start of the " "definition, as in the following impls of `Printable` for `int` and `~str`." msgstr "" #. type: Plain text #: doc/tutorial.md:1928 msgid "[impls]: #functions-and-methods" msgstr "" #. type: Plain text #: doc/tutorial.md:1934 #, no-wrap msgid "" "~~~~\n" "# trait Printable { fn print(&self); }\n" "impl Printable for int {\n" " fn print(&self) { println(fmt!(\"%d\", *self)) }\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1938 #, no-wrap msgid "" "impl Printable for ~str {\n" " fn print(&self) { println(*self) }\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1942 msgid "# 1.print(); # (~\"foo\").print(); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1947 msgid "" "Methods defined in an implementation of a trait may be called just like any " "other method, using dot notation, as in `1.print()`. Traits may themselves " "contain type parameters. A trait for generalized sequence types might look " "like the following:" msgstr "" #. type: Plain text #: doc/tutorial.md:1952 #, no-wrap msgid "" "~~~~\n" "trait Seq {\n" " fn length(&self) -> uint;\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1957 #, no-wrap msgid "" "impl Seq for ~[T] {\n" " fn length(&self) -> uint { self.len() }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1964 msgid "" "The implementation has to explicitly declare the type parameter that it " "binds, `T`, before using it to specify its trait type. Rust requires this " "declaration because the `impl` could also, for example, specify an " "implementation of `Seq`. The trait type (appearing between `impl` and " "`for`) *refers* to a type, rather than defining one." msgstr "" #. type: Plain text #: doc/tutorial.md:1969 msgid "" "The type parameters bound by a trait are in scope in each of the method " "declarations. So, re-declaring the type parameter `T` as an explicit type " "parameter for `len`, in either the trait or the impl, would be a compile-" "time error." msgstr "" #. type: Plain text #: doc/tutorial.md:1974 msgid "" "Within a trait definition, `Self` is a special type that you can think of as " "a type parameter. An implementation of the trait for any given type `T` " "replaces the `Self` type parameter with `T`. The following trait describes " "types that support an equality operation:" msgstr "" #. type: Plain text #: doc/tutorial.md:1981 #, no-wrap msgid "" "~~~~\n" "// In a trait, `self` refers to the self argument.\n" "// `Self` refers to the type implementing the trait.\n" "trait Eq {\n" " fn equals(&self, other: &Self) -> bool;\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1987 #, no-wrap msgid "" "// In an impl, `self` refers just to the value of the receiver\n" "impl Eq for int {\n" " fn equals(&self, other: &int) -> bool { *other == *self }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1992 msgid "" "Notice that in the trait definition, `equals` takes a second parameter of " "type `Self`. In contrast, in the `impl`, `equals` takes a second parameter " "of type `int`, only using `self` as the name of the receiver." msgstr "" #. type: Plain text #: doc/tutorial.md:1997 msgid "" "Just as in type implementations, traits can define standalone (static) " "methods. These methods are called by prefixing the method name with the " "trait name and a double colon. The compiler uses type inference to decide " "which implementation to use." msgstr "" #. type: Plain text #: doc/tutorial.md:2004 msgid "" "~~~~ # use std::float::consts::pi; # use std::float::sqrt; trait Shape { fn " "new(area: float) -> Self; } struct Circle { radius: float } struct Square " "{ length: float }" msgstr "" #. type: Plain text #: doc/tutorial.md:2011 #, no-wrap msgid "" "impl Shape for Circle {\n" " fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } }\n" "}\n" "impl Shape for Square {\n" " fn new(area: float) -> Square { Square { length: sqrt(area) } }\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2016 msgid "" "let area = 42.5; let c: Circle = Shape::new(area); let s: Square = Shape::" "new(area); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2018 msgid "## Bounded type parameters and static method dispatch" msgstr "" #. type: Plain text #: doc/tutorial.md:2023 msgid "" "Traits give us a language for defining predicates on types, or abstract " "properties that types can have. We can use this language to define _bounds_ " "on type parameters, so that we can then operate on generic types." msgstr "" #. type: Plain text #: doc/tutorial.md:2032 #, no-wrap msgid "" "~~~~\n" "# trait Printable { fn print(&self); }\n" "fn print_all(printable_things: ~[T]) {\n" " for printable_things.iter().advance |thing| {\n" " thing.print();\n" " }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2038 msgid "" "Declaring `T` as conforming to the `Printable` trait (as we earlier did with " "`Copy`) makes it possible to call methods from that trait on values of type " "`T` inside the function. It will also cause a compile-time error when anyone " "tries to call `print_all` on an array whose element type does not have a " "`Printable` implementation." msgstr "" #. type: Plain text #: doc/tutorial.md:2041 msgid "" "Type parameters can have multiple bounds by separating them with `+`, as in " "this version of `print_all` that copies elements." msgstr "" #. type: Plain text #: doc/tutorial.md:2053 #, no-wrap msgid "" "~~~\n" "# trait Printable { fn print(&self); }\n" "fn print_all(printable_things: ~[T]) {\n" " let mut i = 0;\n" " while i < printable_things.len() {\n" " let copy_of_thing = copy printable_things[i];\n" " copy_of_thing.print();\n" " i += 1;\n" " }\n" "}\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2057 msgid "" "Method calls to bounded type parameters are _statically dispatched_, " "imposing no more overhead than normal function invocation, so are the " "preferred way to use traits polymorphically." msgstr "" #. type: Plain text #: doc/tutorial.md:2059 msgid "This usage of traits is similar to Haskell type classes." msgstr "" #. type: Plain text #: doc/tutorial.md:2061 msgid "## Trait objects and dynamic method dispatch" msgstr "" #. type: Plain text #: doc/tutorial.md:2065 msgid "" "The above allows us to define functions that polymorphically act on values " "of a single unknown type that conforms to a given trait. However, consider " "this function:" msgstr "" #. type: Plain text #: doc/tutorial.md:2071 msgid "" "~~~~ # type Circle = int; type Rectangle = int; # impl Drawable for int { fn " "draw(&self) {} } # fn new_circle() -> int { 1 } trait Drawable { fn " "draw(&self); }" msgstr "" #. type: Plain text #: doc/tutorial.md:2078 #, no-wrap msgid "" "fn draw_all(shapes: ~[T]) {\n" " for shapes.iter().advance |shape| { shape.draw(); }\n" "}\n" "# let c: Circle = new_circle();\n" "# draw_all(~[c]);\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2084 msgid "" "You can call that on an array of circles, or an array of rectangles " "(assuming those have suitable `Drawable` traits defined), but not on an " "array containing both circles and rectangles. When such behavior is needed, " "a trait name can alternately be used as a type, called an _object_." msgstr "" #. type: Plain text #: doc/tutorial.md:2091 #, no-wrap msgid "" "~~~~\n" "# trait Drawable { fn draw(&self); }\n" "fn draw_all(shapes: &[@Drawable]) {\n" " for shapes.iter().advance |shape| { shape.draw(); }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2096 msgid "" "In this example, there is no type parameter. Instead, the `@Drawable` type " "denotes any managed box value that implements the `Drawable` trait. To " "construct such a value, you use the `as` operator to cast a value to an " "object:" msgstr "" #. type: Plain text #: doc/tutorial.md:2103 msgid "" "~~~~ # type Circle = int; type Rectangle = bool; # trait Drawable { fn " "draw(&self); } # fn new_circle() -> Circle { 1 } # fn new_rectangle() -> " "Rectangle { true } # fn draw_all(shapes: &[@Drawable]) {}" msgstr "" #. type: Plain text #: doc/tutorial.md:2106 msgid "" "impl Drawable for Circle { fn draw(&self) { ... } } impl Drawable for " "Rectangle { fn draw(&self) { ... } }" msgstr "" #. type: Plain text #: doc/tutorial.md:2111 msgid "" "let c: @Circle = @new_circle(); let r: @Rectangle = @new_rectangle(); " "draw_all([c as @Drawable, r as @Drawable]); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2119 msgid "" "We omit the code for `new_circle` and `new_rectangle`; imagine that these " "just return `Circle`s and `Rectangle`s with a default size. Note that, like " "strings and vectors, objects have dynamic size and may only be referred to " "via one of the pointer types. Other pointer types work as well. Casts to " "traits may only be done with compatible pointers so, for example, an " "`@Circle` may not be cast to an `~Drawable`." msgstr "" #. type: Plain text #: doc/tutorial.md:2133 msgid "" "~~~ # type Circle = int; type Rectangle = int; # trait Drawable { fn " "draw(&self); } # impl Drawable for int { fn draw(&self) {} } # fn " "new_circle() -> int { 1 } # fn new_rectangle() -> int { 2 } // A managed " "object let boxy: @Drawable = @new_circle() as @Drawable; // An owned object " "let owny: ~Drawable = ~new_circle() as ~Drawable; // A borrowed object let " "stacky: &Drawable = &new_circle() as &Drawable; ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2138 msgid "" "Method calls to trait types are _dynamically dispatched_. Since the compiler " "doesn't know specifically which functions to call at compile time, it uses a " "lookup table (also known as a vtable or dictionary) to select the method to " "call at runtime." msgstr "" #. type: Plain text #: doc/tutorial.md:2140 msgid "This usage of traits is similar to Java interfaces." msgstr "" #. type: Plain text #: doc/tutorial.md:2142 msgid "## Trait inheritance" msgstr "" #. type: Plain text #: doc/tutorial.md:2147 msgid "" "We can write a trait declaration that _inherits_ from other traits, called " "_supertraits_. Types that implement a trait must also implement its " "supertraits. For example, we can define a `Circle` trait that inherits from " "`Shape`." msgstr "" #. type: Plain text #: doc/tutorial.md:2152 msgid "" "~~~~ trait Shape { fn area(&self) -> float; } trait Circle : Shape { fn " "radius(&self) -> float; } ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2154 msgid "" "Now, we can implement `Circle` on a type only if we also implement `Shape`." msgstr "" #. type: Plain text #: doc/tutorial.md:2170 #, no-wrap msgid "" "~~~~\n" "# use std::float::consts::pi;\n" "# use std::float::sqrt;\n" "# trait Shape { fn area(&self) -> float; }\n" "# trait Circle : Shape { fn radius(&self) -> float; }\n" "# struct Point { x: float, y: float }\n" "# fn square(x: float) -> float { x * x }\n" "struct CircleStruct { center: Point, radius: float }\n" "impl Circle for CircleStruct {\n" " fn radius(&self) -> float { sqrt(self.area() / pi) }\n" "}\n" "impl Shape for CircleStruct {\n" " fn area(&self) -> float { pi * square(self.radius) }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2175 msgid "" "Notice that methods of `Circle` can call methods on `Shape`, as our `radius` " "implementation calls the `area` method. This is a silly way to compute the " "radius of a circle (since we could just return the `radius` field), but you " "get the idea." msgstr "" #. type: Plain text #: doc/tutorial.md:2200 msgid "" "~~~ {.xfail-test} # use std::float::consts::pi; # use std::float::sqrt; # " "trait Shape { fn area(&self) -> float; } # trait Circle : Shape { fn " "radius(&self) -> float; } # struct Point { x: float, y: float } # struct " "CircleStruct { center: Point, radius: float } # impl Circle for CircleStruct " "{ fn radius(&self) -> float { sqrt(self.area() / pi) } } # impl Shape for " "CircleStruct { fn area(&self) -> float { pi * square(self.radius) } }" msgstr "" #. type: Plain text #: doc/tutorial.md:2205 msgid "" "let concrete = @CircleStruct{center:Point{x:3f,y:4f},radius:5f}; let " "mycircle: Circle = concrete as @Circle; let nonsense = mycircle.radius() * " "mycircle.area(); ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2207 msgid "> ***Note:*** Trait inheritance does not actually work with objects yet" msgstr "" #. type: Plain text #: doc/tutorial.md:2209 msgid "## Deriving implementations for traits" msgstr "" #. type: Plain text #: doc/tutorial.md:2216 msgid "" "A small number of traits in `std` and `extra` can have implementations that " "can be automatically derived. These instances are specified by placing the " "`deriving` attribute on a data type declaration. For example, the following " "will mean that `Circle` has an implementation for `Eq` and can be used with " "the equality operators, and that a value of type `ABC` can be randomly " "generated and converted to a string:" msgstr "" #. type: Plain text #: doc/tutorial.md:2220 msgid "~~~ #[deriving(Eq)] struct Circle { radius: float }" msgstr "" #. type: Plain text #: doc/tutorial.md:2224 msgid "#[deriving(Rand, ToStr)] enum ABC { A, B, C } ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2228 msgid "" "The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, `TotalOrd`, " "`Encodable` `Decodable`, `Clone`, `DeepClone`, `IterBytes`, `Rand`, `Zero`, " "and `ToStr`." msgstr "" #. type: Plain text #: doc/tutorial.md:2230 msgid "# Modules and crates" msgstr "" #. type: Plain text #: doc/tutorial.md:2234 msgid "" "The Rust namespace is arranged in a hierarchy of modules. Each source (.rs) " "file represents a single module and may in turn contain additional modules." msgstr "" #. type: Plain text #: doc/tutorial.md:2240 #, no-wrap msgid "" "~~~~\n" "mod farm {\n" " pub fn chicken() -> &str { \"cluck cluck\" }\n" " pub fn cow() -> &str { \"mooo\" }\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2245 #, no-wrap msgid "" "fn main() {\n" " println(farm::chicken());\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2250 msgid "" "The contents of modules can be imported into the current scope with the " "`use` keyword, optionally giving it an alias. `use` may appear at the " "beginning of crates, `mod`s, `fn`s, and other blocks." msgstr "" #. type: Plain text #: doc/tutorial.md:2256 msgid "" "~~~ # mod farm { pub fn chicken() { } } # fn main() { // Bring `chicken` " "into scope use farm::chicken;" msgstr "" #. type: Plain text #: doc/tutorial.md:2266 #, no-wrap msgid "" "fn chicken_farmer() {\n" " // The same, but name it `my_chicken`\n" " use my_chicken = farm::chicken;\n" " ...\n" "# my_chicken();\n" "}\n" "# chicken();\n" "# }\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2273 msgid "" "These farm animal functions have a new keyword, `pub`, attached to them. The " "`pub` keyword modifies an item's visibility, making it visible outside its " "containing module. An expression with `::`, like `farm::chicken`, can name " "an item outside of its containing module. Items, such as those declared with " "`fn`, `struct`, `enum`, `type`, or `static`, are module-private by default." msgstr "" #. type: Plain text #: doc/tutorial.md:2280 msgid "" "Visibility restrictions in Rust exist only at module boundaries. This is " "quite different from most object-oriented languages that also enforce " "restrictions on objects themselves. That's not to say that Rust doesn't " "support encapsulation: both struct fields and methods can be private. But " "this encapsulation is at the module level, not the struct level. Note that " "fields and methods are _public_ by default." msgstr "" #. type: Plain text #: doc/tutorial.md:2293 #, no-wrap msgid "" "~~~\n" "pub mod farm {\n" "# pub type Chicken = int;\n" "# type Cow = int;\n" "# struct Human(int);\n" "# impl Human { fn rest(&self) { } }\n" "# pub fn make_me_a_farm() -> Farm { Farm { chickens: ~[], cows: ~[], farmer: Human(0) } }\n" " pub struct Farm {\n" " priv chickens: ~[Chicken],\n" " priv cows: ~[Cow],\n" " farmer: Human\n" " }\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2299 #, no-wrap msgid "" " impl Farm {\n" " priv fn feed_chickens(&self) { ... }\n" " priv fn feed_cows(&self) { ... }\n" " pub fn add_chicken(&self, c: Chicken) { ... }\n" " }\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2305 #, no-wrap msgid "" " pub fn feed_animals(farm: &Farm) {\n" " farm.feed_chickens();\n" " farm.feed_cows();\n" " }\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2315 #, no-wrap msgid "" "fn main() {\n" " let f = make_me_a_farm();\n" " f.add_chicken(make_me_a_chicken());\n" " farm::feed_animals(&f);\n" " f.farmer.rest();\n" "}\n" "# fn make_me_a_farm() -> farm::Farm { farm::make_me_a_farm() }\n" "# fn make_me_a_chicken() -> farm::Chicken { 0 }\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2317 msgid "## Crates" msgstr "" #. type: Plain text #: doc/tutorial.md:2321 msgid "" "The unit of independent compilation in Rust is the crate: rustc compiles a " "single crate at a time, from which it produces either a library or an " "executable." msgstr "" #. type: Plain text #: doc/tutorial.md:2326 msgid "" "When compiling a single `.rs` source file, the file acts as the whole " "crate. You can compile it with the `--lib` compiler switch to create a " "shared library, or without, provided that your file contains a `fn main` " "somewhere, to create an executable." msgstr "" #. type: Plain text #: doc/tutorial.md:2331 msgid "" "Larger crates typically span multiple files and are, by convention, compiled " "from a source file with the `.rc` extension, called a *crate file*. The " "crate file extension distinguishes source files that represent crates from " "those that do not, but otherwise source files and crate files are identical." msgstr "" #. type: Plain text #: doc/tutorial.md:2340 msgid "" "A typical crate file declares attributes associated with the crate that may " "affect how the compiler processes the source. Crate attributes specify " "metadata used for locating and linking crates, the type of crate (library or " "executable), and control warning and error behavior, among other things. " "Crate files additionally declare the external crates they depend on as well " "as any modules loaded from other files." msgstr "" #. type: Plain text #: doc/tutorial.md:2344 msgid "" "~~~~ { .xfail-test } // Crate linkage metadata #[link(name = \"farm\", vers " "= \"2.5\", author = \"mjh\")];" msgstr "" #. type: Plain text #: doc/tutorial.md:2347 msgid "// Make a library (\"bin\" is the default) #[crate_type = \"lib\"];" msgstr "" #. type: Plain text #: doc/tutorial.md:2350 msgid "// Turn on a warning #[warn(non_camel_case_types)]" msgstr "" #. type: Plain text #: doc/tutorial.md:2353 msgid "// Link to the standard library extern mod std;" msgstr "" #. type: Plain text #: doc/tutorial.md:2358 msgid "// Load some modules from other files mod cow; mod chicken; mod horse;" msgstr "" #. type: Plain text #: doc/tutorial.md:2363 #, no-wrap msgid "" "fn main() {\n" " ...\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2370 msgid "" "Compiling this file will cause `rustc` to look for files named `cow.rs`, " "`chicken.rs`, and `horse.rs` in the same directory as the `.rc` file, " "compile them all together, and, based on the presence of the `crate_type = " "\"lib\"` attribute, output a shared library or an executable. (If the line " "`#[crate_type = \"lib\"];` was omitted, `rustc` would create an executable.)" msgstr "" #. type: Plain text #: doc/tutorial.md:2374 msgid "" "The `#[link(...)]` attribute provides meta information about the module, " "which other crates can use to load the right module. More about that later." msgstr "" #. type: Plain text #: doc/tutorial.md:2377 msgid "" "To have a nested directory structure for your source files, you can nest " "mods:" msgstr "" #. type: Plain text #: doc/tutorial.md:2384 #, no-wrap msgid "" "~~~~ {.ignore}\n" "mod poultry {\n" " mod chicken;\n" " mod turkey;\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2389 msgid "" "The compiler will now look for `poultry/chicken.rs` and `poultry/turkey.rs`, " "and export their content in `poultry::chicken` and `poultry::turkey`. You " "can also provide a `poultry.rs` to add content to the `poultry` module " "itself." msgstr "" #. type: Plain text #: doc/tutorial.md:2391 msgid "## Using other crates" msgstr "" #. type: Plain text #: doc/tutorial.md:2399 msgid "" "The `extern mod` directive lets you use a crate (once it's been compiled " "into a library) from inside another crate. `extern mod` can appear at the " "top of a crate file or at the top of modules. It will cause the compiler to " "look in the library search path (which you can extend with the `-L` switch) " "for a compiled Rust library with the right name, then add a module with that " "crate's name into the local scope." msgstr "" #. type: Plain text #: doc/tutorial.md:2401 msgid "For example, `extern mod std` links the [standard library]." msgstr "" #. type: Plain text #: doc/tutorial.md:2403 msgid "[standard library]: std/index.html" msgstr "" #. type: Plain text #: doc/tutorial.md:2410 msgid "" "When a comma-separated list of name/value pairs appears after `extern mod`, " "the compiler front-end matches these pairs against the attributes provided " "in the `link` attribute of the crate file. The front-end will only select " "this crate for use if the actual pairs match the declared attributes. You " "can provide a `name` value to override the name used to search for the crate." msgstr "" #. type: Plain text #: doc/tutorial.md:2412 msgid "Our example crate declared this set of `link` attributes:" msgstr "" #. type: Plain text #: doc/tutorial.md:2416 msgid "~~~~ #[link(name = \"farm\", vers = \"2.5\", author = \"mjh\")]; ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2418 msgid "Which you can then link with any (or all) of the following:" msgstr "" #. type: Plain text #: doc/tutorial.md:2424 msgid "" "~~~~ {.xfail-test} extern mod farm; extern mod my_farm (name = \"farm\", " "vers = \"2.5\"); extern mod my_auxiliary_farm (name = \"farm\", author = " "\"mjh\"); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2427 msgid "" "If any of the requested metadata do not match, then the crate will not be " "compiled successfully." msgstr "" #. type: Plain text #: doc/tutorial.md:2429 msgid "## A minimal example" msgstr "" #. type: Plain text #: doc/tutorial.md:2432 msgid "" "Now for something that you can actually compile yourself, we have these two " "files:" msgstr "" #. type: Plain text #: doc/tutorial.md:2438 msgid "" "~~~~ // world.rs #[link(name = \"world\", vers = \"1.0\")]; pub fn explore() " "-> &str { \"world\" } ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2444 msgid "" "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello " "\" + world::explore()); } ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2446 msgid "Now compile and run like this (adjust to your platform if necessary):" msgstr "" #. type: Plain text #: doc/tutorial.md:2453 #, no-wrap msgid "" "~~~~ {.notrust}\n" "> rustc --lib world.rs # compiles libworld-94839cbfe144198-1.0.so\n" "> rustc main.rs -L . # compiles main\n" "> ./main\n" "\"hello world\"\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2458 msgid "" "Notice that the library produced contains the version in the filename as " "well as an inscrutable string of alphanumerics. These are both part of " "Rust's library versioning scheme. The alphanumerics are a hash representing " "the crate metadata." msgstr "" #. type: Plain text #: doc/tutorial.md:2460 msgid "## The standard library" msgstr "" #. type: Plain text #: doc/tutorial.md:2465 msgid "" "The Rust standard library provides runtime features required by the " "language, including the task scheduler and memory allocators, as well as " "library support for Rust built-in types, platform abstractions, and other " "commonly used features." msgstr "" #. type: Plain text #: doc/tutorial.md:2476 msgid "" "[`std`] includes modules corresponding to each of the integer types, each of " "the floating point types, the [`bool`] type, [tuples], [characters], " "[strings], [vectors], [managed boxes], [owned boxes], and unsafe and " "borrowed [pointers]. Additionally, `std` provides some pervasive types " "([`option`] and [`result`]), [task] creation and [communication] primitives, " "platform abstractions ([`os`] and [`path`]), basic I/O abstractions " "([`io`]), [containers] like [`hashmap`], common traits ([`kinds`], [`ops`], " "[`cmp`], [`num`], [`to_str`], [`clone`]), and complete bindings to the C " "standard library ([`libc`])." msgstr "" #. type: Plain text #: doc/tutorial.md:2478 msgid "### Standard Library injection and the Rust prelude" msgstr "" #. type: Plain text #: doc/tutorial.md:2481 msgid "" "`std` is imported at the topmost level of every crate by default, as if the " "first line of each crate was" msgstr "" #. type: Plain text #: doc/tutorial.md:2483 #, no-wrap msgid " extern mod std;\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2487 msgid "" "This means that the contents of std can be accessed from from any context " "with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`, " "etc." msgstr "" #. type: Plain text #: doc/tutorial.md:2492 msgid "" "Additionally, `std` contains a `prelude` module that reexports many of the " "most common standard modules, types and traits. The contents of the prelude " "are imported into every *module* by default. Implicitly, all modules behave " "as if they contained the following prologue:" msgstr "" #. type: Plain text #: doc/tutorial.md:2494 #, no-wrap msgid " use std::prelude::*;\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2520 msgid "" "[`std`]: std/index.html [`bool`]: std/bool.html [tuples]: std/tuple.html " "[characters]: std/char.html [strings]: std/str.html [vectors]: std/vec.html " "[managed boxes]: std/managed.html [owned boxes]: std/owned.html [pointers]: " "std/ptr.html [`option`]: std/option.html [`result`]: std/result.html [task]: " "std/task.html [communication]: std/comm.html [`os`]: std/os.html [`path`]: " "std/path.html [`io`]: std/io.html [containers]: std/container.html " "[`hashmap`]: std/hashmap.html [`kinds`]: std/kinds.html [`ops`]: std/ops." "html [`cmp`]: std/cmp.html [`num`]: std/num.html [`to_str`]: std/to_str.html " "[`clone`]: std/clone.html [`libc`]: std/libc.html" msgstr "" #. type: Plain text #: doc/tutorial.md:2522 msgid "# What next?" msgstr "" #. type: Plain text #: doc/tutorial.md:2525 msgid "" "Now that you know the essentials, check out any of the additional tutorials " "on individual topics." msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:2531 msgid "[Borrowed pointers][borrow]" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:2531 msgid "[Tasks and communication][tasks]" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:2531 msgid "[Macros][macros]" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:2531 msgid "[The foreign function interface][ffi]" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:2531 msgid "[Containers and iterators](tutorial-container.html)" msgstr "" #. type: Plain text #: doc/tutorial.md:2533 msgid "There is further documentation on the [wiki]." msgstr "" #. type: Plain text #: doc/tutorial.md:2538 msgid "" "[borrow]: tutorial-borrowed-ptr.html [tasks]: tutorial-tasks.html [macros]: " "tutorial-macros.html [ffi]: tutorial-ffi.html" msgstr "" #. type: Plain text #: doc/tutorial.md:2544 msgid "" "[wiki]: https://github.com/mozilla/rust/wiki/Docs [unit testing]: https://" "github.com/mozilla/rust/wiki/Doc-unit-testing [rustdoc]: https://github.com/" "mozilla/rust/wiki/Doc-using-rustdoc [cargo]: https://github.com/mozilla/rust/" "wiki/Doc-using-cargo-to-manage-packages [attributes]: https://github.com/" "mozilla/rust/wiki/Doc-attributes" msgstr "" #. type: Plain text #: doc/tutorial.md:2545 msgid "" "[pound-rust]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust" msgstr ""