rust/doc/po/tutorial.md.pot

4392 lines
121 KiB
Plaintext
Raw Normal View History

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