# SOME DESCRIPTIVE TITLE # Copyright (C) YEAR The Rust Project Developers # This file is distributed under the same license as the Rust package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Rust 0.8\n" "POT-Creation-Date: 2013-08-12 02:06+0900\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=UTF-8\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 msgid "# Introduction" msgstr "" #. type: Plain text #: doc/rust.md:1277 doc/tutorial.md:2176 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:1286 doc/tutorial.md:2185 #, 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:1288 doc/tutorial.md:2187 msgid "Likewise, supertrait methods may also be called on trait objects." msgstr "" #. type: Plain text #: doc/tutorial.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]: " "https://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.8.tar.gz $ " "tar -xzf rust-0.8.tar.gz $ cd rust-0.8 $ ./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:123 msgid "" "[tarball]: http://static.rust-lang.org/dist/rust-0.8.tar.gz [win-exe]: " "http://static.rust-lang.org/dist/rust-0.8-install.exe" msgstr "" #. type: Plain text #: doc/tutorial.md:125 msgid "## Compiling your first program" msgstr "" #. type: Plain text #: doc/tutorial.md:128 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:134 #, no-wrap msgid "" "~~~~\n" "fn main() {\n" " println(\"hello?\");\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:138 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:143 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:149 #, 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:156 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:158 msgid "## Using the rust tool" msgstr "" #. type: Plain text #: doc/tutorial.md:163 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:169 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:172 msgid "" "To get a list of all available commands, simply call `rust` without any " "argument." msgstr "" #. type: Plain text #: doc/tutorial.md:174 msgid "## Editing Rust code" msgstr "" #. type: Plain text #: doc/tutorial.md:184 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:188 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:191 msgid "" "[sublime]: http://github.com/dbp/sublime-rust [sublime-pkg]: http://wbond." "net/sublime_packages/package_control" msgstr "" #. type: Plain text #: doc/tutorial.md:193 msgid "# Syntax basics" msgstr "" #. type: Plain text #: doc/tutorial.md:201 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:206 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:219 #, 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:223 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:227 msgid "~~~~ let hi = \"hi\"; let mut count = 0;" msgstr "" #. type: Plain text #: doc/tutorial.md:233 #, no-wrap msgid "" "while count < 10 {\n" " println(fmt!(\"count: %?\", count));\n" " count += 1;\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:237 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:243 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:252 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:258 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:263 #, 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:265 msgid "## Expressions and semicolons" msgstr "" #. type: Plain text #: doc/tutorial.md:271 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:283 #, 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:285 msgid "But, in Rust, you don't have to repeat the name `price`:" msgstr "" #. type: Plain text #: doc/tutorial.md:297 #, 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:303 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:309 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:314 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 static items) is an expression, " "including function bodies." msgstr "" #. type: Plain text #: doc/tutorial.md:322 #, 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:324 msgid "## Primitive types and literals" msgstr "" #. type: Plain text #: doc/tutorial.md:331 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:337 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:344 #, 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:349 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:351 msgid "The keywords `true` and `false` produce literals of type `bool`." msgstr "" #. type: Plain text #: doc/tutorial.md:358 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:360 msgid "The nil type, written `()`, has a single value, also written `()`." msgstr "" #. type: Plain text #: doc/tutorial.md:362 msgid "## Operators" msgstr "" #. type: Plain text #: doc/tutorial.md:367 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:370 msgid "" "Note that, if applied to an integer value, `!` flips all the bits (like `~` " "in C)." msgstr "" #. type: Plain text #: doc/tutorial.md:374 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:379 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:385 msgid "" "~~~~ let x: float = 4.0; let y: uint = x as uint; assert!(y == 4u); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:387 msgid "## Syntax extensions" msgstr "" #. type: Plain text #: doc/tutorial.md:394 #, 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:398 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:401 msgid "~~~~ # let mystery_object = ();" msgstr "" #. type: Plain text #: doc/tutorial.md:403 msgid "println(fmt!(\"%s is %d\", \"the answer\", 43));" msgstr "" #. type: Plain text #: doc/tutorial.md:407 msgid "" "// %? will conveniently print any type println(fmt!(\"what is this thing: %?" "\", mystery_object)); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:409 msgid "[pf]: http://en.cppreference.com/w/cpp/io/c/fprintf" msgstr "" #. type: Plain text #: doc/tutorial.md:411 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:413 msgid "# Control structures" msgstr "" #. type: Plain text #: doc/tutorial.md:415 msgid "## Conditionals" msgstr "" #. type: Plain text #: doc/tutorial.md:419 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:429 #, 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:434 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:442 #, 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:444 msgid "## Pattern matching" msgstr "" #. type: Plain text #: doc/tutorial.md:450 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:460 #, 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:464 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:474 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:479 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:487 #, 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:492 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:496 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:500 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:513 #, no-wrap msgid "" "~~~~\n" "use std::float;\n" "use std::num::atan;\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) => atan(y / x)\n" " }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:519 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:526 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:531 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:536 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:540 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:542 msgid "## Loops" msgstr "" #. type: Plain text #: doc/tutorial.md:547 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:554 #, 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:556 msgid "" "`loop` denotes an infinite loop, and is the preferred way of writing `while " "true`:" msgstr "" #. type: Plain text #: doc/tutorial.md:566 #, 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:569 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:571 msgid "# Data structures" msgstr "" #. type: Plain text #: doc/tutorial.md:573 msgid "## Structs" msgstr "" #. type: Plain text #: doc/tutorial.md:578 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:582 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:589 #, no-wrap msgid "" "~~~~\n" "struct Point {\n" " x: float,\n" " y: float\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:593 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:597 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:602 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:606 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:609 msgid "" "`match` patterns destructure structs. The basic syntax is `Name { fieldname: " "pattern, ... }`:" msgstr "" #. type: Plain text #: doc/tutorial.md:618 #, 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:625 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:633 #, 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:635 msgid "## Enums" msgstr "" #. type: Plain text #: doc/tutorial.md:638 msgid "" "Enums are datatypes that have several alternate representations. For " "example, consider the type shown earlier:" msgstr "" #. type: Plain text #: doc/tutorial.md:646 #, 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:652 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:658 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:661 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:670 #, no-wrap msgid "" "~~~~\n" "enum Direction {\n" " North,\n" " East,\n" " South,\n" " West\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:673 msgid "" "This declaration defines `North`, `East`, `South`, and `West` as constants, " "all of which have type `Direction`." msgstr "" #. type: Plain text #: doc/tutorial.md:677 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:685 #, 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:690 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:693 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:697 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:709 #, 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:714 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:727 #, 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:729 msgid "Enum variants may also be structs. For example:" msgstr "" #. type: Plain text #: doc/tutorial.md:747 #, 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:749 msgid "## Tuples" msgstr "" #. type: Plain text #: doc/tutorial.md:754 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:761 #, 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:763 msgid "## Tuple structs" msgstr "" #. type: Plain text #: doc/tutorial.md:768 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:777 #, 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:779 msgid "" msgstr "" #. type: Plain text #: doc/tutorial.md:784 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:788 msgid "~~~~ struct GizmoId(int); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:791 msgid "" "For convenience, you can extract the contents of such a struct with the " "dereference (`*`) unary operator:" msgstr "" #. type: Plain text #: doc/tutorial.md:797 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:800 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:805 msgid "~~~~ struct Inches(int); struct Centimeters(int); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:808 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:810 msgid "# Functions" msgstr "" #. type: Plain text #: doc/tutorial.md:818 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:824 #, 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:829 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:835 #, 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:842 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:845 msgid "~~~~ fn do_nothing_the_hard_way() -> () { return (); }" msgstr "" #. type: Plain text #: doc/tutorial.md:848 msgid "fn do_nothing_the_easy_way() { } ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:850 msgid "" "Ending the function with a semicolon like so is equivalent to returning `()`." msgstr "" #. type: Plain text #: doc/tutorial.md:854 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:858 msgid "assert!(8 == line(5, 3, 1)); assert!(() == oops(5, 3, 1)); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:862 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:866 msgid "~~~ fn first((value, _): (int, float)) -> int { value } ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:868 doc/tutorial-ffi.md:143 msgid "# Destructors" msgstr "" #. type: Plain text #: doc/tutorial.md:872 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:876 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:878 msgid "" "The `~` sigil represents a unique handle for a memory allocation on the heap:" msgstr "" #. type: Plain text #: doc/tutorial.md:886 #, 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:890 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:892 msgid "# Ownership" msgstr "" #. type: Plain text #: doc/tutorial.md:897 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:903 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:907 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:914 #, 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:919 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:925 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:927 msgid "# Boxes" msgstr "" #. type: Plain text #: doc/tutorial.md:934 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:939 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:941 msgid "## Owned boxes" msgstr "" #. type: Plain text #: doc/tutorial.md:944 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:949 msgid "~~~~ let x = 5; // immutable let mut y = 5; // mutable y += 2;" msgstr "" #. type: Plain text #: doc/tutorial.md:954 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:959 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:962 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:968 #, no-wrap msgid "" "~~~~ {.xfail-test}\n" "struct Foo {\n" " child: Option\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:972 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:976 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:982 #, no-wrap msgid "" "~~~~\n" "struct Foo {\n" " child: Option<~Foo>\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:984 msgid "## Managed boxes" msgstr "" #. type: Plain text #: doc/tutorial.md:992 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 managed 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:995 msgid "~~~~ let a = @5; // immutable" msgstr "" #. type: Plain text #: doc/tutorial.md:998 msgid "let mut b = @5; // mutable variable, immutable box b = @10;" msgstr "" #. type: Plain text #: doc/tutorial.md:1001 msgid "let c = @mut 5; // immutable variable, mutable box *c = 10;" msgstr "" #. type: Plain text #: doc/tutorial.md:1006 msgid "" "let mut d = @mut 5; // mutable variable, mutable box *d += 5; d = @mut 15; " "~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1011 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:1015 #, no-wrap msgid "" "~~~~\n" "let a = @1; // immutable box\n" "let b = @mut 2; // mutable box\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1018 #, 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:1022 #, 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:1027 #, 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:1029 msgid "# Move semantics" msgstr "" #. type: Plain text #: doc/tutorial.md:1035 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:1041 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:1044 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:1051 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:1053 msgid "# Borrowed pointers" msgstr "" #. type: Plain text #: doc/tutorial.md:1059 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:1061 msgid "As an example, consider a simple struct type, `Point`:" msgstr "" #. type: Plain text #: doc/tutorial.md:1068 #, no-wrap msgid "" "~~~\n" "struct Point {\n" " x: float,\n" " y: float\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1072 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:1079 #, 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:1089 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 point—that is, it takes the points by value. But this " "will cause the points to be copied when we call the function. For points, " "this is probably not so bad, but often copies are expensive. So we’d like to " "define a function that takes the points by pointer. We can use borrowed " "pointers to do this:" msgstr "" #. type: Plain text #: doc/tutorial.md:1099 #, 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:1101 doc/tutorial-borrowed-ptr.md:72 msgid "Now we can call `compute_distance()` in various ways:" msgstr "" #. type: Plain text #: doc/tutorial.md:1111 #, 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:1118 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:1124 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:1133 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:1136 msgid "" "For a more in-depth explanation of borrowed pointers, read the [borrowed " "pointer tutorial][borrowtut]." msgstr "" #. type: Plain text #: doc/tutorial.md:1138 msgid "[borrowtut]: tutorial-borrowed-ptr.html" msgstr "" #. type: Plain text #: doc/tutorial.md:1140 msgid "## Freezing" msgstr "" #. type: Plain text #: doc/tutorial.md:1143 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:1152 #, 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" "# x = 3;\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1156 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:1166 #, 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:1168 msgid "# Dereferencing pointers" msgstr "" #. type: Plain text #: doc/tutorial.md:1171 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:1176 msgid "~~~ let managed = @10; let owned = ~20; let borrowed = &30;" msgstr "" #. type: Plain text #: doc/tutorial.md:1179 msgid "let sum = *managed + *owned + *borrowed; ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1183 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:1187 msgid "~~~ let managed = @mut 10; let mut owned = ~20;" msgstr "" #. type: Plain text #: doc/tutorial.md:1190 msgid "let mut value = 30; let borrowed = &mut value;" msgstr "" #. type: Plain text #: doc/tutorial.md:1195 #, no-wrap msgid "" "*managed = *owned + 10;\n" "*owned = *borrowed + 100;\n" "*borrowed = *managed + 1000;\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1199 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:1209 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:1213 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:1223 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:1227 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:1233 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:1235 msgid "The indexing operator (`[]`) also auto-dereferences." msgstr "" #. type: Plain text #: doc/tutorial.md:1237 msgid "# Vectors and strings" msgstr "" #. type: Plain text #: doc/tutorial.md:1242 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:1252 #, 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:1255 msgid "" "// A borrowed pointer to stack-allocated vector let stack_crayons: &[Crayon] " "= &[Aquamarine, Asparagus, AtomicTangerine];" msgstr "" #. type: Plain text #: doc/tutorial.md:1258 msgid "" "// A local heap (managed) vector of crayons let local_crayons: @[Crayon] = " "@[BananaMania, Beaver, Bittersweet];" msgstr "" #. type: Plain text #: doc/tutorial.md:1262 msgid "" "// An exchange heap (owned) vector of crayons let exchange_crayons: " "~[Crayon] = ~[Black, BlizzardBlue, Blue]; ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1264 msgid "The `+` operator means concatenation when applied to vector types." msgstr "" #. type: Plain text #: doc/tutorial.md:1274 #, no-wrap msgid "" "~~~~\n" "# enum Crayon { Almond, AntiqueBrass, Apricot,\n" "# Aquamarine, Asparagus, AtomicTangerine,\n" "# BananaMania, Beaver, Bittersweet };\n" "# impl Clone for Crayon {\n" "# fn clone(&self) -> Crayon {\n" "# *self\n" "# }\n" "# }\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1277 msgid "" "let my_crayons = ~[Almond, AntiqueBrass, Apricot]; let your_crayons = " "~[BananaMania, Beaver, Bittersweet];" msgstr "" #. type: Plain text #: doc/tutorial.md:1280 msgid "" "// Add two vectors to create a new one let our_crayons = my_crayons + " "your_crayons;" msgstr "" #. type: Plain text #: doc/tutorial.md:1285 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:1290 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:1292 msgid "Square brackets denote indexing into a vector:" msgstr "" #. type: Plain text #: doc/tutorial.md:1304 #, 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:1306 msgid "A vector can be destructured using pattern matching:" msgstr "" #. type: Plain text #: doc/tutorial.md:1316 #, no-wrap msgid "" "~~~~\n" "let numbers: &[int] = &[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:1320 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:1326 #, 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:1329 msgid "crayons[0] = Apricot; // ERROR: Can't assign to immutable vector ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1331 msgid "Moving it into a mutable slot makes the elements assignable." msgstr "" #. type: Plain text #: doc/tutorial.md:1337 #, 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:1340 msgid "" "// Put the vector into a mutable slot let mut mutable_crayons = crayons;" msgstr "" #. type: Plain text #: doc/tutorial.md:1344 msgid "// Now it's mutable to the bone mutable_crayons[0] = Apricot; ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1347 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:1355 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:1359 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:1362 msgid "" "// The same thing, but with the `&` let stack_crayons: &str = &\"Aquamarine, " "Asparagus, AtomicTangerine\";" msgstr "" #. type: Plain text #: doc/tutorial.md:1365 msgid "" "// A local heap (managed) string let local_crayons: @str = @\"BananaMania, " "Beaver, Bittersweet\";" msgstr "" #. type: Plain text #: doc/tutorial.md:1369 msgid "" "// An exchange heap (owned) string let exchange_crayons: ~str = ~\"Black, " "BlizzardBlue, Blue\"; ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1373 msgid "" "Both vectors and strings support a number of useful [methods](#methods), " "defined in [`std::vec`] and [`std::str`]. Here are some examples." msgstr "" #. type: Plain text #: doc/tutorial.md:1376 msgid "[`std::vec`]: std/vec.html [`std::str`]: std/str.html" msgstr "" #. type: Plain text #: doc/tutorial.md:1387 #, 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:1389 msgid "let crayons = [Almond, AntiqueBrass, Apricot];" msgstr "" #. type: Plain text #: doc/tutorial.md:1393 msgid "" "// Check the length of the vector assert!(crayons.len() == 3); assert!(!" "crayons.is_empty());" msgstr "" #. type: Plain text #: doc/tutorial.md:1400 #, no-wrap msgid "" "// Iterate over a vector, obtaining a pointer to each element\n" "// (`for` is explained in the container/iterator tutorial)\n" "for crayon in crayons.iter() {\n" " let delicious_crayon_wax = unwrap_crayon(*crayon);\n" " eat_crayon_wax(delicious_crayon_wax);\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1404 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:1407 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:1413 #, 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:1415 msgid "# Closures" msgstr "" #. type: Plain text #: doc/tutorial.md:1420 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:1423 msgid "~~~~ {.ignore} let foo = 10;" msgstr "" #. type: Plain text #: doc/tutorial.md:1428 #, no-wrap msgid "" "fn bar() -> int {\n" " return foo; // `bar` cannot refer to `foo`\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1431 msgid "" "Rust also supports _closures_, functions that can access variables in the " "enclosing scope." msgstr "" #. type: Plain text #: doc/tutorial.md:1434 msgid "~~~~ fn call_closure_with_ten(b: &fn(int)) { b(10); }" msgstr "" #. type: Plain text #: doc/tutorial.md:1437 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:1440 msgid "call_closure_with_ten(closure); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1446 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:1451 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:1455 msgid "~~~~ let square = |x: int| -> uint { (x * x) as uint }; ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1459 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:1464 msgid "~~~~ let mut max = 0; [1, 2, 3].map(|x| if *x > max { max = *x }); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1473 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:1475 msgid "## Managed closures" msgstr "" #. type: Plain text #: doc/tutorial.md:1481 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:1486 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:1489 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:1495 #, 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:1501 #, 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:1503 msgid "## Owned closures" msgstr "" #. type: Plain text #: doc/tutorial.md:1510 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:1512 msgid "## Closure compatibility" msgstr "" #. type: Plain text #: doc/tutorial.md:1519 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:1527 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:1531 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:1533 msgid "## Do syntax" msgstr "" #. type: Plain text #: doc/tutorial.md:1536 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:1539 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:1549 #, 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:1553 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:1561 #, 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:1564 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:1572 #, 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:1577 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:1582 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:1585 doc/tutorial.md:1597 msgid "~~~~ use std::task::spawn;" msgstr "" #. type: Plain text #: doc/tutorial.md:1590 #, no-wrap msgid "" "do spawn() || {\n" " debug!(\"I'm a task, whatever\");\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1594 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:1602 #, no-wrap msgid "" "do spawn {\n" " debug!(\"Kablam!\");\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1605 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:1607 msgid "# Methods" msgstr "" #. type: Plain text #: doc/tutorial.md:1613 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:1617 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:1625 #, 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:1630 #, no-wrap msgid "" "enum Shape {\n" " Circle(Point, float),\n" " Rectangle(Point, Point)\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1639 #, 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:1643 msgid "let s = Circle(Point { x: 1f, y: 2f }, 3f); s.draw(); ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1647 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:1652 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:1667 #, 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:1669 msgid "let s = Circle(Point { x: 1f, y: 2f }, 3f);" msgstr "" #. type: Plain text #: doc/tutorial.md:1675 msgid "" "(@s).draw_managed(); (~s).draw_owned(); (&s).draw_borrowed(); s." "draw_value(); ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1679 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:1697 #, 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:1700 msgid "(@s).draw_borrowed(); (~s).draw_borrowed();" msgstr "" #. type: Plain text #: doc/tutorial.md:1704 msgid "" "// Unlike typical function arguments, the self value will // automatically " "be referenced ... s.draw_borrowed();" msgstr "" #. type: Plain text #: doc/tutorial.md:1707 msgid "// ... and dereferenced (& &s).draw_borrowed();" msgstr "" #. type: Plain text #: doc/tutorial.md:1711 msgid "// ... and dereferenced and borrowed (&@~s).draw_borrowed(); ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1715 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:1722 #, 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:1724 msgid "" "To call such a method, just prefix it with the type name and a double colon:" msgstr "" #. type: Plain text #: doc/tutorial.md:1733 #, no-wrap msgid "" "~~~~\n" "use std::float::consts::pi;\n" "struct Circle { radius: float }\n" "impl Circle {\n" " fn new(area: float) -> Circle { Circle { radius: (area / pi).sqrt() } }\n" "}\n" "let c = Circle::new(42.5);\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1735 msgid "# Generics" msgstr "" #. type: Plain text #: doc/tutorial.md:1743 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:1753 #, no-wrap msgid "" "~~~~\n" "fn map(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] {\n" " let mut accumulator = ~[];\n" " for element in vector.iter() {\n" " accumulator.push(function(element));\n" " }\n" " return accumulator;\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1758 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:1768 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:1770 msgid "" "Generic `type`, `struct`, and `enum` declarations follow the same pattern:" msgstr "" #. type: Plain text #: doc/tutorial.md:1774 msgid "~~~~ use std::hashmap::HashMap; type Set = HashMap;" msgstr "" #. type: Plain text #: doc/tutorial.md:1778 #, no-wrap msgid "" "struct Stack {\n" " elements: ~[T]\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1784 #, no-wrap msgid "" "enum Option {\n" " Some(T),\n" " None\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1787 msgid "" "These declarations can be instantiated to valid types like `Set`, " "`Stack`, and `Option`." msgstr "" #. type: Plain text #: doc/tutorial.md:1793 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:1804 #, 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:1812 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:1814 msgid "## Traits" msgstr "" #. type: Plain text #: doc/tutorial.md:1824 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:1832 msgid "" "As motivation, let us consider copying in Rust. The `clone` method 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 destructors cannot be copied unless you " "explicitly implement `Clone` for them." msgstr "" #. type: Plain text #: doc/tutorial.md:1837 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:1844 #, 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:1851 msgid "" "However, we can tell the compiler that the `head` function is only for " "copyable types: that is, those that implement the `Clone` trait. In that " "case, we can explicitly create a second copy of the value we are returning " "using the `clone` keyword:" msgstr "" #. type: Plain text #: doc/tutorial.md:1858 #, no-wrap msgid "" "~~~~\n" "// This does\n" "fn head(v: &[T]) -> T {\n" " v[0].clone()\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1866 msgid "" "This says that we can call `head` on any type `T` as long as that type " "implements the `Clone` 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 that does not implement `Clone`." msgstr "" #. type: Plain text #: doc/tutorial.md:1871 msgid "" "While most traits can be defined and implemented by user code, two traits " "are automatically derived and implemented for all applicable types by the " "compiler, and may not be overridden:" msgstr "" #. type: Plain text #: doc/tutorial.md:1875 #, no-wrap msgid "" "* `Send` - Sendable types.\n" "Types are sendable\n" "unless they contain managed boxes, managed closures, or borrowed pointers.\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1880 #, no-wrap msgid "" "* `Freeze` - Constant (immutable) types.\n" "These are types that do not contain anything intrinsically mutable.\n" "Intrinsically mutable values include `@mut`\n" "and `Cell` in the standard library.\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1883 msgid "" "> ***Note:*** These two traits were referred to as 'kinds' in earlier > " "iterations of the language, and often still are." msgstr "" #. type: Plain text #: doc/tutorial.md:1889 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:1894 #, no-wrap msgid "" "~~~\n" "struct TimeBomb {\n" " explosivity: uint\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1903 #, no-wrap msgid "" "impl Drop for TimeBomb {\n" " fn drop(&self) {\n" " for _ in range(0, self.explosivity) {\n" " println(\"blam!\");\n" " }\n" " }\n" "}\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1906 msgid "" "It is illegal to call `drop` directly. Only code inserted by the compiler " "may call it." msgstr "" #. type: Plain text #: doc/tutorial.md:1908 msgid "## Declaring and implementing traits" msgstr "" #. type: Plain text #: doc/tutorial.md:1914 msgid "" "A trait consists of a set of methods without bodies, or may be empty, as is " "the case with `Send` and `Freeze`. 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:1920 #, no-wrap msgid "" "~~~~\n" "trait Printable {\n" " fn print(&self);\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1925 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:1927 msgid "[impls]: #methods" msgstr "" #. type: Plain text #: doc/tutorial.md:1933 #, 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:1937 #, no-wrap msgid "" "impl Printable for ~str {\n" " fn print(&self) { println(*self) }\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1941 msgid "# 1.print(); # (~\"foo\").print(); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:1946 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:1951 #, no-wrap msgid "" "~~~~\n" "trait Seq {\n" " fn length(&self) -> uint;\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1956 #, no-wrap msgid "" "impl Seq for ~[T] {\n" " fn length(&self) -> uint { self.len() }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:1963 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:1968 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:1973 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:1980 #, 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:1986 #, 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:1991 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:1996 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:2002 msgid "" "~~~~ use std::float::consts::pi; trait Shape { fn new(area: float) -> " "Self; } struct Circle { radius: float } struct Square { length: float }" msgstr "" #. type: Plain text #: doc/tutorial.md:2009 #, no-wrap msgid "" "impl Shape for Circle {\n" " fn new(area: float) -> Circle { Circle { radius: (area / pi).sqrt() } }\n" "}\n" "impl Shape for Square {\n" " fn new(area: float) -> Square { Square { length: (area).sqrt() } }\n" "}\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2014 msgid "" "let area = 42.5; let c: Circle = Shape::new(area); let s: Square = Shape::" "new(area); ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2016 msgid "## Bounded type parameters and static method dispatch" msgstr "" #. type: Plain text #: doc/tutorial.md:2021 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:2030 #, no-wrap msgid "" "~~~~\n" "# trait Printable { fn print(&self); }\n" "fn print_all(printable_things: ~[T]) {\n" " for thing in printable_things.iter() {\n" " thing.print();\n" " }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2036 msgid "" "Declaring `T` as conforming to the `Printable` trait (as we earlier did with " "`Clone`) makes it possible to call methods from that trait on values of type " "`T` inside the function. It will also cause a compile-time error when anyone " "tries to call `print_all` on an array whose element type does not have a " "`Printable` implementation." msgstr "" #. type: Plain text #: doc/tutorial.md:2039 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:2051 #, 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 = printable_things[i].clone();\n" " copy_of_thing.print();\n" " i += 1;\n" " }\n" "}\n" "~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2055 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:2057 msgid "This usage of traits is similar to Haskell type classes." msgstr "" #. type: Plain text #: doc/tutorial.md:2059 msgid "## Trait objects and dynamic method dispatch" msgstr "" #. type: Plain text #: doc/tutorial.md:2063 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:2069 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:2076 #, no-wrap msgid "" "fn draw_all(shapes: ~[T]) {\n" " for shape in shapes.iter() { shape.draw(); }\n" "}\n" "# let c: Circle = new_circle();\n" "# draw_all(~[c]);\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2082 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:2089 #, no-wrap msgid "" "~~~~\n" "# trait Drawable { fn draw(&self); }\n" "fn draw_all(shapes: &[@Drawable]) {\n" " for shape in shapes.iter() { shape.draw(); }\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2094 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:2101 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:2104 msgid "" "impl Drawable for Circle { fn draw(&self) { ... } } impl Drawable for " "Rectangle { fn draw(&self) { ... } }" msgstr "" #. type: Plain text #: doc/tutorial.md:2109 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:2117 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:2131 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:2136 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:2138 msgid "This usage of traits is similar to Java interfaces." msgstr "" #. type: Plain text #: doc/tutorial.md:2140 msgid "## Trait inheritance" msgstr "" #. type: Plain text #: doc/tutorial.md:2145 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:2150 msgid "" "~~~~ trait Shape { fn area(&self) -> float; } trait Circle : Shape { fn " "radius(&self) -> float; } ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2152 msgid "" "Now, we can implement `Circle` on a type only if we also implement `Shape`." msgstr "" #. type: Plain text #: doc/tutorial.md:2167 #, no-wrap msgid "" "~~~~\n" "use std::float::consts::pi;\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 { (self.area() / pi).sqrt() }\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:2172 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:2196 msgid "" "~~~ {.xfail-test} use std::float::consts::pi; # 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 { (self." "area() / pi).sqrt() } } # impl Shape for CircleStruct { fn area(&self) -> " "float { pi * square(self.radius) } }" msgstr "" #. type: Plain text #: doc/tutorial.md:2201 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:2203 msgid "> ***Note:*** Trait inheritance does not actually work with objects yet" msgstr "" #. type: Plain text #: doc/tutorial.md:2205 msgid "## Deriving implementations for traits" msgstr "" #. type: Plain text #: doc/tutorial.md:2212 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:2216 msgid "~~~ #[deriving(Eq)] struct Circle { radius: float }" msgstr "" #. type: Plain text #: doc/tutorial.md:2220 msgid "#[deriving(Rand, ToStr)] enum ABC { A, B, C } ~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2224 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:2226 msgid "# Modules and crates" msgstr "" #. type: Plain text #: doc/tutorial.md:2230 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:2236 #, 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:2241 #, no-wrap msgid "" "fn main() {\n" " println(farm::chicken());\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2246 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:2252 msgid "" "~~~ # mod farm { pub fn chicken() { } } # fn main() { // Bring `chicken` " "into scope use farm::chicken;" msgstr "" #. type: Plain text #: doc/tutorial.md:2262 #, 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:2269 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:2276 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:2289 #, 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:2295 #, no-wrap msgid "" " impl Farm {\n" " fn feed_chickens(&self) { ... }\n" " fn feed_cows(&self) { ... }\n" " pub fn add_chicken(&self, c: Chicken) { ... }\n" " }\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2301 #, 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:2311 #, 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:2313 msgid "## Crates" msgstr "" #. type: Plain text #: doc/tutorial.md:2317 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:2322 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:2327 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:2336 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:2340 msgid "" "~~~~ { .xfail-test } // Crate linkage metadata #[link(name = \"farm\", vers " "= \"2.5\", author = \"mjh\")];" msgstr "" #. type: Plain text #: doc/tutorial.md:2343 msgid "// Make a library (\"bin\" is the default) #[crate_type = \"lib\"];" msgstr "" #. type: Plain text #: doc/tutorial.md:2346 msgid "// Turn on a warning #[warn(non_camel_case_types)]" msgstr "" #. type: Plain text #: doc/tutorial.md:2349 msgid "// Link to the standard library extern mod std;" msgstr "" #. type: Plain text #: doc/tutorial.md:2354 msgid "// Load some modules from other files mod cow; mod chicken; mod horse;" msgstr "" #. type: Plain text #: doc/tutorial.md:2359 #, no-wrap msgid "" "fn main() {\n" " ...\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2366 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:2370 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:2373 msgid "" "To have a nested directory structure for your source files, you can nest " "mods:" msgstr "" #. type: Plain text #: doc/tutorial.md:2380 #, no-wrap msgid "" "~~~~ {.ignore}\n" "mod poultry {\n" " mod chicken;\n" " mod turkey;\n" "}\n" "~~~~\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2385 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:2387 msgid "## Using other crates" msgstr "" #. type: Plain text #: doc/tutorial.md:2395 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:2397 msgid "For example, `extern mod std` links the [standard library]." msgstr "" #. type: Plain text #: doc/tutorial.md:2399 msgid "[standard library]: std/index.html" msgstr "" #. type: Plain text #: doc/tutorial.md:2406 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:2408 msgid "Our example crate declared this set of `link` attributes:" msgstr "" #. type: Plain text #: doc/tutorial.md:2412 msgid "~~~~ #[link(name = \"farm\", vers = \"2.5\", author = \"mjh\")]; ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2414 msgid "Which you can then link with any (or all) of the following:" msgstr "" #. type: Plain text #: doc/tutorial.md:2420 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:2423 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:2425 msgid "## A minimal example" msgstr "" #. type: Plain text #: doc/tutorial.md:2428 msgid "" "Now for something that you can actually compile yourself, we have these two " "files:" msgstr "" #. type: Plain text #: doc/tutorial.md:2434 msgid "" "~~~~ // world.rs #[link(name = \"world\", vers = \"1.0\")]; pub fn explore() " "-> &str { \"world\" } ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2440 msgid "" "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello " "\" + world::explore()); } ~~~~" msgstr "" #. type: Plain text #: doc/tutorial.md:2442 msgid "Now compile and run like this (adjust to your platform if necessary):" msgstr "" #. type: Plain text #: doc/tutorial.md:2449 #, 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:2454 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:2456 msgid "## The standard library" msgstr "" #. type: Plain text #: doc/tutorial.md:2461 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:2472 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:2474 msgid "### Standard Library injection and the Rust prelude" msgstr "" #. type: Plain text #: doc/tutorial.md:2477 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:2479 #, no-wrap msgid " extern mod std;\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2483 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:2488 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:2490 #, no-wrap msgid " use std::prelude::*;\n" msgstr "" #. type: Plain text #: doc/tutorial.md:2516 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:2518 msgid "# What next?" msgstr "" #. type: Plain text #: doc/tutorial.md:2521 msgid "" "Now that you know the essentials, check out any of the additional tutorials " "on individual topics." msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:2527 msgid "[Borrowed pointers][borrow]" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:2527 msgid "[Tasks and communication][tasks]" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:2527 msgid "[Macros][macros]" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:2527 msgid "[The foreign function interface][ffi]" msgstr "" #. type: Bullet: '* ' #: doc/tutorial.md:2527 msgid "[Containers and iterators](tutorial-container.html)" msgstr "" #. type: Plain text #: doc/tutorial.md:2529 msgid "There is further documentation on the [wiki]." msgstr "" #. type: Plain text #: doc/tutorial.md:2534 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:2536 msgid "[wiki]: https://github.com/mozilla/rust/wiki/Docs" msgstr ""