From 27740af310292f87b3e079643bfc848baa25bd92 Mon Sep 17 00:00:00 2001 From: dalance Date: Thu, 6 Jun 2024 15:51:16 +0900 Subject: [PATCH 1/2] Add translation support --- .github/workflows/main.yml | 24 +- .gitignore | 1 + README.md | 21 ++ TRANSLATING.md | 98 ++++++++ book.toml | 8 +- theme/{ => css}/2018-edition.css | 0 theme/css/language-picker.css | 13 + theme/{ => css}/listing.css | 0 theme/{ => css}/semantic-notes.css | 0 theme/index.hbs | 388 +++++++++++++++++++++++++++++ 10 files changed, 550 insertions(+), 3 deletions(-) create mode 100644 TRANSLATING.md rename theme/{ => css}/2018-edition.css (100%) create mode 100644 theme/css/language-picker.css rename theme/{ => css}/listing.css (100%) rename theme/{ => css}/semantic-notes.css (100%) create mode 100644 theme/index.hbs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1737bce009..b460baa601 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,10 @@ name: CI on: [push, pull_request] +env: + # Update the language picker in index.hbs to link new languages. + LANGUAGES: + jobs: test: name: Run tests @@ -17,7 +21,7 @@ jobs: - name: Install mdbook run: | mkdir bin - curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.21/mdbook-v0.4.21-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.37/mdbook-v0.4.37-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin echo "$(pwd)/bin" >> "${GITHUB_PATH}" - name: Report versions run: | @@ -64,8 +68,10 @@ jobs: - name: Install mdbook run: | mkdir bin - curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.21/mdbook-v0.4.21-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin + curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.37/mdbook-v0.4.37-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin echo "$(pwd)/bin" >> "${GITHUB_PATH}" + - name: Install mdbook-i18n-helpers + run: cargo install mdbook-i18n-helpers --locked --version 0.3.3 - name: Install mdbook-trpl-note run: cargo install --path packages/mdbook-trpl-note - name: Install mdbook-trpl-listing @@ -97,3 +103,17 @@ jobs: https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh # Cannot use --all here because of the generated redirect pages aren't available. sh linkcheck.sh book + - name: Build all translations + run: | + for po_lang in ${{ env.LANGUAGES }}; do + echo "::group::Building $po_lang translation" + MDBOOK_BOOK__LANGUAGE=$po_lang \ + mdbook build -d book/$po_lang + echo "::endgroup::" + done + - name: Check all translations for broken links + run: | + for po_lang in ${{ env.LANGUAGES }}; do + MDBOOK_BOOK__LANGUAGE=$po_lang \ + sh linkcheck.sh --all rust-by-example + done diff --git a/.gitignore b/.gitignore index 17127d1142..2cbfc24112 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,6 @@ book/ .DS_Store target tmp +po/messages.pot .nova diff --git a/README.md b/README.md index 8befc1b31e..3be0610240 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,21 @@ To run the tests: $ mdbook test ``` +The following warnings can be ignored safely if you don't build a translated version. + +``` +[WARN] (mdbook::preprocess::cmd): The command wasn't found, is the "gettext" preprocessor installed? +[WARN] (mdbook::preprocess::cmd): Command: mdbook-gettext +``` + +### Building translated version + +If there is a translated resource in `po/` directory, it can be specified through `MDBOOK_BOOK__LANGUAGE` like below: + +```bash +MDBOOK_BOOK__LANGUAGE=ja mdbook build +``` + ## Contributing We'd love your help! Please see [CONTRIBUTING.md][contrib] to learn about the @@ -85,6 +100,12 @@ isn't strictly fixing an error, it might sit until the next time that we're working on a large revision: expect on the order of months or years. Thank you for your patience! +## Translating + +Please see the [TRANSLATING.md] file for more details. + +[TRANSLATING.md]: https://github.com/rust-lang/book/blob/main/TRANSLATING.md + ### Translations We'd love help translating the book! See the [Translations] label to join in diff --git a/TRANSLATING.md b/TRANSLATING.md new file mode 100644 index 0000000000..bf1c2969da --- /dev/null +++ b/TRANSLATING.md @@ -0,0 +1,98 @@ +# Translation guidelines + +Please see the [CONTRIBUTING.md] file for general contribution guidelines. +This file describes about the translation workflow. + +[CONTRIBUTING.md]: https://github.com/rust-lang/book/blob/main/CONTRIBUTING.md + +## Translation workflow + +### Preparation + +The book uses [mdbook-i18n-helpers](https://github.com/google/mdbook-i18n-helpers) as a translation framework. +The following tools are required. + +* GNU gettext utilities ( `msgmerge` and `msgcat` ) +* mdbook-i18n-helpers ( `cargo install mdbook-i18n-helpers` ) + +### Creating and Updating Translations + +Please see the [mdbook-i18n-helpers USAGE](https://github.com/google/mdbook-i18n-helpers/blob/main/i18n-helpers/USAGE.md) file for the detailed usage of mdbook-i18n-helpers. +The summarized command list is below: + +#### Generating a message template + +The generated message templete `po/messages.pot` is required to create or update translations. + +```bash +MDBOOK_OUTPUT='{"xgettext": {"pot-file": "messages.pot"}}' \ + mdbook build -d po +``` + +#### Creating a new translation resource + +`xx` is [ISO 639](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language code. + +```bash +msginit -i po/messages.pot -l xx -o po/xx.po +``` + +#### Updating the exising translation resource + +```bash +msgmerge --update po/xx.po po/messages.pot +``` + +### Editing translation resources + +After generating a translation resource `po/xx.po`, you can write translation messages in `msgstr` entry of `po/xx.po`. +To build a translated book, the following command can be used. + +```bash +MDBOOK_BOOK__LANGUAGE=xx mdbook build +MDBOOK_BOOK__LANGUAGE=xx mdbook serve +``` + +### Add a language entry + +Please add a language entry in `.github/workflows/main.yml`, `theme/index.hbs`, and `src/bootstrap/src/core/build_steps/doc.rs` in [rust-lang/rust](https://github.com/rust-lang/rust) like below: + +* `main.yml` + +```yml +env: + # Update the language picker in index.hbs to link new languages. + LANGUAGES: xx yy zz +``` + +* `index.hbs` + +```html + +``` + +* `src/bootstrap/src/core/build_steps/doc.rs` in [rust-lang/rust](https://github.com/rust-lang/rust) + +```rust +// build book +builder.ensure(RustbookSrc { + target, + name: "book".to_owned(), + src: absolute_path.clone(), + parent: Some(self), + languages: vec!["xx", "yy", "zz"], +}); +``` diff --git a/book.toml b/book.toml index 800adcf0f5..158b699687 100644 --- a/book.toml +++ b/book.toml @@ -6,7 +6,7 @@ title = "The Rust Programming Language" authors = ["Steve Klabnik", "Carol Nichols", "Contributions from the Rust Community"] [output.html] -additional-css = ["ferris.css", "theme/2018-edition.css", "theme/semantic-notes.css", "theme/listing.css"] +additional-css = ["ferris.css", "theme/css/2018-edition.css", "theme/css/semantic-notes.css", "theme/css/listing.css", "theme/css/language-picker.css"] additional-js = ["ferris.js"] git-repository-url = "https://github.com/rust-lang/book" @@ -18,3 +18,9 @@ output-mode = "default" [rust] edition = "2021" + +[build] +extra-watch-dirs = ["po"] + +[preprocessor.gettext] +after = ["links"] diff --git a/theme/2018-edition.css b/theme/css/2018-edition.css similarity index 100% rename from theme/2018-edition.css rename to theme/css/2018-edition.css diff --git a/theme/css/language-picker.css b/theme/css/language-picker.css new file mode 100644 index 0000000000..1553ed68fe --- /dev/null +++ b/theme/css/language-picker.css @@ -0,0 +1,13 @@ +#language-list { + left: auto; + right: 10px; +} + +[dir="rtl"] #language-list { + left: 10px; + right: auto; +} + +#language-list a { + color: inherit; +} diff --git a/theme/listing.css b/theme/css/listing.css similarity index 100% rename from theme/listing.css rename to theme/css/listing.css diff --git a/theme/semantic-notes.css b/theme/css/semantic-notes.css similarity index 100% rename from theme/semantic-notes.css rename to theme/css/semantic-notes.css diff --git a/theme/index.hbs b/theme/index.hbs new file mode 100644 index 0000000000..bae3ea4b61 --- /dev/null +++ b/theme/index.hbs @@ -0,0 +1,388 @@ + + + + + + {{ title }} + {{#if is_print }} + + {{/if}} + {{#if base_url}} + + {{/if}} + + + + {{> head}} + + + + + + {{#if favicon_svg}} + + {{/if}} + {{#if favicon_png}} + + {{/if}} + + + + {{#if print_enable}} + + {{/if}} + + + + {{#if copy_fonts}} + + {{/if}} + + + + + + + + {{#each additional_css}} + + {{/each}} + + {{#if mathjax_support}} + + + {{/if}} + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ {{> header}} + + + + {{#if search_enabled}} + + {{/if}} + + + + +
+
+ {{{ content }}} +
+ + +
+
+ + + +
+ + {{#if live_reload_endpoint}} + + + {{/if}} + + {{#if google_analytics}} + + + {{/if}} + + {{#if playground_line_numbers}} + + {{/if}} + + {{#if playground_copyable}} + + {{/if}} + + {{#if playground_js}} + + + + + + {{/if}} + + {{#if search_js}} + + + + {{/if}} + + + + + + + {{#each additional_js}} + + {{/each}} + + {{#if is_print}} + {{#if mathjax_support}} + + {{else}} + + {{/if}} + {{/if}} + +
+ + From bb5fdddd2bd28b2020d8f0a3558f7789776867c9 Mon Sep 17 00:00:00 2001 From: dalance Date: Wed, 2 Oct 2024 09:29:52 +0900 Subject: [PATCH 2/2] Add Japanese translation --- po/ja.po | 36512 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 36512 insertions(+) create mode 100644 po/ja.po diff --git a/po/ja.po b/po/ja.po new file mode 100644 index 0000000000..c8953d609e --- /dev/null +++ b/po/ja.po @@ -0,0 +1,36512 @@ +msgid "" +msgstr "" +"Project-Id-Version: The Rust Programming Language\n" +"POT-Creation-Date: 2024-10-02T09:25:03+09:00\n" +"PO-Revision-Date: 2024-06-06 09:50+0900\n" +"Last-Translator: Naoya Hatta \n" +"Language-Team: Japanese\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/SUMMARY.md:1 src/SUMMARY.md:3 src/title-page.md:1 +msgid "The Rust Programming Language" +msgstr "The Rust Programming Language 日本語版" + +#: src/SUMMARY.md:4 src/foreword.md:1 +msgid "Foreword" +msgstr "" + +#: src/SUMMARY.md:5 src/ch00-00-introduction.md:1 +msgid "Introduction" +msgstr "" + +#: src/SUMMARY.md:7 +msgid "Getting started" +msgstr "" + +#: src/SUMMARY.md:9 src/ch01-00-getting-started.md:1 +msgid "Getting Started" +msgstr "" + +#: src/SUMMARY.md:10 src/ch01-01-installation.md:1 +msgid "Installation" +msgstr "" + +#: src/SUMMARY.md:11 src/ch01-02-hello-world.md:1 +msgid "Hello, World!" +msgstr "" + +#: src/SUMMARY.md:12 src/ch01-03-hello-cargo.md:1 +msgid "Hello, Cargo!" +msgstr "" + +#: src/SUMMARY.md:14 src/ch02-00-guessing-game-tutorial.md:1 +msgid "Programming a Guessing Game" +msgstr "" + +#: src/SUMMARY.md:16 src/ch03-00-common-programming-concepts.md:1 +msgid "Common Programming Concepts" +msgstr "" + +#: src/SUMMARY.md:17 src/ch03-01-variables-and-mutability.md:1 +msgid "Variables and Mutability" +msgstr "" + +#: src/SUMMARY.md:18 src/ch03-02-data-types.md:1 +msgid "Data Types" +msgstr "" + +#: src/SUMMARY.md:19 src/ch03-03-how-functions-work.md:1 +msgid "Functions" +msgstr "" + +#: src/SUMMARY.md:20 src/ch03-04-comments.md:1 +msgid "Comments" +msgstr "" + +#: src/SUMMARY.md:21 src/ch03-05-control-flow.md:1 +msgid "Control Flow" +msgstr "" + +#: src/SUMMARY.md:23 src/ch04-00-understanding-ownership.md:1 +msgid "Understanding Ownership" +msgstr "" + +#: src/SUMMARY.md:24 +msgid "What is Ownership?" +msgstr "" + +#: src/SUMMARY.md:25 src/ch04-02-references-and-borrowing.md:1 +msgid "References and Borrowing" +msgstr "" + +#: src/SUMMARY.md:26 src/ch04-03-slices.md:1 +msgid "The Slice Type" +msgstr "" + +#: src/SUMMARY.md:28 src/ch05-00-structs.md:1 +msgid "Using Structs to Structure Related Data" +msgstr "" + +#: src/SUMMARY.md:29 src/ch05-01-defining-structs.md:1 +msgid "Defining and Instantiating Structs" +msgstr "" + +#: src/SUMMARY.md:30 src/ch05-02-example-structs.md:1 +msgid "An Example Program Using Structs" +msgstr "" + +#: src/SUMMARY.md:31 src/ch05-03-method-syntax.md:1 +msgid "Method Syntax" +msgstr "" + +#: src/SUMMARY.md:33 src/ch06-00-enums.md:1 +msgid "Enums and Pattern Matching" +msgstr "" + +#: src/SUMMARY.md:34 src/ch06-01-defining-an-enum.md:1 +msgid "Defining an Enum" +msgstr "" + +#: src/SUMMARY.md:35 src/ch06-02-match.md:3 +msgid "The `match` Control Flow Construct" +msgstr "" + +#: src/SUMMARY.md:36 src/ch06-03-if-let.md:1 +msgid "Concise Control Flow with `if let`" +msgstr "" + +#: src/SUMMARY.md:38 +msgid "Basic Rust Literacy" +msgstr "" + +#: src/SUMMARY.md:40 +#: src/ch07-00-managing-growing-projects-with-packages-crates-and-modules.md:1 +msgid "Managing Growing Projects with Packages, Crates, and Modules" +msgstr "" + +#: src/SUMMARY.md:41 src/ch07-01-packages-and-crates.md:1 +msgid "Packages and Crates" +msgstr "" + +#: src/SUMMARY.md:42 +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:1 +msgid "Defining Modules to Control Scope and Privacy" +msgstr "" + +#: src/SUMMARY.md:43 +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:1 +msgid "Paths for Referring to an Item in the Module Tree" +msgstr "" + +#: src/SUMMARY.md:44 +msgid "Bringing Paths Into Scope with the `use` Keyword" +msgstr "" + +#: src/SUMMARY.md:45 src/ch07-05-separating-modules-into-different-files.md:1 +msgid "Separating Modules into Different Files" +msgstr "" + +#: src/SUMMARY.md:47 src/ch08-00-common-collections.md:1 +msgid "Common Collections" +msgstr "" + +#: src/SUMMARY.md:48 src/ch08-01-vectors.md:1 +msgid "Storing Lists of Values with Vectors" +msgstr "" + +#: src/SUMMARY.md:49 src/ch08-02-strings.md:1 +msgid "Storing UTF-8 Encoded Text with Strings" +msgstr "" + +#: src/SUMMARY.md:50 src/ch08-03-hash-maps.md:1 +msgid "Storing Keys with Associated Values in Hash Maps" +msgstr "" + +#: src/SUMMARY.md:52 src/ch09-00-error-handling.md:1 +msgid "Error Handling" +msgstr "" + +#: src/SUMMARY.md:53 src/ch09-01-unrecoverable-errors-with-panic.md:1 +msgid "Unrecoverable Errors with `panic!`" +msgstr "" + +#: src/SUMMARY.md:54 src/ch09-02-recoverable-errors-with-result.md:1 +msgid "Recoverable Errors with `Result`" +msgstr "" + +#: src/SUMMARY.md:55 src/ch09-03-to-panic-or-not-to-panic.md:1 +msgid "To `panic!` or Not to `panic!`" +msgstr "" + +#: src/SUMMARY.md:57 src/ch10-00-generics.md:1 +msgid "Generic Types, Traits, and Lifetimes" +msgstr "" + +#: src/SUMMARY.md:58 src/ch10-01-syntax.md:1 +msgid "Generic Data Types" +msgstr "" + +#: src/SUMMARY.md:59 src/ch10-02-traits.md:1 +msgid "Traits: Defining Shared Behavior" +msgstr "" + +#: src/SUMMARY.md:60 src/ch10-03-lifetime-syntax.md:1 +msgid "Validating References with Lifetimes" +msgstr "" + +#: src/SUMMARY.md:62 src/ch11-00-testing.md:1 +msgid "Writing Automated Tests" +msgstr "" + +#: src/SUMMARY.md:63 src/ch11-01-writing-tests.md:1 +msgid "How to Write Tests" +msgstr "" + +#: src/SUMMARY.md:64 src/ch11-02-running-tests.md:1 +msgid "Controlling How Tests Are Run" +msgstr "" + +#: src/SUMMARY.md:65 src/ch11-03-test-organization.md:1 +msgid "Test Organization" +msgstr "" + +#: src/SUMMARY.md:67 src/ch12-00-an-io-project.md:1 +msgid "An I/O Project: Building a Command Line Program" +msgstr "" + +#: src/SUMMARY.md:68 src/ch12-01-accepting-command-line-arguments.md:1 +msgid "Accepting Command Line Arguments" +msgstr "" + +#: src/SUMMARY.md:69 src/ch12-02-reading-a-file.md:1 +msgid "Reading a File" +msgstr "" + +#: src/SUMMARY.md:70 src/ch12-03-improving-error-handling-and-modularity.md:1 +msgid "Refactoring to Improve Modularity and Error Handling" +msgstr "" + +#: src/SUMMARY.md:71 +msgid "Developing the Library’s Functionality with Test Driven Development" +msgstr "" + +#: src/SUMMARY.md:72 src/ch12-05-working-with-environment-variables.md:1 +msgid "Working with Environment Variables" +msgstr "" + +#: src/SUMMARY.md:73 src/ch12-06-writing-to-stderr-instead-of-stdout.md:1 +msgid "Writing Error Messages to Standard Error Instead of Standard Output" +msgstr "" + +#: src/SUMMARY.md:75 +msgid "Thinking in Rust" +msgstr "" + +#: src/SUMMARY.md:77 src/ch13-00-functional-features.md:1 +msgid "Functional Language Features: Iterators and Closures" +msgstr "" + +#: src/SUMMARY.md:78 src/ch13-01-closures.md:4 +msgid "Closures: Anonymous Functions that Capture Their Environment" +msgstr "" + +#: src/SUMMARY.md:79 src/ch13-02-iterators.md:1 +msgid "Processing a Series of Items with Iterators" +msgstr "" + +#: src/SUMMARY.md:80 src/ch13-03-improving-our-io-project.md:1 +msgid "Improving Our I/O Project" +msgstr "" + +#: src/SUMMARY.md:81 src/ch13-04-performance.md:1 +msgid "Comparing Performance: Loops vs. Iterators" +msgstr "" + +#: src/SUMMARY.md:83 +msgid "More about Cargo and Crates.io" +msgstr "" + +#: src/SUMMARY.md:84 src/ch14-01-release-profiles.md:1 +msgid "Customizing Builds with Release Profiles" +msgstr "" + +#: src/SUMMARY.md:85 src/ch14-02-publishing-to-crates-io.md:1 +msgid "Publishing a Crate to Crates.io" +msgstr "" + +#: src/SUMMARY.md:86 src/ch14-03-cargo-workspaces.md:1 +msgid "Cargo Workspaces" +msgstr "" + +#: src/SUMMARY.md:87 +msgid "Installing Binaries from Crates.io with `cargo install`" +msgstr "" + +#: src/SUMMARY.md:88 src/ch14-05-extending-cargo.md:1 +msgid "Extending Cargo with Custom Commands" +msgstr "" + +#: src/SUMMARY.md:90 src/ch15-00-smart-pointers.md:1 +msgid "Smart Pointers" +msgstr "" + +#: src/SUMMARY.md:91 src/ch15-01-box.md:1 +msgid "Using `Box` to Point to Data on the Heap" +msgstr "" + +#: src/SUMMARY.md:92 src/ch15-02-deref.md:1 +msgid "Treating Smart Pointers Like Regular References with the `Deref` Trait" +msgstr "" + +#: src/SUMMARY.md:93 src/ch15-03-drop.md:1 +msgid "Running Code on Cleanup with the `Drop` Trait" +msgstr "" + +#: src/SUMMARY.md:94 src/ch15-04-rc.md:1 +msgid "`Rc`, the Reference Counted Smart Pointer" +msgstr "" + +#: src/SUMMARY.md:95 src/ch15-05-interior-mutability.md:1 +msgid "`RefCell` and the Interior Mutability Pattern" +msgstr "" + +#: src/SUMMARY.md:96 src/ch15-06-reference-cycles.md:1 +msgid "Reference Cycles Can Leak Memory" +msgstr "" + +#: src/SUMMARY.md:98 src/ch16-00-concurrency.md:1 +msgid "Fearless Concurrency" +msgstr "" + +#: src/SUMMARY.md:99 src/ch16-01-threads.md:1 +msgid "Using Threads to Run Code Simultaneously" +msgstr "" + +#: src/SUMMARY.md:100 src/ch16-02-message-passing.md:1 +msgid "Using Message Passing to Transfer Data Between Threads" +msgstr "" + +#: src/SUMMARY.md:101 src/ch16-03-shared-state.md:1 +msgid "Shared-State Concurrency" +msgstr "" + +#: src/SUMMARY.md:102 src/ch16-04-extensible-concurrency-sync-and-send.md:1 +msgid "Extensible Concurrency with the `Sync` and `Send` Traits" +msgstr "" + +#: src/SUMMARY.md:104 +msgid "Object Oriented Programming Features of Rust" +msgstr "" + +#: src/SUMMARY.md:105 src/ch17-01-what-is-oo.md:1 +msgid "Characteristics of Object-Oriented Languages" +msgstr "" + +#: src/SUMMARY.md:106 src/ch17-02-trait-objects.md:1 +msgid "Using Trait Objects That Allow for Values of Different Types" +msgstr "" + +#: src/SUMMARY.md:107 src/ch17-03-oo-design-patterns.md:1 +msgid "Implementing an Object-Oriented Design Pattern" +msgstr "" + +#: src/SUMMARY.md:109 +msgid "Advanced Topics" +msgstr "" + +#: src/SUMMARY.md:111 src/ch18-00-patterns.md:1 +msgid "Patterns and Matching" +msgstr "" + +#: src/SUMMARY.md:112 src/ch18-01-all-the-places-for-patterns.md:1 +msgid "All the Places Patterns Can Be Used" +msgstr "" + +#: src/SUMMARY.md:113 src/ch18-02-refutability.md:1 +msgid "Refutability: Whether a Pattern Might Fail to Match" +msgstr "" + +#: src/SUMMARY.md:114 src/ch18-03-pattern-syntax.md:1 +msgid "Pattern Syntax" +msgstr "" + +#: src/SUMMARY.md:116 src/ch19-00-advanced-features.md:1 +msgid "Advanced Features" +msgstr "" + +#: src/SUMMARY.md:117 src/ch19-01-unsafe-rust.md:1 +msgid "Unsafe Rust" +msgstr "" + +#: src/SUMMARY.md:118 src/ch19-03-advanced-traits.md:1 +msgid "Advanced Traits" +msgstr "" + +#: src/SUMMARY.md:119 src/ch19-04-advanced-types.md:1 +msgid "Advanced Types" +msgstr "" + +#: src/SUMMARY.md:120 src/ch19-05-advanced-functions-and-closures.md:1 +msgid "Advanced Functions and Closures" +msgstr "" + +#: src/SUMMARY.md:121 src/ch19-06-macros.md:1 +msgid "Macros" +msgstr "" + +#: src/SUMMARY.md:123 src/ch20-00-final-project-a-web-server.md:1 +msgid "Final Project: Building a Multithreaded Web Server" +msgstr "" + +#: src/SUMMARY.md:124 src/ch20-01-single-threaded.md:1 +msgid "Building a Single-Threaded Web Server" +msgstr "" + +#: src/SUMMARY.md:125 src/ch20-02-multithreaded.md:1 +msgid "Turning Our Single-Threaded Server into a Multithreaded Server" +msgstr "" + +#: src/SUMMARY.md:126 src/ch20-03-graceful-shutdown-and-cleanup.md:1 +msgid "Graceful Shutdown and Cleanup" +msgstr "" + +#: src/SUMMARY.md:128 src/appendix-00.md:1 +msgid "Appendix" +msgstr "" + +#: src/SUMMARY.md:129 +msgid "A - Keywords" +msgstr "" + +#: src/SUMMARY.md:130 +msgid "B - Operators and Symbols" +msgstr "" + +#: src/SUMMARY.md:131 +msgid "C - Derivable Traits" +msgstr "" + +#: src/SUMMARY.md:132 +msgid "D - Useful Development Tools" +msgstr "" + +#: src/SUMMARY.md:133 +msgid "E - Editions" +msgstr "" + +#: src/SUMMARY.md:134 +msgid "F - Translations of the Book" +msgstr "" + +#: src/SUMMARY.md:135 +msgid "G - How Rust is Made and “Nightly Rust”" +msgstr "" + +#: src/title-page.md:3 +msgid "" +"_by Steve Klabnik and Carol Nichols, with contributions from the Rust " +"Community_" +msgstr "" + +#: src/title-page.md:5 +msgid "" +"This version of the text assumes you’re using Rust 1.79.0 (released " +"2024-06-13) or later. See the [“Installation” section of Chapter 1](ch01-01-" +"installation.html) to install or update Rust." +msgstr "" +"このバージョンは Rust 1.79.0 (2024-06-13 リリース) 以降を想定しています。" +"Rust をインストールしたりアップデートするには[1章の “インストール” 節](ch01-01-installation.html)を参照してください。" + +#: src/title-page.md:9 +msgid "" +"The HTML format is available online at [https://doc.rust-lang.org/stable/" +"book/](https://doc.rust-lang.org/stable/book/) and offline with " +"installations of Rust made with `rustup`; run `rustup doc --book` to open." +msgstr "" + +#: src/title-page.md:14 +msgid "" +"Several community [translations](appendix-06-translation.html) are also " +"available." +msgstr "" + +#: src/title-page.md:16 +msgid "" +"This text is available in [paperback and ebook format from No Starch Press]" +"(https://nostarch.com/rust-programming-language-2nd-edition)." +msgstr "" + +#: src/title-page.md:24 +msgid "" +"**🚨 Want a more interactive learning experience? Try out a different version " +"of the Rust Book, featuring: quizzes, highlighting, visualizations, and " +"more**: " +msgstr "" + +#: src/foreword.md:3 +msgid "" +"It wasn’t always so clear, but the Rust programming language is " +"fundamentally about _empowerment_: no matter what kind of code you are " +"writing now, Rust empowers you to reach farther, to program with confidence " +"in a wider variety of domains than you did before." +msgstr "" + +#: src/foreword.md:8 +msgid "" +"Take, for example, “systems-level” work that deals with low-level details of " +"memory management, data representation, and concurrency. Traditionally, this " +"realm of programming is seen as arcane, accessible only to a select few who " +"have devoted the necessary years learning to avoid its infamous pitfalls. " +"And even those who practice it do so with caution, lest their code be open " +"to exploits, crashes, or corruption." +msgstr "" + +#: src/foreword.md:15 +msgid "" +"Rust breaks down these barriers by eliminating the old pitfalls and " +"providing a friendly, polished set of tools to help you along the way. " +"Programmers who need to “dip down” into lower-level control can do so with " +"Rust, without taking on the customary risk of crashes or security holes, and " +"without having to learn the fine points of a fickle toolchain. Better yet, " +"the language is designed to guide you naturally towards reliable code that " +"is efficient in terms of speed and memory usage." +msgstr "" + +#: src/foreword.md:23 +msgid "" +"Programmers who are already working with low-level code can use Rust to " +"raise their ambitions. For example, introducing parallelism in Rust is a " +"relatively low-risk operation: the compiler will catch the classical " +"mistakes for you. And you can tackle more aggressive optimizations in your " +"code with the confidence that you won’t accidentally introduce crashes or " +"vulnerabilities." +msgstr "" + +#: src/foreword.md:29 +msgid "" +"But Rust isn’t limited to low-level systems programming. It’s expressive and " +"ergonomic enough to make CLI apps, web servers, and many other kinds of code " +"quite pleasant to write — you’ll find simple examples of both later in the " +"book. Working with Rust allows you to build skills that transfer from one " +"domain to another; you can learn Rust by writing a web app, then apply those " +"same skills to target your Raspberry Pi." +msgstr "" + +#: src/foreword.md:36 +msgid "" +"This book fully embraces the potential of Rust to empower its users. It’s a " +"friendly and approachable text intended to help you level up not just your " +"knowledge of Rust, but also your reach and confidence as a programmer in " +"general. So dive in, get ready to learn—and welcome to the Rust community!" +msgstr "" + +#: src/foreword.md:41 +msgid "— Nicholas Matsakis and Aaron Turon" +msgstr "" + +#: src/ch00-00-introduction.md:3 +msgid "" +"Note: This edition of the book is the same as [The Rust Programming Language]" +"(https://nostarch.com/rust-programming-language-2nd-edition) available in " +"print and ebook format from [No Starch Press](https://nostarch.com/)." +msgstr "" + +#: src/ch00-00-introduction.md:10 +msgid "" +"Welcome to _The Rust Programming Language_, an introductory book about Rust. " +"The Rust programming language helps you write faster, more reliable " +"software. High-level ergonomics and low-level control are often at odds in " +"programming language design; Rust challenges that conflict. Through " +"balancing powerful technical capacity and a great developer experience, Rust " +"gives you the option to control low-level details (such as memory usage) " +"without all the hassle traditionally associated with such control." +msgstr "" + +#: src/ch00-00-introduction.md:18 +msgid "Who Rust Is For" +msgstr "" + +#: src/ch00-00-introduction.md:20 +msgid "" +"Rust is ideal for many people for a variety of reasons. Let’s look at a few " +"of the most important groups." +msgstr "" + +#: src/ch00-00-introduction.md:23 +msgid "Teams of Developers" +msgstr "" + +#: src/ch00-00-introduction.md:25 +msgid "" +"Rust is proving to be a productive tool for collaborating among large teams " +"of developers with varying levels of systems programming knowledge. Low-" +"level code is prone to various subtle bugs, which in most other languages " +"can be caught only through extensive testing and careful code review by " +"experienced developers. In Rust, the compiler plays a gatekeeper role by " +"refusing to compile code with these elusive bugs, including concurrency " +"bugs. By working alongside the compiler, the team can spend their time " +"focusing on the program’s logic rather than chasing down bugs." +msgstr "" + +#: src/ch00-00-introduction.md:34 +msgid "" +"Rust also brings contemporary developer tools to the systems programming " +"world:" +msgstr "" + +#: src/ch00-00-introduction.md:36 +msgid "" +"Cargo, the included dependency manager and build tool, makes adding, " +"compiling, and managing dependencies painless and consistent across the Rust " +"ecosystem." +msgstr "" + +#: src/ch00-00-introduction.md:39 +msgid "" +"The Rustfmt formatting tool ensures a consistent coding style across " +"developers." +msgstr "" + +#: src/ch00-00-introduction.md:41 +msgid "" +"The rust-analyzer powers Integrated Development Environment (IDE) " +"integration for code completion and inline error messages." +msgstr "" + +#: src/ch00-00-introduction.md:44 +msgid "" +"By using these and other tools in the Rust ecosystem, developers can be " +"productive while writing systems-level code." +msgstr "" + +#: src/ch00-00-introduction.md:47 +msgid "Students" +msgstr "" + +#: src/ch00-00-introduction.md:49 +msgid "" +"Rust is for students and those who are interested in learning about systems " +"concepts. Using Rust, many people have learned about topics like operating " +"systems development. The community is very welcoming and happy to answer " +"student questions. Through efforts such as this book, the Rust teams want to " +"make systems concepts more accessible to more people, especially those new " +"to programming." +msgstr "" + +#: src/ch00-00-introduction.md:56 +msgid "Companies" +msgstr "" + +#: src/ch00-00-introduction.md:58 +msgid "" +"Hundreds of companies, large and small, use Rust in production for a variety " +"of tasks, including command line tools, web services, DevOps tooling, " +"embedded devices, audio and video analysis and transcoding, " +"cryptocurrencies, bioinformatics, search engines, Internet of Things " +"applications, machine learning, and even major parts of the Firefox web " +"browser." +msgstr "" + +#: src/ch00-00-introduction.md:64 +msgid "Open Source Developers" +msgstr "" + +#: src/ch00-00-introduction.md:66 +msgid "" +"Rust is for people who want to build the Rust programming language, " +"community, developer tools, and libraries. We’d love to have you contribute " +"to the Rust language." +msgstr "" + +#: src/ch00-00-introduction.md:70 +msgid "People Who Value Speed and Stability" +msgstr "" + +#: src/ch00-00-introduction.md:72 +msgid "" +"Rust is for people who crave speed and stability in a language. By speed, we " +"mean both how quickly Rust code can run and the speed at which Rust lets you " +"write programs. The Rust compiler’s checks ensure stability through feature " +"additions and refactoring. This is in contrast to the brittle legacy code in " +"languages without these checks, which developers are often afraid to modify. " +"By striving for zero-cost abstractions, higher-level features that compile " +"to lower-level code as fast as code written manually, Rust endeavors to make " +"safe code be fast code as well." +msgstr "" + +#: src/ch00-00-introduction.md:81 +msgid "" +"The Rust language hopes to support many other users as well; those mentioned " +"here are merely some of the biggest stakeholders. Overall, Rust’s greatest " +"ambition is to eliminate the trade-offs that programmers have accepted for " +"decades by providing safety _and_ productivity, speed _and_ ergonomics. Give " +"Rust a try and see if its choices work for you." +msgstr "" + +#: src/ch00-00-introduction.md:87 +msgid "Who This Book Is For" +msgstr "" + +#: src/ch00-00-introduction.md:89 +msgid "" +"This book assumes that you’ve written code in another programming language " +"but doesn’t make any assumptions about which one. We’ve tried to make the " +"material broadly accessible to those from a wide variety of programming " +"backgrounds. We don’t spend a lot of time talking about what programming " +"_is_ or how to think about it. If you’re entirely new to programming, you " +"would be better served by reading a book that specifically provides an " +"introduction to programming." +msgstr "" + +#: src/ch00-00-introduction.md:96 +msgid "How to Use This Book" +msgstr "" + +#: src/ch00-00-introduction.md:98 +msgid "" +"In general, this book assumes that you’re reading it in sequence from front " +"to back. Later chapters build on concepts in earlier chapters, and earlier " +"chapters might not delve into details on a particular topic but will revisit " +"the topic in a later chapter." +msgstr "" + +#: src/ch00-00-introduction.md:103 +msgid "" +"You’ll find two kinds of chapters in this book: concept chapters and project " +"chapters. In concept chapters, you’ll learn about an aspect of Rust. In " +"project chapters, we’ll build small programs together, applying what you’ve " +"learned so far. Chapters 2, 12, and 20 are project chapters; the rest are " +"concept chapters." +msgstr "" + +#: src/ch00-00-introduction.md:108 +msgid "" +"Chapter 1 explains how to install Rust, how to write a “Hello, world!” " +"program, and how to use Cargo, Rust’s package manager and build tool. " +"Chapter 2 is a hands-on introduction to writing a program in Rust, having " +"you build up a number guessing game. Here we cover concepts at a high level, " +"and later chapters will provide additional detail. If you want to get your " +"hands dirty right away, Chapter 2 is the place for that. Chapter 3 covers " +"Rust features that are similar to those of other programming languages, and " +"in Chapter 4 you’ll learn about Rust’s ownership system. If you’re a " +"particularly meticulous learner who prefers to learn every detail before " +"moving on to the next, you might want to skip Chapter 2 and go straight to " +"Chapter 3, returning to Chapter 2 when you’d like to work on a project " +"applying the details you’ve learned." +msgstr "" + +#: src/ch00-00-introduction.md:120 +msgid "" +"Chapter 5 discusses structs and methods, and Chapter 6 covers enums, `match` " +"expressions, and the `if let` control flow construct. You’ll use structs and " +"enums to make custom types in Rust." +msgstr "" + +#: src/ch00-00-introduction.md:124 +msgid "" +"In Chapter 7, you’ll learn about Rust’s module system and about privacy " +"rules for organizing your code and its public Application Programming " +"Interface (API). Chapter 8 discusses some common collection data structures " +"that the standard library provides, such as vectors, strings, and hash maps. " +"Chapter 9 explores Rust’s error-handling philosophy and techniques." +msgstr "" + +#: src/ch00-00-introduction.md:130 +msgid "" +"Chapter 10 digs into generics, traits, and lifetimes, which give you the " +"power to define code that applies to multiple types. Chapter 11 is all about " +"testing, which even with Rust’s safety guarantees is necessary to ensure " +"your program’s logic is correct. In Chapter 12, we’ll build our own " +"implementation of a subset of functionality from the `grep` command line " +"tool that searches for text within files. For this, we’ll use many of the " +"concepts we discussed in the previous chapters." +msgstr "" + +#: src/ch00-00-introduction.md:138 +msgid "" +"Chapter 13 explores closures and iterators: features of Rust that come from " +"functional programming languages. In Chapter 14, we’ll examine Cargo in more " +"depth and talk about best practices for sharing your libraries with others. " +"Chapter 15 discusses smart pointers that the standard library provides and " +"the traits that enable their functionality." +msgstr "" + +#: src/ch00-00-introduction.md:144 +msgid "" +"In Chapter 16, we’ll walk through different models of concurrent programming " +"and talk about how Rust helps you to program in multiple threads fearlessly. " +"Chapter 17 looks at how Rust idioms compare to object-oriented programming " +"principles you might be familiar with." +msgstr "" + +#: src/ch00-00-introduction.md:149 +msgid "" +"Chapter 18 is a reference on patterns and pattern matching, which are " +"powerful ways of expressing ideas throughout Rust programs. Chapter 19 " +"contains a smorgasbord of advanced topics of interest, including unsafe " +"Rust, macros, and more about lifetimes, traits, types, functions, and " +"closures." +msgstr "" + +#: src/ch00-00-introduction.md:154 +msgid "" +"In Chapter 20, we’ll complete a project in which we’ll implement a low-level " +"multithreaded web server!" +msgstr "" + +#: src/ch00-00-introduction.md:157 +msgid "" +"Finally, some appendices contain useful information about the language in a " +"more reference-like format. Appendix A covers Rust’s keywords, Appendix B " +"covers Rust’s operators and symbols, Appendix C covers derivable traits " +"provided by the standard library, Appendix D covers some useful development " +"tools, and Appendix E explains Rust editions. In Appendix F, you can find " +"translations of the book, and in Appendix G we’ll cover how Rust is made and " +"what nightly Rust is." +msgstr "" + +#: src/ch00-00-introduction.md:165 +msgid "" +"There is no wrong way to read this book: if you want to skip ahead, go for " +"it! You might have to jump back to earlier chapters if you experience any " +"confusion. But do whatever works for you." +msgstr "" + +#: src/ch00-00-introduction.md:169 +msgid "" +msgstr "" + +#: src/ch00-00-introduction.md:171 +msgid "" +"An important part of the process of learning Rust is learning how to read " +"the error messages the compiler displays: these will guide you toward " +"working code. As such, we’ll provide many examples that don’t compile along " +"with the error message the compiler will show you in each situation. Know " +"that if you enter and run a random example, it may not compile! Make sure " +"you read the surrounding text to see whether the example you’re trying to " +"run is meant to error. Ferris will also help you distinguish code that isn’t " +"meant to work:" +msgstr "" + +#: src/ch00-00-introduction.md:179 +msgid "Ferris" +msgstr "" + +#: src/ch00-00-introduction.md:179 +msgid "Meaning" +msgstr "" + +#: src/ch00-00-introduction.md:181 +msgid "" +"
+" +msgstr "" + +#: src/ch00-00-introduction.md:181 +msgid "This code does not compile!" +msgstr "" + +#: src/ch00-00-introduction.md:182 +msgid "" +"\"Ferris" +msgstr "" + +#: src/ch00-00-introduction.md:182 +msgid "This code panics!" +msgstr "" + +#: src/ch00-00-introduction.md:183 +msgid "" +"" +msgstr "" + +#: src/ch00-00-introduction.md:183 +msgid "This code does not produce the desired behavior." +msgstr "" + +#: src/ch00-00-introduction.md:185 +msgid "" +"In most situations, we’ll lead you to the correct version of any code that " +"doesn’t compile." +msgstr "" + +#: src/ch00-00-introduction.md:188 +msgid "Source Code" +msgstr "" + +#: src/ch00-00-introduction.md:190 +msgid "" +"The source files from which this book is generated can be found on [GitHub]" +"(https://github.com/rust-lang/book/tree/main/src)." +msgstr "" + +#: src/ch01-00-getting-started.md:3 +msgid "" +"Let’s start your Rust journey! There’s a lot to learn, but every journey " +"starts somewhere. In this chapter, we’ll discuss:" +msgstr "" + +#: src/ch01-00-getting-started.md:6 +msgid "Installing Rust on Linux, macOS, and Windows" +msgstr "" + +#: src/ch01-00-getting-started.md:7 +msgid "Writing a program that prints `Hello, world!`" +msgstr "" + +#: src/ch01-00-getting-started.md:8 +msgid "Using `cargo`, Rust’s package manager and build system" +msgstr "" + +#: src/ch01-01-installation.md:3 +msgid "" +"The first step is to install Rust. We’ll download Rust through `rustup`, a " +"command line tool for managing Rust versions and associated tools. You’ll " +"need an internet connection for the download." +msgstr "" + +#: src/ch01-01-installation.md:7 +msgid "" +"Note: If you prefer not to use `rustup` for some reason, please see the " +"[Other Rust Installation Methods page](https://forge.rust-lang.org/infra/" +"other-installation-methods.html) for more options." +msgstr "" + +#: src/ch01-01-installation.md:10 +msgid "" +"The following steps install the latest stable version of the Rust compiler. " +"Rust’s stability guarantees ensure that all the examples in the book that " +"compile will continue to compile with newer Rust versions. The output might " +"differ slightly between versions because Rust often improves error messages " +"and warnings. In other words, any newer, stable version of Rust you install " +"using these steps should work as expected with the content of this book." +msgstr "" + +#: src/ch01-01-installation.md:17 +msgid "Command Line Notation" +msgstr "" + +#: src/ch01-01-installation.md:19 +msgid "" +"In this chapter and throughout the book, we’ll show some commands used in " +"the terminal. Lines that you should enter in a terminal all start with `$`. " +"You don’t need to type the `$` character; it’s the command line prompt shown " +"to indicate the start of each command. Lines that don’t start with `$` " +"typically show the output of the previous command. Additionally, PowerShell-" +"specific examples will use `>` rather than `$`." +msgstr "" + +#: src/ch01-01-installation.md:26 +msgid "Installing `rustup` on Linux or macOS" +msgstr "" + +#: src/ch01-01-installation.md:28 +msgid "" +"If you’re using Linux or macOS, open a terminal and enter the following " +"command:" +msgstr "" + +#: src/ch01-01-installation.md:30 +msgid "" +"```console\n" +"$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh\n" +"```" +msgstr "" + +#: src/ch01-01-installation.md:34 +msgid "" +"The command downloads a script and starts the installation of the `rustup` " +"tool, which installs the latest stable version of Rust. You might be " +"prompted for your password. If the install is successful, the following line " +"will appear:" +msgstr "" + +#: src/ch01-01-installation.md:42 +msgid "" +"You will also need a _linker_, which is a program that Rust uses to join its " +"compiled outputs into one file. It is likely you already have one. If you " +"get linker errors, you should install a C compiler, which will typically " +"include a linker. A C compiler is also useful because some common Rust " +"packages depend on C code and will need a C compiler." +msgstr "" + +#: src/ch01-01-installation.md:48 +msgid "On macOS, you can get a C compiler by running:" +msgstr "" + +#: src/ch01-01-installation.md:54 +msgid "" +"Linux users should generally install GCC or Clang, according to their " +"distribution’s documentation. For example, if you use Ubuntu, you can " +"install the `build-essential` package." +msgstr "" + +#: src/ch01-01-installation.md:58 +msgid "Installing `rustup` on Windows" +msgstr "" + +#: src/ch01-01-installation.md:60 +msgid "" +"On Windows, go to [https://www.rust-lang.org/tools/install](https://www.rust-" +"lang.org/tools/install) and follow the instructions for installing Rust. At " +"some point in the installation, you’ll be prompted to install Visual Studio. " +"This provides a linker and the native libraries needed to compile programs. " +"If you need more help with this step, see [https://rust-lang.github.io/" +"rustup/installation/windows-msvc.html](https://rust-lang.github.io/rustup/" +"installation/windows-msvc.html)" +msgstr "" + +#: src/ch01-01-installation.md:66 +msgid "" +"The rest of this book uses commands that work in both _cmd.exe_ and " +"PowerShell. If there are specific differences, we’ll explain which to use." +msgstr "" + +#: src/ch01-01-installation.md:69 +msgid "Troubleshooting" +msgstr "" + +#: src/ch01-01-installation.md:71 +msgid "" +"To check whether you have Rust installed correctly, open a shell and enter " +"this line:" +msgstr "" + +#: src/ch01-01-installation.md:78 +msgid "" +"You should see the version number, commit hash, and commit date for the " +"latest stable version that has been released, in the following format:" +msgstr "" + +#: src/ch01-01-installation.md:85 +msgid "" +"If you see this information, you have installed Rust successfully! If you " +"don’t see this information, check that Rust is in your `%PATH%` system " +"variable as follows." +msgstr "" + +#: src/ch01-01-installation.md:89 +msgid "In Windows CMD, use:" +msgstr "" + +#: src/ch01-01-installation.md:95 +msgid "In PowerShell, use:" +msgstr "" + +#: src/ch01-01-installation.md:101 +msgid "In Linux and macOS, use:" +msgstr "" + +#: src/ch01-01-installation.md:107 +msgid "" +"If that’s all correct and Rust still isn’t working, there are a number of " +"places you can get help. Find out how to get in touch with other Rustaceans " +"(a silly nickname we call ourselves) on [the community page](https://www." +"rust-lang.org/community)." +msgstr "" + +#: src/ch01-01-installation.md:111 +msgid "Updating and Uninstalling" +msgstr "" + +#: src/ch01-01-installation.md:113 +msgid "" +"Once Rust is installed via `rustup`, updating to a newly released version is " +"easy. From your shell, run the following update script:" +msgstr "" + +#: src/ch01-01-installation.md:120 +msgid "" +"To uninstall Rust and `rustup`, run the following uninstall script from your " +"shell:" +msgstr "" + +#: src/ch01-01-installation.md:127 +msgid "Local Documentation" +msgstr "" + +#: src/ch01-01-installation.md:129 +msgid "" +"The installation of Rust also includes a local copy of the documentation so " +"that you can read it offline. Run `rustup doc` to open the local " +"documentation in your browser." +msgstr "" + +#: src/ch01-01-installation.md:133 +msgid "" +"Any time a type or function is provided by the standard library and you’re " +"not sure what it does or how to use it, use the application programming " +"interface (API) documentation to find out!" +msgstr "" + +#: src/ch01-02-hello-world.md:3 +msgid "" +"Now that you’ve installed Rust, it’s time to write your first Rust program. " +"It’s traditional when learning a new language to write a little program that " +"prints the text `Hello, world!` to the screen, so we’ll do the same here!" +msgstr "" + +#: src/ch01-02-hello-world.md:7 +msgid "" +"Note: This book assumes basic familiarity with the command line. Rust makes " +"no specific demands about your editing or tooling or where your code lives, " +"so if you prefer to use an integrated development environment (IDE) instead " +"of the command line, feel free to use your favorite IDE. Many IDEs now have " +"some degree of Rust support; check the IDE’s documentation for details. The " +"Rust team has been focusing on enabling great IDE support via `rust-" +"analyzer`. See [Appendix D](appendix-04-useful-development-tools.html) for more details." +msgstr "" + +#: src/ch01-02-hello-world.md:15 +msgid "Creating a Project Directory" +msgstr "" + +#: src/ch01-02-hello-world.md:17 +msgid "" +"You’ll start by making a directory to store your Rust code. It doesn’t " +"matter to Rust where your code lives, but for the exercises and projects in " +"this book, we suggest making a _projects_ directory in your home directory " +"and keeping all your projects there." +msgstr "" + +#: src/ch01-02-hello-world.md:22 +msgid "" +"Open a terminal and enter the following commands to make a _projects_ " +"directory and a directory for the “Hello, world!” project within the " +"_projects_ directory." +msgstr "" + +#: src/ch01-02-hello-world.md:25 +msgid "For Linux, macOS, and PowerShell on Windows, enter this:" +msgstr "" + +#: src/ch01-02-hello-world.md:34 +msgid "For Windows CMD, enter this:" +msgstr "" + +#: src/ch01-02-hello-world.md:37 src/ch01-02-hello-world.md:38 +msgid "\"%USERPROFILE%\\projects\"" +msgstr "" + +#: src/ch01-02-hello-world.md:43 +msgid "Writing and Running a Rust Program" +msgstr "" + +#: src/ch01-02-hello-world.md:45 +msgid "" +"Next, make a new source file and call it _main.rs_. Rust files always end " +"with the _.rs_ extension. If you’re using more than one word in your " +"filename, the convention is to use an underscore to separate them. For " +"example, use _hello_world.rs_ rather than _helloworld.rs_." +msgstr "" + +#: src/ch01-02-hello-world.md:50 +msgid "" +"Now open the _main.rs_ file you just created and enter the code in Listing " +"1-1." +msgstr "" + +#: src/ch01-02-hello-world.md:56 src/ch01-02-hello-world.md:118 +#: src/ch01-03-hello-cargo.md:98 src/ch02-00-guessing-game-tutorial.md:61 +#: src/ch03-03-how-functions-work.md:16 src/ch04-03-slices.md:361 +#: src/ch19-01-unsafe-rust.md:470 +msgid "\"Hello, world!\"" +msgstr "" + +#: src/ch01-02-hello-world.md:62 +msgid "" +"Save the file and go back to your terminal window in the _~/projects/" +"hello_world_ directory. On Linux or macOS, enter the following commands to " +"compile and run the file:" +msgstr "" + +#: src/ch01-02-hello-world.md:72 +msgid "On Windows, enter the command `.\\main.exe` instead of `./main`:" +msgstr "" + +#: src/ch01-02-hello-world.md:80 +msgid "" +"Regardless of your operating system, the string `Hello, world!` should print " +"to the terminal. If you don’t see this output, refer back to the " +"[“Troubleshooting”](ch01-01-installation.html#troubleshooting)). The Rust team has included this " +"tool with the standard Rust distribution, as `rustc` is, so it should " +"already be installed on your computer!" +msgstr "" + +#: src/ch01-02-hello-world.md:115 +msgid "The body of the `main` function holds the following code:" +msgstr "" + +#: src/ch01-02-hello-world.md:121 +msgid "" +"This line does all the work in this little program: it prints text to the " +"screen. There are four important details to notice here." +msgstr "" + +#: src/ch01-02-hello-world.md:124 +msgid "First, Rust style is to indent with four spaces, not a tab." +msgstr "" + +#: src/ch01-02-hello-world.md:126 +msgid "" +"Second, `println!` calls a Rust macro. If it had called a function instead, " +"it would be entered as `println` (without the `!`). We’ll discuss Rust " +"macros in more detail in Chapter 19. For now, you just need to know that " +"using a `!` means that you’re calling a macro instead of a normal function " +"and that macros don’t always follow the same rules as functions." +msgstr "" + +#: src/ch01-02-hello-world.md:132 +msgid "" +"Third, you see the `\"Hello, world!\"` string. We pass this string as an " +"argument to `println!`, and the string is printed to the screen." +msgstr "" + +#: src/ch01-02-hello-world.md:135 +msgid "" +"Fourth, we end the line with a semicolon (`;`), which indicates that this " +"expression is over and the next one is ready to begin. Most lines of Rust " +"code end with a semicolon." +msgstr "" + +#: src/ch01-02-hello-world.md:139 +msgid "Compiling and Running Are Separate Steps" +msgstr "" + +#: src/ch01-02-hello-world.md:141 +msgid "" +"You’ve just run a newly created program, so let’s examine each step in the " +"process." +msgstr "" + +#: src/ch01-02-hello-world.md:144 +msgid "" +"Before running a Rust program, you must compile it using the Rust compiler " +"by entering the `rustc` command and passing it the name of your source file, " +"like this:" +msgstr "" + +#: src/ch01-02-hello-world.md:152 +msgid "" +"If you have a C or C++ background, you’ll notice that this is similar to " +"`gcc` or `clang`. After compiling successfully, Rust outputs a binary " +"executable." +msgstr "" + +#: src/ch01-02-hello-world.md:155 +msgid "" +"On Linux, macOS, and PowerShell on Windows, you can see the executable by " +"entering the `ls` command in your shell:" +msgstr "" + +#: src/ch01-02-hello-world.md:163 +msgid "" +"On Linux and macOS, you’ll see two files. With PowerShell on Windows, you’ll " +"see the same three files that you would see using CMD. With CMD on Windows, " +"you would enter the following:" +msgstr "" + +#: src/ch01-02-hello-world.md:174 +msgid "" +"This shows the source code file with the _.rs_ extension, the executable " +"file (_main.exe_ on Windows, but _main_ on all other platforms), and, when " +"using Windows, a file containing debugging information with the _.pdb_ " +"extension. From here, you run the _main_ or _main.exe_ file, like this:" +msgstr "" + +#: src/ch01-02-hello-world.md:183 +msgid "" +"If your _main.rs_ is your “Hello, world!” program, this line prints `Hello, " +"world!` to your terminal." +msgstr "" + +#: src/ch01-02-hello-world.md:186 +msgid "" +"If you’re more familiar with a dynamic language, such as Ruby, Python, or " +"JavaScript, you might not be used to compiling and running a program as " +"separate steps. Rust is an _ahead-of-time compiled_ language, meaning you " +"can compile a program and give the executable to someone else, and they can " +"run it even without having Rust installed. If you give someone a _.rb_, _." +"py_, or _.js_ file, they need to have a Ruby, Python, or JavaScript " +"implementation installed (respectively). But in those languages, you only " +"need one command to compile and run your program. Everything is a trade-off " +"in language design." +msgstr "" + +#: src/ch01-02-hello-world.md:195 +msgid "" +"Just compiling with `rustc` is fine for simple programs, but as your project " +"grows, you’ll want to manage all the options and make it easy to share your " +"code. Next, we’ll introduce you to the Cargo tool, which will help you write " +"real-world Rust programs." +msgstr "" + +#: src/ch01-03-hello-cargo.md:3 +msgid "" +"Cargo is Rust’s build system and package manager. Most Rustaceans use this " +"tool to manage their Rust projects because Cargo handles a lot of tasks for " +"you, such as building your code, downloading the libraries your code depends " +"on, and building those libraries. (We call the libraries that your code " +"needs _dependencies_.)" +msgstr "" + +#: src/ch01-03-hello-cargo.md:9 +msgid "" +"The simplest Rust programs, like the one we’ve written so far, don’t have " +"any dependencies. If we had built the “Hello, world!” project with Cargo, it " +"would only use the part of Cargo that handles building your code. As you " +"write more complex Rust programs, you’ll add dependencies, and if you start " +"a project using Cargo, adding dependencies will be much easier to do." +msgstr "" + +#: src/ch01-03-hello-cargo.md:15 +msgid "" +"Because the vast majority of Rust projects use Cargo, the rest of this book " +"assumes that you’re using Cargo too. Cargo comes installed with Rust if you " +"used the official installers discussed in the [“Installation”](ch01-01-" +"installation.html#installation) section. If you installed " +"Rust through some other means, check whether Cargo is installed by entering " +"the following in your terminal:" +msgstr "" + +#: src/ch01-03-hello-cargo.md:26 +msgid "" +"If you see a version number, you have it! If you see an error, such as " +"`command not found`, look at the documentation for your method of " +"installation to determine how to install Cargo separately." +msgstr "" + +#: src/ch01-03-hello-cargo.md:30 +msgid "Creating a Project with Cargo" +msgstr "" + +#: src/ch01-03-hello-cargo.md:32 +msgid "" +"Let’s create a new project using Cargo and look at how it differs from our " +"original “Hello, world!” project. Navigate back to your _projects_ directory " +"(or wherever you decided to store your code). Then, on any operating system, " +"run the following:" +msgstr "" + +#: src/ch01-03-hello-cargo.md:42 +msgid "" +"The first command creates a new directory and project called _hello_cargo_. " +"We’ve named our project _hello_cargo_, and Cargo creates its files in a " +"directory of the same name." +msgstr "" + +#: src/ch01-03-hello-cargo.md:46 +msgid "" +"Go into the _hello_cargo_ directory and list the files. You’ll see that " +"Cargo has generated two files and one directory for us: a _Cargo.toml_ file " +"and a _src_ directory with a _main.rs_ file inside." +msgstr "" + +#: src/ch01-03-hello-cargo.md:50 +msgid "" +"It has also initialized a new Git repository along with a _.gitignore_ file. " +"Git files won’t be generated if you run `cargo new` within an existing Git " +"repository; you can override this behavior by using `cargo new --vcs=git`." +msgstr "" + +#: src/ch01-03-hello-cargo.md:54 +msgid "" +"Note: Git is a common version control system. You can change `cargo new` to " +"use a different version control system or no version control system by using " +"the `--vcs` flag. Run `cargo new --help` to see the available options." +msgstr "" + +#: src/ch01-03-hello-cargo.md:58 +msgid "" +"Open _Cargo.toml_ in your text editor of choice. It should look similar to " +"the code in Listing 1-2." +msgstr "" + +#: src/ch01-03-hello-cargo.md:63 +msgid "" +"```toml\n" +"[package]\n" +"name = \"hello_cargo\"\n" +"version = \"0.1.0\"\n" +"edition = \"2021\"\n" +"\n" +"# See more keys and their definitions at https://doc.rust-lang.org/cargo/" +"reference/manifest.html\n" +"\n" +"[dependencies]\n" +"```" +msgstr "" + +#: src/ch01-03-hello-cargo.md:76 +msgid "" +"This file is in the [_TOML_](https://toml.io) (_Tom’s " +"Obvious, Minimal Language_) format, which is Cargo’s configuration format." +msgstr "" + +#: src/ch01-03-hello-cargo.md:79 +msgid "" +"The first line, `[package]`, is a section heading that indicates that the " +"following statements are configuring a package. As we add more information " +"to this file, we’ll add other sections." +msgstr "" + +#: src/ch01-03-hello-cargo.md:83 +msgid "" +"The next three lines set the configuration information Cargo needs to " +"compile your program: the name, the version, and the edition of Rust to use. " +"We’ll talk about the `edition` key in [Appendix E](appendix-05-editions." +"html)." +msgstr "" + +#: src/ch01-03-hello-cargo.md:87 +msgid "" +"The last line, `[dependencies]`, is the start of a section for you to list " +"any of your project’s dependencies. In Rust, packages of code are referred " +"to as _crates_. We won’t need any other crates for this project, but we will " +"in the first project in Chapter 2, so we’ll use this dependencies section " +"then." +msgstr "" + +#: src/ch01-03-hello-cargo.md:92 +msgid "Now open _src/main.rs_ and take a look:" +msgstr "" + +#: src/ch01-03-hello-cargo.md:94 src/ch02-00-guessing-game-tutorial.md:57 +#: src/ch02-00-guessing-game-tutorial.md:869 +#: src/ch02-00-guessing-game-tutorial.md:991 +#: src/ch02-00-guessing-game-tutorial.md:1086 +#: src/ch03-01-variables-and-mutability.md:18 +#: src/ch03-01-variables-and-mutability.md:79 +#: src/ch03-01-variables-and-mutability.md:164 src/ch03-02-data-types.md:153 +#: src/ch03-02-data-types.md:173 src/ch03-02-data-types.md:206 +#: src/ch03-02-data-types.md:225 src/ch03-02-data-types.md:262 +#: src/ch03-02-data-types.md:274 src/ch03-02-data-types.md:295 +#: src/ch03-02-data-types.md:327 src/ch03-02-data-types.md:382 +#: src/ch03-02-data-types.md:403 src/ch03-03-how-functions-work.md:12 +#: src/ch03-03-how-functions-work.md:66 src/ch03-03-how-functions-work.md:102 +#: src/ch03-03-how-functions-work.md:169 src/ch03-03-how-functions-work.md:221 +#: src/ch03-03-how-functions-work.md:261 src/ch03-03-how-functions-work.md:304 +#: src/ch03-03-how-functions-work.md:322 src/ch03-04-comments.md:26 +#: src/ch03-04-comments.md:37 src/ch03-05-control-flow.md:17 +#: src/ch03-05-control-flow.md:85 src/ch03-05-control-flow.md:120 +#: src/ch03-05-control-flow.md:139 src/ch03-05-control-flow.md:216 +#: src/ch03-05-control-flow.md:273 src/ch03-05-control-flow.md:531 +#: src/ch04-01-what-is-ownership.md:492 src/ch04-01-what-is-ownership.md:534 +#: src/ch04-01-what-is-ownership.md:584 +#: src/ch04-02-references-and-borrowing.md:15 +#: src/ch04-02-references-and-borrowing.md:101 +#: src/ch04-02-references-and-borrowing.md:145 +#: src/ch04-02-references-and-borrowing.md:168 +#: src/ch04-02-references-and-borrowing.md:324 +#: src/ch04-02-references-and-borrowing.md:383 src/ch04-03-slices.md:24 +#: src/ch04-03-slices.md:124 src/ch04-03-slices.md:253 +#: src/ch04-03-slices.md:296 src/ch04-03-slices.md:428 +#: src/ch05-01-defining-structs.md:16 src/ch05-01-defining-structs.md:41 +#: src/ch05-01-defining-structs.md:70 src/ch05-01-defining-structs.md:104 +#: src/ch05-01-defining-structs.md:149 src/ch05-01-defining-structs.md:196 +#: src/ch05-01-defining-structs.md:232 src/ch05-01-defining-structs.md:295 +#: src/ch05-01-defining-structs.md:326 src/ch05-01-defining-structs.md:359 +#: src/ch05-02-example-structs.md:12 src/ch05-02-example-structs.md:76 +#: src/ch05-02-example-structs.md:114 src/ch05-02-example-structs.md:169 +#: src/ch05-02-example-structs.md:238 src/ch05-03-method-syntax.md:18 +#: src/ch05-03-method-syntax.md:90 src/ch05-03-method-syntax.md:187 +#: src/ch05-03-method-syntax.md:235 src/ch05-03-method-syntax.md:298 +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:66 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:140 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:345 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:384 +#: src/ch09-01-unrecoverable-errors-with-panic.md:34 +#: src/ch09-01-unrecoverable-errors-with-panic.md:75 +#: src/ch09-02-recoverable-errors-with-result.md:32 +#: src/ch09-02-recoverable-errors-with-result.md:66 +#: src/ch09-02-recoverable-errors-with-result.md:120 +#: src/ch09-02-recoverable-errors-with-result.md:212 +#: src/ch09-02-recoverable-errors-with-result.md:241 +#: src/ch09-02-recoverable-errors-with-result.md:286 +#: src/ch09-02-recoverable-errors-with-result.md:373 +#: src/ch09-02-recoverable-errors-with-result.md:429 +#: src/ch09-02-recoverable-errors-with-result.md:462 +#: src/ch09-02-recoverable-errors-with-result.md:501 +#: src/ch09-02-recoverable-errors-with-result.md:613 +#: src/ch09-03-to-panic-or-not-to-panic.md:149 src/ch10-00-generics.md:45 +#: src/ch10-00-generics.md:80 src/ch10-00-generics.md:127 +#: src/ch10-01-syntax.md:19 src/ch10-01-syntax.md:97 src/ch10-01-syntax.md:167 +#: src/ch10-01-syntax.md:196 src/ch10-01-syntax.md:235 +#: src/ch10-01-syntax.md:308 src/ch10-01-syntax.md:351 +#: src/ch10-01-syntax.md:394 src/ch10-01-syntax.md:471 +#: src/ch10-03-lifetime-syntax.md:148 src/ch10-03-lifetime-syntax.md:173 +#: src/ch10-03-lifetime-syntax.md:276 src/ch10-03-lifetime-syntax.md:342 +#: src/ch10-03-lifetime-syntax.md:381 src/ch10-03-lifetime-syntax.md:454 +#: src/ch10-03-lifetime-syntax.md:482 src/ch10-03-lifetime-syntax.md:540 +#: src/ch12-03-improving-error-handling-and-modularity.md:749 +#: src/ch13-03-improving-our-io-project.md:149 src/ch15-01-box.md:38 +#: src/ch15-01-box.md:112 src/ch15-01-box.md:134 src/ch15-01-box.md:269 +#: src/ch15-02-deref.md:32 src/ch15-02-deref.md:84 src/ch15-02-deref.md:118 +#: src/ch15-02-deref.md:144 src/ch15-02-deref.md:195 src/ch15-02-deref.md:292 +#: src/ch15-02-deref.md:309 src/ch15-02-deref.md:355 src/ch15-03-drop.md:31 +#: src/ch15-03-drop.md:106 src/ch15-03-drop.md:172 src/ch15-04-rc.md:51 +#: src/ch15-04-rc.md:111 src/ch15-04-rc.md:157 +#: src/ch15-05-interior-mutability.md:611 src/ch15-06-reference-cycles.md:18 +#: src/ch15-06-reference-cycles.md:59 src/ch15-06-reference-cycles.md:220 +#: src/ch15-06-reference-cycles.md:255 src/ch15-06-reference-cycles.md:308 +#: src/ch15-06-reference-cycles.md:346 src/ch15-06-reference-cycles.md:427 +#: src/ch16-01-threads.md:42 src/ch16-01-threads.md:113 +#: src/ch16-01-threads.md:171 src/ch16-01-threads.md:236 +#: src/ch16-01-threads.md:296 src/ch16-01-threads.md:343 +#: src/ch16-02-message-passing.md:36 src/ch16-02-message-passing.md:73 +#: src/ch16-02-message-passing.md:106 src/ch16-02-message-passing.md:169 +#: src/ch16-02-message-passing.md:231 src/ch16-02-message-passing.md:298 +#: src/ch16-03-shared-state.md:55 src/ch16-03-shared-state.md:112 +#: src/ch16-03-shared-state.md:198 src/ch16-03-shared-state.md:301 +#: src/ch17-02-trait-objects.md:227 src/ch17-02-trait-objects.md:256 +#: src/ch17-02-trait-objects.md:327 src/ch17-03-oo-design-patterns.md:43 +#: src/ch17-03-oo-design-patterns.md:750 src/ch17-03-oo-design-patterns.md:912 +#: src/ch18-01-all-the-places-for-patterns.md:66 +#: src/ch18-01-all-the-places-for-patterns.md:290 +#: src/ch18-03-pattern-syntax.md:41 src/ch18-03-pattern-syntax.md:165 +#: src/ch18-03-pattern-syntax.md:197 src/ch18-03-pattern-syntax.md:230 +#: src/ch18-03-pattern-syntax.md:278 src/ch18-03-pattern-syntax.md:414 +#: src/ch18-03-pattern-syntax.md:512 src/ch18-03-pattern-syntax.md:606 +#: src/ch18-03-pattern-syntax.md:631 src/ch18-03-pattern-syntax.md:718 +#: src/ch19-01-unsafe-rust.md:409 src/ch19-01-unsafe-rust.md:467 +#: src/ch19-01-unsafe-rust.md:497 src/ch19-03-advanced-traits.md:129 +#: src/ch19-03-advanced-traits.md:252 src/ch19-03-advanced-traits.md:293 +#: src/ch19-03-advanced-traits.md:340 src/ch19-03-advanced-traits.md:413 +#: src/ch19-03-advanced-traits.md:466 src/ch19-03-advanced-traits.md:526 +#: src/ch19-03-advanced-traits.md:614 src/ch19-03-advanced-traits.md:647 +#: src/ch19-03-advanced-traits.md:719 src/ch19-03-advanced-traits.md:781 +#: src/ch19-05-advanced-functions-and-closures.md:25 src/ch19-06-macros.md:216 +#: src/ch20-01-single-threaded.md:37 src/ch20-01-single-threaded.md:140 +#: src/ch20-01-single-threaded.md:310 src/ch20-01-single-threaded.md:389 +#: src/ch20-01-single-threaded.md:462 src/ch20-01-single-threaded.md:530 +#: src/ch20-01-single-threaded.md:621 src/ch20-02-multithreaded.md:18 +#: src/ch20-02-multithreaded.md:152 src/ch20-02-multithreaded.md:218 +#: src/ch20-02-multithreaded.md:316 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:668 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:783 +#: src/appendix-01-keywords.md:89 src/appendix-01-keywords.md:111 +#: src/appendix-04-useful-development-tools.md:39 +#: src/appendix-04-useful-development-tools.md:83 +#: src/appendix-04-useful-development-tools.md:120 +#: src/appendix-04-useful-development-tools.md:149 +msgid "Filename: src/main.rs" +msgstr "" + +#: src/ch01-03-hello-cargo.md:102 +msgid "" +"Cargo has generated a “Hello, world!” program for you, just like the one we " +"wrote in Listing 1-1! So far, the differences between our project and the " +"project Cargo generated are that Cargo placed the code in the _src_ " +"directory and we have a _Cargo.toml_ configuration file in the top directory." +msgstr "" + +#: src/ch01-03-hello-cargo.md:107 +msgid "" +"Cargo expects your source files to live inside the _src_ directory. The top-" +"level project directory is just for README files, license information, " +"configuration files, and anything else not related to your code. Using Cargo " +"helps you organize your projects. There’s a place for everything, and " +"everything is in its place." +msgstr "" + +#: src/ch01-03-hello-cargo.md:113 +msgid "" +"If you started a project that doesn’t use Cargo, as we did with the “Hello, " +"world!” project, you can convert it to a project that does use Cargo. Move " +"the project code into the _src_ directory and create an appropriate _Cargo." +"toml_ file." +msgstr "" + +#: src/ch01-03-hello-cargo.md:118 +msgid "Building and Running a Cargo Project" +msgstr "" + +#: src/ch01-03-hello-cargo.md:120 +msgid "" +"Now let’s look at what’s different when we build and run the “Hello, world!” " +"program with Cargo! From your _hello_cargo_ directory, build your project by " +"entering the following command:" +msgstr "" + +#: src/ch01-03-hello-cargo.md:124 +msgid "" +"```console\n" +"$ cargo build\n" +" Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)\n" +" Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs\n" +"```" +msgstr "" + +#: src/ch01-03-hello-cargo.md:130 +msgid "" +"This command creates an executable file in _target/debug/hello_cargo_ (or " +"_target\\debug\\hello_cargo.exe_ on Windows) rather than in your current " +"directory. Because the default build is a debug build, Cargo puts the binary " +"in a directory named _debug_. You can run the executable with this command:" +msgstr "" + +#: src/ch01-03-hello-cargo.md:140 +msgid "" +"If all goes well, `Hello, world!` should print to the terminal. Running " +"`cargo build` for the first time also causes Cargo to create a new file at " +"the top level: _Cargo.lock_. This file keeps track of the exact versions of " +"dependencies in your project. This project doesn’t have dependencies, so the " +"file is a bit sparse. You won’t ever need to change this file manually; " +"Cargo manages its contents for you." +msgstr "" + +#: src/ch01-03-hello-cargo.md:147 +msgid "" +"We just built a project with `cargo build` and ran it with `./target/debug/" +"hello_cargo`, but we can also use `cargo run` to compile the code and then " +"run the resultant executable all in one command:" +msgstr "" + +#: src/ch01-03-hello-cargo.md:158 +msgid "" +"Using `cargo run` is more convenient than having to remember to run `cargo " +"build` and then use the whole path to the binary, so most developers use " +"`cargo run`." +msgstr "" + +#: src/ch01-03-hello-cargo.md:162 +msgid "" +"Notice that this time we didn’t see output indicating that Cargo was " +"compiling `hello_cargo`. Cargo figured out that the files hadn’t changed, so " +"it didn’t rebuild but just ran the binary. If you had modified your source " +"code, Cargo would have rebuilt the project before running it, and you would " +"have seen this output:" +msgstr "" + +#: src/ch01-03-hello-cargo.md:168 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)\n" +" Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs\n" +" Running `target/debug/hello_cargo`\n" +"Hello, world!\n" +"```" +msgstr "" + +#: src/ch01-03-hello-cargo.md:176 +msgid "" +"Cargo also provides a command called `cargo check`. This command quickly " +"checks your code to make sure it compiles but doesn’t produce an executable:" +msgstr "" + +#: src/ch01-03-hello-cargo.md:179 +msgid "" +"```console\n" +"$ cargo check\n" +" Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)\n" +" Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs\n" +"```" +msgstr "" + +#: src/ch01-03-hello-cargo.md:185 +msgid "" +"Why would you not want an executable? Often, `cargo check` is much faster " +"than `cargo build` because it skips the step of producing an executable. If " +"you’re continually checking your work while writing the code, using `cargo " +"check` will speed up the process of letting you know if your project is " +"still compiling! As such, many Rustaceans run `cargo check` periodically as " +"they write their program to make sure it compiles. Then they run `cargo " +"build` when they’re ready to use the executable." +msgstr "" + +#: src/ch01-03-hello-cargo.md:193 +msgid "Let’s recap what we’ve learned so far about Cargo:" +msgstr "" + +#: src/ch01-03-hello-cargo.md:195 +msgid "We can create a project using `cargo new`." +msgstr "" + +#: src/ch01-03-hello-cargo.md:196 +msgid "We can build a project using `cargo build`." +msgstr "" + +#: src/ch01-03-hello-cargo.md:197 +msgid "We can build and run a project in one step using `cargo run`." +msgstr "" + +#: src/ch01-03-hello-cargo.md:198 +msgid "" +"We can build a project without producing a binary to check for errors using " +"`cargo check`." +msgstr "" + +#: src/ch01-03-hello-cargo.md:200 +msgid "" +"Instead of saving the result of the build in the same directory as our code, " +"Cargo stores it in the _target/debug_ directory." +msgstr "" + +#: src/ch01-03-hello-cargo.md:203 +msgid "" +"An additional advantage of using Cargo is that the commands are the same no " +"matter which operating system you’re working on. So, at this point, we’ll no " +"longer provide specific instructions for Linux and macOS versus Windows." +msgstr "" + +#: src/ch01-03-hello-cargo.md:207 +msgid "Building for Release" +msgstr "" + +#: src/ch01-03-hello-cargo.md:209 +msgid "" +"When your project is finally ready for release, you can use `cargo build --" +"release` to compile it with optimizations. This command will create an " +"executable in _target/release_ instead of _target/debug_. The optimizations " +"make your Rust code run faster, but turning them on lengthens the time it " +"takes for your program to compile. This is why there are two different " +"profiles: one for development, when you want to rebuild quickly and often, " +"and another for building the final program you’ll give to a user that won’t " +"be rebuilt repeatedly and that will run as fast as possible. If you’re " +"benchmarking your code’s running time, be sure to run `cargo build --" +"release` and benchmark with the executable in _target/release_." +msgstr "" + +#: src/ch01-03-hello-cargo.md:220 +msgid "Cargo as Convention" +msgstr "" + +#: src/ch01-03-hello-cargo.md:222 +msgid "" +"With simple projects, Cargo doesn’t provide a lot of value over just using " +"`rustc`, but it will prove its worth as your programs become more intricate. " +"Once programs grow to multiple files or need a dependency, it’s much easier " +"to let Cargo coordinate the build." +msgstr "" + +#: src/ch01-03-hello-cargo.md:227 +msgid "" +"Even though the `hello_cargo` project is simple, it now uses much of the " +"real tooling you’ll use in the rest of your Rust career. In fact, to work on " +"any existing projects, you can use the following commands to check out the " +"code using Git, change to that project’s directory, and build:" +msgstr "" + +#: src/ch01-03-hello-cargo.md:238 +msgid "" +"For more information about Cargo, check out [its documentation](https://doc." +"rust-lang.org/cargo/)." +msgstr "" + +#: src/ch01-03-hello-cargo.md:240 src/ch02-00-guessing-game-tutorial.md:1291 +#: src/ch03-05-control-flow.md:544 src/ch04-03-slices.md:490 +#: src/ch05-03-method-syntax.md:382 src/ch06-03-if-let.md:121 +#: src/ch07-05-separating-modules-into-different-files.md:123 +#: src/ch08-03-hash-maps.md:285 src/ch09-03-to-panic-or-not-to-panic.md:269 +#: src/ch10-03-lifetime-syntax.md:879 src/ch11-03-test-organization.md:354 +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:113 +#: src/ch13-04-performance.md:84 src/ch14-05-extending-cargo.md:10 +#: src/ch15-06-reference-cycles.md:513 +#: src/ch16-04-extensible-concurrency-sync-and-send.md:63 +#: src/ch17-03-oo-design-patterns.md:955 src/ch18-03-pattern-syntax.md:847 +#: src/ch19-06-macros.md:568 src/ch20-03-graceful-shutdown-and-cleanup.md:941 +msgid "Summary" +msgstr "" + +#: src/ch01-03-hello-cargo.md:242 +msgid "" +"You’re already off to a great start on your Rust journey! In this chapter, " +"you’ve learned how to:" +msgstr "" + +#: src/ch01-03-hello-cargo.md:245 +msgid "Install the latest stable version of Rust using `rustup`" +msgstr "" + +#: src/ch01-03-hello-cargo.md:246 +msgid "Update to a newer Rust version" +msgstr "" + +#: src/ch01-03-hello-cargo.md:247 +msgid "Open locally installed documentation" +msgstr "" + +#: src/ch01-03-hello-cargo.md:248 +msgid "Write and run a “Hello, world!” program using `rustc` directly" +msgstr "" + +#: src/ch01-03-hello-cargo.md:249 +msgid "Create and run a new project using the conventions of Cargo" +msgstr "" + +#: src/ch01-03-hello-cargo.md:251 +msgid "" +"This is a great time to build a more substantial program to get used to " +"reading and writing Rust code. So, in Chapter 2, we’ll build a guessing game " +"program. If you would rather start by learning how common programming " +"concepts work in Rust, see Chapter 3 and then return to Chapter 2." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:3 +msgid "" +"Let’s jump into Rust by working through a hands-on project together! This " +"chapter introduces you to a few common Rust concepts by showing you how to " +"use them in a real program. You’ll learn about `let`, `match`, methods, " +"associated functions, external crates, and more! In the following chapters, " +"we’ll explore these ideas in more detail. In this chapter, you’ll just " +"practice the fundamentals." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:10 +msgid "" +"We’ll implement a classic beginner programming problem: a guessing game. " +"Here’s how it works: the program will generate a random integer between 1 " +"and 100. It will then prompt the player to enter a guess. After a guess is " +"entered, the program will indicate whether the guess is too low or too high. " +"If the guess is correct, the game will print a congratulatory message and " +"exit." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:16 +msgid "Setting Up a New Project" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:18 +msgid "" +"To set up a new project, go to the _projects_ directory that you created in " +"Chapter 1 and make a new project using Cargo, like so:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:26 +msgid "" +"The first command, `cargo new`, takes the name of the project " +"(`guessing_game`) as the first argument. The second command changes to the " +"new project’s directory." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:30 +msgid "Look at the generated _Cargo.toml_ file:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:41 +#: src/ch02-00-guessing-game-tutorial.md:489 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:281 +#: src/ch14-01-release-profiles.md:37 src/ch14-01-release-profiles.md:62 +#: src/ch14-02-publishing-to-crates-io.md:406 +#: src/ch14-02-publishing-to-crates-io.md:443 +#: src/ch14-02-publishing-to-crates-io.md:465 +#: src/ch14-03-cargo-workspaces.md:32 src/ch14-03-cargo-workspaces.md:87 +msgid "Filename: Cargo.toml" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:43 +msgid "" +"```toml\n" +"[package]\n" +"name = \"guessing_game\"\n" +"version = \"0.1.0\"\n" +"edition = \"2021\"\n" +"\n" +"# See more keys and their definitions at https://doc.rust-lang.org/cargo/" +"reference/manifest.html\n" +"\n" +"[dependencies]\n" +"```" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:54 +msgid "" +"As you saw in Chapter 1, `cargo new` generates a “Hello, world!” program for " +"you. Check out the _src/main.rs_ file:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:65 +msgid "" +"Now let’s compile this “Hello, world!” program and run it in the same step " +"using the `cargo run` command:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:68 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling guessing_game v0.1.0 (file:///projects/guessing_game)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.50s\n" +" Running `target/debug/guessing_game`\n" +"Hello, world!\n" +"```" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:76 +msgid "" +"The `run` command comes in handy when you need to rapidly iterate on a " +"project, as we’ll do in this game, quickly testing each iteration before " +"moving on to the next one." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:80 +msgid "" +"Reopen the _src/main.rs_ file. You’ll be writing all the code in this file." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:82 +msgid "Processing a Guess" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:84 +msgid "" +"The first part of the guessing game program will ask for user input, process " +"that input, and check that the input is in the expected form. To start, " +"we’ll allow the player to input a guess. Enter the code in Listing 2-1 into " +"_src/main.rs_." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:95 +#: src/ch02-00-guessing-game-tutorial.md:120 +#: src/ch02-00-guessing-game-tutorial.md:150 +#: src/ch02-00-guessing-game-tutorial.md:174 +#: src/ch02-00-guessing-game-tutorial.md:199 +#: src/ch02-00-guessing-game-tutorial.md:264 +#: src/ch02-00-guessing-game-tutorial.md:316 +#: src/ch02-00-guessing-game-tutorial.md:404 +#: src/ch02-00-guessing-game-tutorial.md:660 +#: src/ch02-00-guessing-game-tutorial.md:757 +#: src/ch02-00-guessing-game-tutorial.md:877 +#: src/ch02-00-guessing-game-tutorial.md:999 +#: src/ch02-00-guessing-game-tutorial.md:1094 +#: src/ch02-00-guessing-game-tutorial.md:1146 +#: src/ch02-00-guessing-game-tutorial.md:1255 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:302 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:355 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:393 +#: src/ch09-03-to-panic-or-not-to-panic.md:157 +#: src/ch19-04-advanced-types.md:226 +msgid "\"Guess the number!\"" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:97 +#: src/ch02-00-guessing-game-tutorial.md:122 +#: src/ch02-00-guessing-game-tutorial.md:152 +#: src/ch02-00-guessing-game-tutorial.md:176 +#: src/ch02-00-guessing-game-tutorial.md:201 +#: src/ch02-00-guessing-game-tutorial.md:266 +#: src/ch02-00-guessing-game-tutorial.md:318 +#: src/ch02-00-guessing-game-tutorial.md:406 +#: src/ch02-00-guessing-game-tutorial.md:666 +#: src/ch02-00-guessing-game-tutorial.md:763 +#: src/ch02-00-guessing-game-tutorial.md:883 +#: src/ch02-00-guessing-game-tutorial.md:1008 +#: src/ch02-00-guessing-game-tutorial.md:1101 +#: src/ch02-00-guessing-game-tutorial.md:1153 +#: src/ch02-00-guessing-game-tutorial.md:1260 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:308 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:361 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:399 +#: src/ch09-03-to-panic-or-not-to-panic.md:164 +#: src/ch19-04-advanced-types.md:233 +msgid "\"Please input your guess.\"" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:103 +#: src/ch02-00-guessing-game-tutorial.md:128 +#: src/ch02-00-guessing-game-tutorial.md:158 +#: src/ch02-00-guessing-game-tutorial.md:182 +#: src/ch02-00-guessing-game-tutorial.md:207 +#: src/ch02-00-guessing-game-tutorial.md:272 +#: src/ch02-00-guessing-game-tutorial.md:324 +#: src/ch02-00-guessing-game-tutorial.md:333 +#: src/ch02-00-guessing-game-tutorial.md:412 +#: src/ch02-00-guessing-game-tutorial.md:672 +#: src/ch02-00-guessing-game-tutorial.md:769 +#: src/ch02-00-guessing-game-tutorial.md:891 +#: src/ch02-00-guessing-game-tutorial.md:1017 +#: src/ch02-00-guessing-game-tutorial.md:1107 +#: src/ch02-00-guessing-game-tutorial.md:1161 +#: src/ch02-00-guessing-game-tutorial.md:1266 src/ch03-02-data-types.md:417 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:314 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:367 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:405 +#: src/ch09-03-to-panic-or-not-to-panic.md:170 +#: src/ch19-04-advanced-types.md:241 +msgid "\"Failed to read line\"" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:105 +#: src/ch02-00-guessing-game-tutorial.md:130 +#: src/ch02-00-guessing-game-tutorial.md:160 +#: src/ch02-00-guessing-game-tutorial.md:184 +#: src/ch02-00-guessing-game-tutorial.md:209 +#: src/ch02-00-guessing-game-tutorial.md:274 +#: src/ch02-00-guessing-game-tutorial.md:326 +#: src/ch02-00-guessing-game-tutorial.md:414 +msgid "\"You guessed: {}\"" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:111 +msgid "" +"This code contains a lot of information, so let’s go over it line by line. " +"To obtain user input and then print the result as output, we need to bring " +"the `io` input/output library into scope. The `io` library comes from the " +"standard library, known as `std`:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:134 +msgid "" +"By default, Rust has a set of items defined in the standard library that it " +"brings into the scope of every program. This set is called the _prelude_, " +"and you can see everything in it [in the standard library documentation](../" +"std/prelude/index.html)." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:138 +msgid "" +"If a type you want to use isn’t in the prelude, you have to bring that type " +"into scope explicitly with a `use` statement. Using the `std::io` library " +"provides you with a number of useful features, including the ability to " +"accept user input." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:143 +msgid "" +"As you saw in Chapter 1, the `main` function is the entry point into the " +"program:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:164 +msgid "" +"The `fn` syntax declares a new function; the parentheses, `()`, indicate " +"there are no parameters; and the curly bracket, `{`, starts the body of the " +"function." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:167 +msgid "" +"As you also learned in Chapter 1, `println!` is a macro that prints a string " +"to the screen:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:188 +msgid "" +"This code is printing a prompt stating what the game is and requesting input " +"from the user." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:191 +msgid "Storing Values with Variables" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:193 +msgid "Next, we’ll create a _variable_ to store the user input, like this:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:213 +msgid "" +"Now the program is getting interesting! There’s a lot going on in this " +"little line. We use the `let` statement to create the variable. Here’s " +"another example:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:220 +msgid "" +"This line creates a new variable named `apples` and binds it to the value 5. " +"In Rust, variables are immutable by default, meaning once we give the " +"variable a value, the value won’t change. We’ll be discussing this concept " +"in detail in the [“Variables and Mutability”](ch03-01-variables-and-" +"mutability.html#variables-and-mutability) section in Chapter " +"3. To make a variable mutable, we add `mut` before the variable name:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:228 +msgid "// immutable\n" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:229 +msgid "// mutable\n" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:232 +msgid "" +"Note: The `//` syntax starts a comment that continues until the end of the " +"line. Rust ignores everything in comments. We’ll discuss comments in more " +"detail in [Chapter 3](ch03-04-comments.html)." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:236 +msgid "" +"Returning to the guessing game program, you now know that `let mut guess` " +"will introduce a mutable variable named `guess`. The equal sign (`=`) tells " +"Rust we want to bind something to the variable now. On the right of the " +"equal sign is the value that `guess` is bound to, which is the result of " +"calling `String::new`, a function that returns a new instance of a `String`. " +"[`String`](../std/string/struct.String.html) is a string type " +"provided by the standard library that is a growable, UTF-8 encoded bit of " +"text." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:244 +msgid "" +"The `::` syntax in the `::new` line indicates that `new` is an associated " +"function of the `String` type. An _associated function_ is a function that’s " +"implemented on a type, in this case `String`. This `new` function creates a " +"new, empty string. You’ll find a `new` function on many types because it’s a " +"common name for a function that makes a new value of some kind." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:250 +msgid "" +"In full, the `let mut guess = String::new();` line has created a mutable " +"variable that is currently bound to a new, empty instance of a `String`. " +"Whew!" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:253 +msgid "Receiving User Input" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:255 +msgid "" +"Recall that we included the input/output functionality from the standard " +"library with `use std::io;` on the first line of the program. Now we’ll call " +"the `stdin` function from the `io` module, which will allow us to handle " +"user input:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:278 +msgid "" +"If we hadn’t imported the `io` library with `use std::io;` at the beginning " +"of the program, we could still use the function by writing this function " +"call as `std::io::stdin`. The `stdin` function returns an instance of [`std::" +"io::Stdin`](../std/io/struct.Stdin.html), which is a type " +"that represents a handle to the standard input for your terminal." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:284 +msgid "" +"Next, the line `.read_line(&mut guess)` calls the [`read_line`](../std/io/" +"struct.Stdin.html#method.read_line) method on the standard input handle to get input from the user. " +"We’re also passing `&mut guess` as the argument to `read_line` to tell it " +"what string to store the user input in. The full job of `read_line` is to " +"take whatever the user types into standard input and append that into a " +"string (without overwriting its contents), so we therefore pass that string " +"as an argument. The string argument needs to be mutable so the method can " +"change the string’s content." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:293 +msgid "" +"The `&` indicates that this argument is a _reference_, which gives you a way " +"to let multiple parts of your code access one piece of data without needing " +"to copy that data into memory multiple times. References are a complex " +"feature, and one of Rust’s major advantages is how safe and easy it is to " +"use references. You don’t need to know a lot of those details to finish this " +"program. For now, all you need to know is that, like variables, references " +"are immutable by default. Hence, you need to write `&mut guess` rather than " +"`&guess` to make it mutable. (Chapter 4 will explain references more " +"thoroughly.)" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:304 +msgid "" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:306 +msgid "Handling Potential Failure with `Result`" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:308 +msgid "" +"We’re still working on this line of code. We’re now discussing a third line " +"of text, but note that it’s still part of a single logical line of code. The " +"next part is this method:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:330 +msgid "We could have written this code as:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:336 +msgid "" +"However, one long line is difficult to read, so it’s best to divide it. It’s " +"often wise to introduce a newline and other whitespace to help break up long " +"lines when you call a method with the `.method_name()` syntax. Now let’s " +"discuss what this line does." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:341 +msgid "" +"As mentioned earlier, `read_line` puts whatever the user enters into the " +"string we pass to it, but it also returns a `Result` value. [`Result`](../" +"std/result/enum.Result.html) is an [_enumeration_](ch06-00-enums.html), often " +"called an _enum_, which is a type that can be in one of multiple possible " +"states. We call each possible state a _variant_." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:347 +msgid "" +"[Chapter 6](ch06-00-enums.html) will cover enums in more " +"detail. The purpose of these `Result` types is to encode error-handling " +"information." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:350 +msgid "" +"`Result`’s variants are `Ok` and `Err`. The `Ok` variant indicates the " +"operation was successful, and inside `Ok` is the successfully generated " +"value. The `Err` variant means the operation failed, and `Err` contains " +"information about how or why the operation failed." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:355 +msgid "" +"Values of the `Result` type, like values of any type, have methods defined " +"on them. An instance of `Result` has an [`expect` method](../std/result/enum." +"Result.html#method.expect) that you can call. If this " +"instance of `Result` is an `Err` value, `expect` will cause the program to " +"crash and display the message that you passed as an argument to `expect`. If " +"the `read_line` method returns an `Err`, it would likely be the result of an " +"error coming from the underlying operating system. If this instance of " +"`Result` is an `Ok` value, `expect` will take the return value that `Ok` is " +"holding and return just that value to you so you can use it. In this case, " +"that value is the number of bytes in the user’s input." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:365 +msgid "" +"If you don’t call `expect`, the program will compile, but you’ll get a " +"warning:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:367 +msgid "" +"```console\n" +"$ cargo build\n" +" Compiling guessing_game v0.1.0 (file:///projects/guessing_game)\n" +"warning: unused `Result` that must be used\n" +" --> src/main.rs:10:5\n" +" |\n" +"10 | io::stdin().read_line(&mut guess);\n" +" | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +" |\n" +" = note: this `Result` may be an `Err` variant, which should be handled\n" +" = note: `#[warn(unused_must_use)]` on by default\n" +"help: use `let _ = ...` to ignore the resulting value\n" +" |\n" +"10 | let _ = io::stdin().read_line(&mut guess);\n" +" | +++++++\n" +"\n" +"warning: `guessing_game` (bin \"guessing_game\") generated 1 warning\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.59s\n" +"```" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:387 +msgid "" +"Rust warns that you haven’t used the `Result` value returned from " +"`read_line`, indicating that the program hasn’t handled a possible error." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:390 +msgid "" +"The right way to suppress the warning is to actually write error-handling " +"code, but in our case we just want to crash this program when a problem " +"occurs, so we can use `expect`. You’ll learn about recovering from errors in " +"[Chapter 9](ch09-02-recoverable-errors-with-result.html)." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:395 +msgid "Printing Values with `println!` Placeholders" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:397 +msgid "" +"Aside from the closing curly bracket, there’s only one more line to discuss " +"in the code so far:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:418 +msgid "" +"This line prints the string that now contains the user’s input. The `{}` set " +"of curly brackets is a placeholder: think of `{}` as little crab pincers " +"that hold a value in place. When printing the value of a variable, the " +"variable name can go inside the curly brackets. When printing the result of " +"evaluating an expression, place empty curly brackets in the format string, " +"then follow the format string with a comma-separated list of expressions to " +"print in each empty curly bracket placeholder in the same order. Printing a " +"variable and the result of an expression in one call to `println!` would " +"look like this:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:431 +msgid "\"x = {x} and y + 2 = {}\"" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:434 +msgid "This code would print `x = 5 and y + 2 = 12`." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:436 +msgid "Testing the First Part" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:438 +msgid "" +"Let’s test the first part of the guessing game. Run it using `cargo run`:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:446 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling guessing_game v0.1.0 (file:///projects/guessing_game)\n" +" Finished dev [unoptimized + debuginfo] target(s) in 6.44s\n" +" Running `target/debug/guessing_game`\n" +"Guess the number!\n" +"Please input your guess.\n" +"6\n" +"You guessed: 6\n" +"```" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:457 +msgid "" +"At this point, the first part of the game is done: we’re getting input from " +"the keyboard and then printing it." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:460 +msgid "Generating a Secret Number" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:462 +msgid "" +"Next, we need to generate a secret number that the user will try to guess. " +"The secret number should be different every time so the game is fun to play " +"more than once. We’ll use a random number between 1 and 100 so the game " +"isn’t too difficult. Rust doesn’t yet include random number functionality in " +"its standard library. However, the Rust team does provide a [`rand` crate]" +"(https://crates.io/crates/rand) with said functionality." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:469 +msgid "Using a Crate to Get More Functionality" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:471 +msgid "" +"Remember that a crate is a collection of Rust source code files. The project " +"we’ve been building is a _binary crate_, which is an executable. The `rand` " +"crate is a _library crate_, which contains code that is intended to be used " +"in other programs and can’t be executed on its own." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:476 +msgid "" +"Cargo’s coordination of external crates is where Cargo really shines. Before " +"we can write code that uses `rand`, we need to modify the _Cargo.toml_ file " +"to include the `rand` crate as a dependency. Open that file now and add the " +"following line to the bottom, beneath the `[dependencies]` section header " +"that Cargo created for you. Be sure to specify `rand` exactly as we have " +"here, with this version number, or the code examples in this tutorial may " +"not work:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:491 +#: src/ch14-03-cargo-workspaces.md:225 +msgid "" +"```toml\n" +"[dependencies]\n" +"rand = \"0.8.5\"\n" +"```" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:496 +msgid "" +"In the _Cargo.toml_ file, everything that follows a header is part of that " +"section that continues until another section starts. In `[dependencies]` you " +"tell Cargo which external crates your project depends on and which versions " +"of those crates you require. In this case, we specify the `rand` crate with " +"the semantic version specifier `0.8.5`. Cargo understands [Semantic " +"Versioning](http://semver.org) (sometimes called _SemVer_), " +"which is a standard for writing version numbers. The specifier `0.8.5` is " +"actually shorthand for `^0.8.5`, which means any version that is at least " +"0.8.5 but below 0.9.0." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:506 +msgid "" +"Cargo considers these versions to have public APIs compatible with version " +"0.8.5, and this specification ensures you’ll get the latest patch release " +"that will still compile with the code in this chapter. Any version 0.9.0 or " +"greater is not guaranteed to have the same API as what the following " +"examples use." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:511 +msgid "" +"Now, without changing any of the code, let’s build the project, as shown in " +"Listing 2-2." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:522 +msgid "" +"```console\n" +"$ cargo build\n" +" Updating crates.io index\n" +" Downloaded rand v0.8.5\n" +" Downloaded libc v0.2.127\n" +" Downloaded getrandom v0.2.7\n" +" Downloaded cfg-if v1.0.0\n" +" Downloaded ppv-lite86 v0.2.16\n" +" Downloaded rand_chacha v0.3.1\n" +" Downloaded rand_core v0.6.3\n" +" Compiling libc v0.2.127\n" +" Compiling getrandom v0.2.7\n" +" Compiling cfg-if v1.0.0\n" +" Compiling ppv-lite86 v0.2.16\n" +" Compiling rand_core v0.6.3\n" +" Compiling rand_chacha v0.3.1\n" +" Compiling rand v0.8.5\n" +" Compiling guessing_game v0.1.0 (file:///projects/guessing_game)\n" +" Finished dev [unoptimized + debuginfo] target(s) in 2.53s\n" +"```" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:545 +msgid "" +"You may see different version numbers (but they will all be compatible with " +"the code, thanks to SemVer!) and different lines (depending on the operating " +"system), and the lines may be in a different order." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:549 +msgid "" +"When we include an external dependency, Cargo fetches the latest versions of " +"everything that dependency needs from the _registry_, which is a copy of " +"data from [Crates.io](https://crates.io/). Crates.io is where people in the " +"Rust ecosystem post their open source Rust projects for others to use." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:554 +msgid "" +"After updating the registry, Cargo checks the `[dependencies]` section and " +"downloads any crates listed that aren’t already downloaded. In this case, " +"although we only listed `rand` as a dependency, Cargo also grabbed other " +"crates that `rand` depends on to work. After downloading the crates, Rust " +"compiles them and then compiles the project with the dependencies available." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:560 +msgid "" +"If you immediately run `cargo build` again without making any changes, you " +"won’t get any output aside from the `Finished` line. Cargo knows it has " +"already downloaded and compiled the dependencies, and you haven’t changed " +"anything about them in your _Cargo.toml_ file. Cargo also knows that you " +"haven’t changed anything about your code, so it doesn’t recompile that " +"either. With nothing to do, it simply exits." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:567 +msgid "" +"If you open the _src/main.rs_ file, make a trivial change, and then save it " +"and build again, you’ll only see two lines of output:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:575 +msgid "" +"```console\n" +"$ cargo build\n" +" Compiling guessing_game v0.1.0 (file:///projects/guessing_game)\n" +" Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs\n" +"```" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:581 +msgid "" +"These lines show that Cargo only updates the build with your tiny change to " +"the _src/main.rs_ file. Your dependencies haven’t changed, so Cargo knows it " +"can reuse what it has already downloaded and compiled for those." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:585 +msgid "Ensuring Reproducible Builds with the _Cargo.lock_ File" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:587 +msgid "" +"Cargo has a mechanism that ensures you can rebuild the same artifact every " +"time you or anyone else builds your code: Cargo will use only the versions " +"of the dependencies you specified until you indicate otherwise. For example, " +"say that next week version 0.8.6 of the `rand` crate comes out, and that " +"version contains an important bug fix, but it also contains a regression " +"that will break your code. To handle this, Rust creates the _Cargo.lock_ " +"file the first time you run `cargo build`, so we now have this in the " +"_guessing_game_ directory." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:596 +msgid "" +"When you build a project for the first time, Cargo figures out all the " +"versions of the dependencies that fit the criteria and then writes them to " +"the _Cargo.lock_ file. When you build your project in the future, Cargo will " +"see that the _Cargo.lock_ file exists and will use the versions specified " +"there rather than doing all the work of figuring out versions again. This " +"lets you have a reproducible build automatically. In other words, your " +"project will remain at 0.8.5 until you explicitly upgrade, thanks to the " +"_Cargo.lock_ file. Because the _Cargo.lock_ file is important for " +"reproducible builds, it’s often checked into source control with the rest of " +"the code in your project." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:606 +msgid "Updating a Crate to Get a New Version" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:608 +msgid "" +"When you _do_ want to update a crate, Cargo provides the command `update`, " +"which will ignore the _Cargo.lock_ file and figure out all the latest " +"versions that fit your specifications in _Cargo.toml_. Cargo will then write " +"those versions to the _Cargo.lock_ file. In this case, Cargo will only look " +"for versions greater than 0.8.5 and less than 0.9.0. If the `rand` crate has " +"released the two new versions 0.8.6 and 0.9.0, you would see the following " +"if you ran `cargo update`:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:628 +msgid "" +"Cargo ignores the 0.9.0 release. At this point, you would also notice a " +"change in your _Cargo.lock_ file noting that the version of the `rand` crate " +"you are now using is 0.8.6. To use `rand` version 0.9.0 or any version in " +"the 0.9._x_ series, you’d have to update the _Cargo.toml_ file to look like " +"this instead:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:633 +msgid "" +"```toml\n" +"[dependencies]\n" +"rand = \"0.9.0\"\n" +"```" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:638 +msgid "" +"The next time you run `cargo build`, Cargo will update the registry of " +"crates available and reevaluate your `rand` requirements according to the " +"new version you have specified." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:642 +msgid "" +"There’s a lot more to say about [Cargo](https://doc.rust-lang.org/" +"cargo/) and [its ecosystem](https://doc.rust-lang.org/cargo/" +"reference/publishing.html), which we’ll discuss in Chapter " +"14, but for now, that’s all you need to know. Cargo makes it very easy to " +"reuse libraries, so Rustaceans are able to write smaller projects that are " +"assembled from a number of packages." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:648 +msgid "Generating a Random Number" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:650 +msgid "" +"Let’s start using `rand` to generate a number to guess. The next step is to " +"update _src/main.rs_, as shown in Listing 2-3." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:664 +#: src/ch02-00-guessing-game-tutorial.md:761 +#: src/ch02-00-guessing-game-tutorial.md:881 +#: src/ch02-00-guessing-game-tutorial.md:1005 +#: src/ch02-00-guessing-game-tutorial.md:1098 +#: src/ch02-00-guessing-game-tutorial.md:1150 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:306 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:359 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:397 +#: src/ch19-04-advanced-types.md:230 +msgid "\"The secret number is: {secret_number}\"" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:674 +#: src/ch02-00-guessing-game-tutorial.md:771 +#: src/ch02-00-guessing-game-tutorial.md:895 +#: src/ch02-00-guessing-game-tutorial.md:1021 +#: src/ch02-00-guessing-game-tutorial.md:1111 +#: src/ch02-00-guessing-game-tutorial.md:1168 +#: src/ch02-00-guessing-game-tutorial.md:1273 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:316 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:369 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:409 +#: src/ch19-04-advanced-types.md:248 +msgid "\"You guessed: {guess}\"" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:680 +msgid "" +"First we add the line `use rand::Rng;`. The `Rng` trait defines methods that " +"random number generators implement, and this trait must be in scope for us " +"to use those methods. Chapter 10 will cover traits in detail." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:684 +msgid "" +"Next, we’re adding two lines in the middle. In the first line, we call the " +"`rand::thread_rng` function that gives us the particular random number " +"generator we’re going to use: one that is local to the current thread of " +"execution and is seeded by the operating system. Then we call the " +"`gen_range` method on the random number generator. This method is defined by " +"the `Rng` trait that we brought into scope with the `use rand::Rng;` " +"statement. The `gen_range` method takes a range expression as an argument " +"and generates a random number in the range. The kind of range expression " +"we’re using here takes the form `start..=end` and is inclusive on the lower " +"and upper bounds, so we need to specify `1..=100` to request a number " +"between 1 and 100." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:695 +msgid "" +"Note: You won’t just know which traits to use and which methods and " +"functions to call from a crate, so each crate has documentation with " +"instructions for using it. Another neat feature of Cargo is that running the " +"`cargo doc --open` command will build documentation provided by all your " +"dependencies locally and open it in your browser. If you’re interested in " +"other functionality in the `rand` crate, for example, run `cargo doc --open` " +"and click `rand` in the sidebar on the left." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:703 +msgid "" +"The second new line prints the secret number. This is useful while we’re " +"developing the program to be able to test it, but we’ll delete it from the " +"final version. It’s not much of a game if the program prints the answer as " +"soon as it starts!" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:708 +msgid "Try running the program a few times:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:718 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling guessing_game v0.1.0 (file:///projects/guessing_game)\n" +" Finished dev [unoptimized + debuginfo] target(s) in 2.53s\n" +" Running `target/debug/guessing_game`\n" +"Guess the number!\n" +"The secret number is: 7\n" +"Please input your guess.\n" +"4\n" +"You guessed: 4\n" +"\n" +"$ cargo run\n" +" Finished dev [unoptimized + debuginfo] target(s) in 0.02s\n" +" Running `target/debug/guessing_game`\n" +"Guess the number!\n" +"The secret number is: 83\n" +"Please input your guess.\n" +"5\n" +"You guessed: 5\n" +"```" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:739 +msgid "" +"You should get different random numbers, and they should all be numbers " +"between 1 and 100. Great job!" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:742 +msgid "Comparing the Guess to the Secret Number" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:744 +msgid "" +"Now that we have user input and a random number, we can compare them. That " +"step is shown in Listing 2-4. Note that this code won’t compile just yet, as " +"we will explain." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:756 +#: src/ch02-00-guessing-game-tutorial.md:885 +#: src/ch02-00-guessing-game-tutorial.md:1003 +#: src/ch02-00-guessing-game-tutorial.md:1010 +#: src/ch02-00-guessing-game-tutorial.md:1113 +#: src/ch02-00-guessing-game-tutorial.md:1157 +#: src/ch02-00-guessing-game-tutorial.md:1170 +#: src/ch05-01-defining-structs.md:207 src/ch05-01-defining-structs.md:243 +#: src/ch06-01-defining-an-enum.md:207 src/ch06-01-defining-an-enum.md:211 +#: src/ch06-02-match.md:118 src/ch06-02-match.md:149 src/ch06-03-if-let.md:70 +#: src/ch06-03-if-let.md:97 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:169 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:174 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:201 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:206 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:348 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:351 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:387 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:389 +#: src/ch09-03-to-panic-or-not-to-panic.md:162 +#: src/ch09-03-to-panic-or-not-to-panic.md:183 src/ch10-02-traits.md:645 +#: src/ch11-01-writing-tests.md:407 src/ch11-01-writing-tests.md:471 +#: src/ch11-01-writing-tests.md:914 src/ch11-01-writing-tests.md:981 +#: src/ch12-02-reading-a-file.md:36 +#: src/ch12-03-improving-error-handling-and-modularity.md:84 +#: src/ch12-03-improving-error-handling-and-modularity.md:155 +#: src/ch12-03-improving-error-handling-and-modularity.md:252 +#: src/ch12-03-improving-error-handling-and-modularity.md:254 +#: src/ch12-03-improving-error-handling-and-modularity.md:332 +#: src/ch12-03-improving-error-handling-and-modularity.md:337 +#: src/ch12-03-improving-error-handling-and-modularity.md:478 +#: src/ch12-03-improving-error-handling-and-modularity.md:564 +#: src/ch12-03-improving-error-handling-and-modularity.md:585 +#: src/ch12-03-improving-error-handling-and-modularity.md:630 +#: src/ch12-03-improving-error-handling-and-modularity.md:758 +#: src/ch12-03-improving-error-handling-and-modularity.md:844 +#: src/ch12-03-improving-error-handling-and-modularity.md:857 +#: src/ch12-03-improving-error-handling-and-modularity.md:884 +#: src/ch12-03-improving-error-handling-and-modularity.md:896 +#: src/ch12-05-working-with-environment-variables.md:496 +#: src/ch13-03-improving-our-io-project.md:165 +#: src/ch13-03-improving-our-io-project.md:192 +#: src/ch13-03-improving-our-io-project.md:230 +#: src/ch14-02-publishing-to-crates-io.md:232 +#: src/ch14-02-publishing-to-crates-io.md:297 +#: src/ch14-02-publishing-to-crates-io.md:314 +#: src/ch14-02-publishing-to-crates-io.md:347 +#: src/ch15-05-interior-mutability.md:412 src/ch16-02-message-passing.md:306 +#: src/ch16-02-message-passing.md:343 src/ch17-03-oo-design-patterns.md:160 +#: src/ch17-03-oo-design-patterns.md:211 src/ch17-03-oo-design-patterns.md:255 +#: src/ch17-03-oo-design-patterns.md:362 src/ch17-03-oo-design-patterns.md:399 +#: src/ch17-03-oo-design-patterns.md:412 src/ch17-03-oo-design-patterns.md:463 +#: src/ch17-03-oo-design-patterns.md:478 src/ch17-03-oo-design-patterns.md:602 +#: src/ch17-03-oo-design-patterns.md:610 src/ch17-03-oo-design-patterns.md:640 +#: src/ch17-03-oo-design-patterns.md:863 src/ch19-03-advanced-traits.md:67 +#: src/ch19-04-advanced-types.md:95 src/ch19-04-advanced-types.md:99 +#: src/ch19-04-advanced-types.md:118 src/ch19-04-advanced-types.md:122 +#: src/ch19-04-advanced-types.md:207 src/ch19-04-advanced-types.md:237 +#: src/ch19-04-advanced-types.md:250 src/ch19-04-advanced-types.md:402 +#: src/ch19-04-advanced-types.md:410 src/ch19-04-advanced-types.md:420 +#: src/ch19-06-macros.md:375 src/ch20-01-single-threaded.md:396 +#: src/ch20-01-single-threaded.md:479 src/ch20-01-single-threaded.md:563 +#: src/ch20-01-single-threaded.md:638 src/ch20-01-single-threaded.md:642 +#: src/ch20-02-multithreaded.md:27 src/ch20-02-multithreaded.md:41 +#: src/ch20-02-multithreaded.md:55 src/ch20-02-multithreaded.md:463 +#: src/ch20-02-multithreaded.md:532 src/ch20-02-multithreaded.md:597 +#: src/ch20-02-multithreaded.md:616 src/ch20-02-multithreaded.md:695 +#: src/ch20-02-multithreaded.md:714 src/ch20-02-multithreaded.md:805 +#: src/ch20-02-multithreaded.md:826 src/ch20-02-multithreaded.md:873 +#: src/ch20-02-multithreaded.md:894 src/ch20-02-multithreaded.md:902 +#: src/ch20-02-multithreaded.md:982 src/ch20-02-multithreaded.md:993 +#: src/ch20-02-multithreaded.md:1017 src/ch20-02-multithreaded.md:1025 +#: src/ch20-02-multithreaded.md:1035 src/ch20-02-multithreaded.md:1075 +#: src/ch20-02-multithreaded.md:1081 src/ch20-02-multithreaded.md:1114 +#: src/ch20-02-multithreaded.md:1204 src/ch20-02-multithreaded.md:1356 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:333 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:475 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:489 +msgid "// --snip--\n" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:774 +#: src/ch02-00-guessing-game-tutorial.md:898 +#: src/ch02-00-guessing-game-tutorial.md:1024 +#: src/ch02-00-guessing-game-tutorial.md:1116 +#: src/ch02-00-guessing-game-tutorial.md:1173 +#: src/ch02-00-guessing-game-tutorial.md:1276 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:372 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:412 +#: src/ch09-03-to-panic-or-not-to-panic.md:184 +#: src/ch19-04-advanced-types.md:253 +msgid "\"Too small!\"" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:775 +#: src/ch02-00-guessing-game-tutorial.md:899 +#: src/ch02-00-guessing-game-tutorial.md:1025 +#: src/ch02-00-guessing-game-tutorial.md:1117 +#: src/ch02-00-guessing-game-tutorial.md:1174 +#: src/ch02-00-guessing-game-tutorial.md:1277 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:373 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:413 +#: src/ch09-03-to-panic-or-not-to-panic.md:185 +#: src/ch19-04-advanced-types.md:254 +msgid "\"Too big!\"" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:776 +#: src/ch02-00-guessing-game-tutorial.md:900 +#: src/ch02-00-guessing-game-tutorial.md:1026 +#: src/ch02-00-guessing-game-tutorial.md:1119 +#: src/ch02-00-guessing-game-tutorial.md:1176 +#: src/ch02-00-guessing-game-tutorial.md:1279 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:374 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:414 +#: src/ch09-03-to-panic-or-not-to-panic.md:187 +#: src/ch19-04-advanced-types.md:256 +msgid "\"You win!\"" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:783 +msgid "" +"First we add another `use` statement, bringing a type called `std::cmp::" +"Ordering` into scope from the standard library. The `Ordering` type is " +"another enum and has the variants `Less`, `Greater`, and `Equal`. These are " +"the three outcomes that are possible when you compare two values." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:788 +msgid "" +"Then we add five new lines at the bottom that use the `Ordering` type. The " +"`cmp` method compares two values and can be called on anything that can be " +"compared. It takes a reference to whatever you want to compare with: here " +"it’s comparing `guess` to `secret_number`. Then it returns a variant of the " +"`Ordering` enum we brought into scope with the `use` statement. We use a " +"[`match`](ch06-02-match.html) expression to decide what to do " +"next based on which variant of `Ordering` was returned from the call to " +"`cmp` with the values in `guess` and `secret_number`." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:797 +msgid "" +"A `match` expression is made up of _arms_. An arm consists of a _pattern_ to " +"match against, and the code that should be run if the value given to `match` " +"fits that arm’s pattern. Rust takes the value given to `match` and looks " +"through each arm’s pattern in turn. Patterns and the `match` construct are " +"powerful Rust features: they let you express a variety of situations your " +"code might encounter and they make sure you handle them all. These features " +"will be covered in detail in Chapter 6 and Chapter 18, respectively." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:805 +msgid "" +"Let’s walk through an example with the `match` expression we use here. Say " +"that the user has guessed 50 and the randomly generated secret number this " +"time is 38." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:809 +msgid "" +"When the code compares 50 to 38, the `cmp` method will return `Ordering::" +"Greater` because 50 is greater than 38. The `match` expression gets the " +"`Ordering::Greater` value and starts checking each arm’s pattern. It looks " +"at the first arm’s pattern, `Ordering::Less`, and sees that the value " +"`Ordering::Greater` does not match `Ordering::Less`, so it ignores the code " +"in that arm and moves to the next arm. The next arm’s pattern is `Ordering::" +"Greater`, which _does_ match `Ordering::Greater`! The associated code in " +"that arm will execute and print `Too big!` to the screen. The `match` " +"expression ends after the first successful match, so it won’t look at the " +"last arm in this scenario." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:820 +msgid "However, the code in Listing 2-4 won’t compile yet. Let’s try it:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:827 +msgid "" +"```console\n" +"$ cargo build\n" +" Compiling libc v0.2.86\n" +" Compiling getrandom v0.2.2\n" +" Compiling cfg-if v1.0.0\n" +" Compiling ppv-lite86 v0.2.10\n" +" Compiling rand_core v0.6.2\n" +" Compiling rand_chacha v0.3.0\n" +" Compiling rand v0.8.5\n" +" Compiling guessing_game v0.1.0 (file:///projects/guessing_game)\n" +"error[E0308]: mismatched types\n" +" --> src/main.rs:22:21\n" +" |\n" +"22 | match guess.cmp(&secret_number) {\n" +" | --- ^^^^^^^^^^^^^^ expected `&String`, found `&{integer}" +"`\n" +" | |\n" +" | arguments to this method are incorrect\n" +" |\n" +" = note: expected reference `&String`\n" +" found reference `&{integer}`\n" +"note: method defined here\n" +" --> /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/cmp." +"rs:840:8\n" +"\n" +"For more information about this error, try `rustc --explain E0308`.\n" +"error: could not compile `guessing_game` (bin \"guessing_game\") due to 1 " +"previous error\n" +"```" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:854 +msgid "" +"The core of the error states that there are _mismatched types_. Rust has a " +"strong, static type system. However, it also has type inference. When we " +"wrote `let mut guess = String::new()`, Rust was able to infer that `guess` " +"should be a `String` and didn’t make us write the type. The `secret_number`, " +"on the other hand, is a number type. A few of Rust’s number types can have a " +"value between 1 and 100: `i32`, a 32-bit number; `u32`, an unsigned 32-bit " +"number; `i64`, a 64-bit number; as well as others. Unless otherwise " +"specified, Rust defaults to an `i32`, which is the type of `secret_number` " +"unless you add type information elsewhere that would cause Rust to infer a " +"different numerical type. The reason for the error is that Rust cannot " +"compare a string and a number type." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:865 +msgid "" +"Ultimately, we want to convert the `String` the program reads as input into " +"a number type so we can compare it numerically to the secret number. We do " +"so by adding this line to the `main` function body:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:893 +#: src/ch02-00-guessing-game-tutorial.md:908 +#: src/ch02-00-guessing-game-tutorial.md:1019 +#: src/ch02-00-guessing-game-tutorial.md:1109 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:407 +msgid "\"Please type a number!\"" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:905 +msgid "The line is:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:911 +msgid "" +"We create a variable named `guess`. But wait, doesn’t the program already " +"have a variable named `guess`? It does, but helpfully Rust allows us to " +"shadow the previous value of `guess` with a new one. _Shadowing_ lets us " +"reuse the `guess` variable name rather than forcing us to create two unique " +"variables, such as `guess_str` and `guess`, for example. We’ll cover this in " +"more detail in [Chapter 3](ch03-01-variables-and-mutability." +"html#shadowing), but for now, know that this feature is often " +"used when you want to convert a value from one type to another type." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:919 +msgid "" +"We bind this new variable to the expression `guess.trim().parse()`. The " +"`guess` in the expression refers to the original `guess` variable that " +"contained the input as a string. The `trim` method on a `String` instance " +"will eliminate any whitespace at the beginning and end, which we must do to " +"be able to compare the string to the `u32`, which can only contain numerical " +"data. The user must press enter to satisfy `read_line` and input " +"their guess, which adds a newline character to the string. For example, if " +"the user types 5 and presses enter, `guess` looks like " +"this: `5\\n`. The `\\n` represents “newline.” (On Windows, pressing " +"enter results in a carriage return and a newline, `\\r\\n`.) The " +"`trim` method eliminates `\\n` or `\\r\\n`, resulting in just `5`." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:931 +msgid "" +"The [`parse` method on strings](../std/primitive.str.html#method.parse) converts a string to another type. Here, we use it to convert " +"from a string to a number. We need to tell Rust the exact number type we " +"want by using `let guess: u32`. The colon (`:`) after `guess` tells Rust " +"we’ll annotate the variable’s type. Rust has a few built-in number types; " +"the `u32` seen here is an unsigned, 32-bit integer. It’s a good default " +"choice for a small positive number. You’ll learn about other number types in " +"[Chapter 3](ch03-02-data-types.html#integer-types)." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:939 +msgid "" +"Additionally, the `u32` annotation in this example program and the " +"comparison with `secret_number` means Rust will infer that `secret_number` " +"should be a `u32` as well. So now the comparison will be between two values " +"of the same type!" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:944 +msgid "" +"The `parse` method will only work on characters that can logically be " +"converted into numbers and so can easily cause errors. If, for example, the " +"string contained `A👍%`, there would be no way to convert that to a number. " +"Because it might fail, the `parse` method returns a `Result` type, much as " +"the `read_line` method does (discussed earlier in [“Handling Potential " +"Failure with `Result`”](#handling-potential-failure-with-result): if the user enters a non-number answer, the program " +"will crash. We can take advantage of that to allow the user to quit, as " +"shown here:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1053 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling guessing_game v0.1.0 (file:///projects/guessing_game)\n" +" Finished dev [unoptimized + debuginfo] target(s) in 1.50s\n" +" Running `target/debug/guessing_game`\n" +"Guess the number!\n" +"The secret number is: 59\n" +"Please input your guess.\n" +"45\n" +"You guessed: 45\n" +"Too small!\n" +"Please input your guess.\n" +"60\n" +"You guessed: 60\n" +"Too big!\n" +"Please input your guess.\n" +"59\n" +"You guessed: 59\n" +"You win!\n" +"Please input your guess.\n" +"quit\n" +"thread 'main' panicked at 'Please type a number!: ParseIntError { kind: " +"InvalidDigit }', src/main.rs:28:47\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"```" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1078 +msgid "" +"Typing `quit` will quit the game, but as you’ll notice, so will entering any " +"other non-number input. This is suboptimal, to say the least; we want the " +"game to also stop when the correct number is guessed." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1082 +msgid "Quitting After a Correct Guess" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1084 +msgid "" +"Let’s program the game to quit when the user wins by adding a `break` " +"statement:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1127 +msgid "" +"Adding the `break` line after `You win!` makes the program exit the loop " +"when the user guesses the secret number correctly. Exiting the loop also " +"means exiting the program, because the loop is the last part of `main`." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1131 +msgid "Handling Invalid Input" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1133 +msgid "" +"To further refine the game’s behavior, rather than crashing the program when " +"the user inputs a non-number, let’s make the game ignore a non-number so the " +"user can continue guessing. We can do that by altering the line where " +"`guess` is converted from a `String` to a `u32`, as shown in Listing 2-5." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1186 +msgid "" +"We switch from an `expect` call to a `match` expression to move from " +"crashing on an error to handling the error. Remember that `parse` returns a " +"`Result` type and `Result` is an enum that has the variants `Ok` and `Err`. " +"We’re using a `match` expression here, as we did with the `Ordering` result " +"of the `cmp` method." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1192 +msgid "" +"If `parse` is able to successfully turn the string into a number, it will " +"return an `Ok` value that contains the resultant number. That `Ok` value " +"will match the first arm’s pattern, and the `match` expression will just " +"return the `num` value that `parse` produced and put inside the `Ok` value. " +"That number will end up right where we want it in the new `guess` variable " +"we’re creating." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1198 +msgid "" +"If `parse` is _not_ able to turn the string into a number, it will return an " +"`Err` value that contains more information about the error. The `Err` value " +"does not match the `Ok(num)` pattern in the first `match` arm, but it does " +"match the `Err(_)` pattern in the second arm. The underscore, `_`, is a " +"catchall value; in this example, we’re saying we want to match all `Err` " +"values, no matter what information they have inside them. So the program " +"will execute the second arm’s code, `continue`, which tells the program to " +"go to the next iteration of the `loop` and ask for another guess. So, " +"effectively, the program ignores all errors that `parse` might encounter!" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1208 +msgid "Now everything in the program should work as expected. Let’s try it:" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1219 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling guessing_game v0.1.0 (file:///projects/guessing_game)\n" +" Finished dev [unoptimized + debuginfo] target(s) in 4.45s\n" +" Running `target/debug/guessing_game`\n" +"Guess the number!\n" +"The secret number is: 61\n" +"Please input your guess.\n" +"10\n" +"You guessed: 10\n" +"Too small!\n" +"Please input your guess.\n" +"99\n" +"You guessed: 99\n" +"Too big!\n" +"Please input your guess.\n" +"foo\n" +"Please input your guess.\n" +"61\n" +"You guessed: 61\n" +"You win!\n" +"```" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1242 +msgid "" +"Awesome! With one tiny final tweak, we will finish the guessing game. Recall " +"that the program is still printing the secret number. That worked well for " +"testing, but it ruins the game. Let’s delete the `println!` that outputs the " +"secret number. Listing 2-6 shows the final code." +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1289 +msgid "" +"At this point, you’ve successfully built the guessing game. Congratulations!" +msgstr "" + +#: src/ch02-00-guessing-game-tutorial.md:1293 +msgid "" +"This project was a hands-on way to introduce you to many new Rust concepts: " +"`let`, `match`, functions, the use of external crates, and more. In the next " +"few chapters, you’ll learn about these concepts in more detail. Chapter 3 " +"covers concepts that most programming languages have, such as variables, " +"data types, and functions, and shows how to use them in Rust. Chapter 4 " +"explores ownership, a feature that makes Rust different from other " +"languages. Chapter 5 discusses structs and method syntax, and Chapter 6 " +"explains how enums work." +msgstr "" + +#: src/ch03-00-common-programming-concepts.md:3 +msgid "" +"This chapter covers concepts that appear in almost every programming " +"language and how they work in Rust. Many programming languages have much in " +"common at their core. None of the concepts presented in this chapter are " +"unique to Rust, but we’ll discuss them in the context of Rust and explain " +"the conventions around using these concepts." +msgstr "" + +#: src/ch03-00-common-programming-concepts.md:9 +msgid "" +"Specifically, you’ll learn about variables, basic types, functions, " +"comments, and control flow. These foundations will be in every Rust program, " +"and learning them early will give you a strong core to start from." +msgstr "" + +#: src/ch03-00-common-programming-concepts.md:13 +msgid "Keywords" +msgstr "" + +#: src/ch03-00-common-programming-concepts.md:15 +msgid "" +"The Rust language has a set of _keywords_ that are reserved for use by the " +"language only, much as in other languages. Keep in mind that you cannot use " +"these words as names of variables or functions. Most of the keywords have " +"special meanings, and you’ll be using them to do various tasks in your Rust " +"programs; a few have no current functionality associated with them but have " +"been reserved for functionality that might be added to Rust in the future. " +"You can find a list of the keywords in [Appendix A](appendix-01-keywords." +"md)." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:3 +msgid "" +"As mentioned in the [“Storing Values with Variables”](ch02-00-guessing-game-" +"tutorial.html#storing-values-with-variables) section, by " +"default, variables are immutable. This is one of many nudges Rust gives you " +"to write your code in a way that takes advantage of the safety and easy " +"concurrency that Rust offers. However, you still have the option to make " +"your variables mutable. Let’s explore how and why Rust encourages you to " +"favor immutability and why sometimes you might want to opt out." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:11 +msgid "" +"When a variable is immutable, once a value is bound to a name, you can’t " +"change that value. To illustrate this, generate a new project called " +"_variables_ in your _projects_ directory by using `cargo new variables`." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:15 +msgid "" +"Then, in your new _variables_ directory, open _src/main.rs_ and replace its " +"code with the following code, which won’t compile just yet:" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:23 +#: src/ch03-01-variables-and-mutability.md:25 +#: src/ch03-01-variables-and-mutability.md:84 +#: src/ch03-01-variables-and-mutability.md:86 +#: src/ch03-01-variables-and-mutability.md:177 +#: src/ch03-03-how-functions-work.md:74 src/ch03-03-how-functions-work.md:271 +#: src/ch03-03-how-functions-work.md:310 src/ch03-03-how-functions-work.md:328 +msgid "\"The value of x is: {x}\"" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:29 +msgid "" +"Save and run the program using `cargo run`. You should receive an error " +"message regarding an immutability error, as shown in this output:" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:32 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling variables v0.1.0 (file:///projects/variables)\n" +"error[E0384]: cannot assign twice to immutable variable `x`\n" +" --> src/main.rs:4:5\n" +" |\n" +"2 | let x = 5;\n" +" | -\n" +" | |\n" +" | first assignment to `x`\n" +" | help: consider making this binding mutable: `mut x`\n" +"3 | println!(\"The value of x is: {x}\");\n" +"4 | x = 6;\n" +" | ^^^^^ cannot assign twice to immutable variable\n" +"\n" +"For more information about this error, try `rustc --explain E0384`.\n" +"error: could not compile `variables` (bin \"variables\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:51 +msgid "" +"This example shows how the compiler helps you find errors in your programs. " +"Compiler errors can be frustrating, but really they only mean your program " +"isn’t safely doing what you want it to do yet; they do _not_ mean that " +"you’re not a good programmer! Experienced Rustaceans still get compiler " +"errors." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:56 +msgid "" +"You received the error message `` cannot assign twice to immutable variable " +"`x` `` because you tried to assign a second value to the immutable `x` " +"variable." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:59 +msgid "" +"It’s important that we get compile-time errors when we attempt to change a " +"value that’s designated as immutable because this very situation can lead to " +"bugs. If one part of our code operates on the assumption that a value will " +"never change and another part of our code changes that value, it’s possible " +"that the first part of the code won’t do what it was designed to do. The " +"cause of this kind of bug can be difficult to track down after the fact, " +"especially when the second piece of code changes the value only _sometimes_. " +"The Rust compiler guarantees that when you state that a value won’t change, " +"it really won’t change, so you don’t have to keep track of it yourself. Your " +"code is thus easier to reason through." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:70 +msgid "" +"But mutability can be very useful, and can make code more convenient to " +"write. Although variables are immutable by default, you can make them " +"mutable by adding `mut` in front of the variable name as you did in [Chapter " +"2](ch02-00-guessing-game-tutorial.html#storing-values-with-variables). Adding `mut` also conveys intent to future readers of the code " +"by indicating that other parts of the code will be changing this variable’s " +"value." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:77 +msgid "For example, let’s change _src/main.rs_ to the following:" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:90 +msgid "When we run the program now, we get this:" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:92 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling variables v0.1.0 (file:///projects/variables)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.30s\n" +" Running `target/debug/variables`\n" +"The value of x is: 5\n" +"The value of x is: 6\n" +"```" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:101 +msgid "" +"We’re allowed to change the value bound to `x` from `5` to `6` when `mut` is " +"used. Ultimately, deciding whether to use mutability or not is up to you and " +"depends on what you think is clearest in that particular situation." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:105 +msgid "Constants" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:107 +msgid "" +"Like immutable variables, _constants_ are values that are bound to a name " +"and are not allowed to change, but there are a few differences between " +"constants and variables." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:111 +msgid "" +"First, you aren’t allowed to use `mut` with constants. Constants aren’t just " +"immutable by default—they’re always immutable. You declare constants using " +"the `const` keyword instead of the `let` keyword, and the type of the value " +"_must_ be annotated. We’ll cover types and type annotations in the next " +"section, [“Data Types”](ch03-02-data-types.html#data-types), " +"so don’t worry about the details right now. Just know that you must always " +"annotate the type." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:118 +msgid "" +"Constants can be declared in any scope, including the global scope, which " +"makes them useful for values that many parts of code need to know about." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:121 +msgid "" +"The last difference is that constants may be set only to a constant " +"expression, not the result of a value that could only be computed at runtime." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:124 +msgid "Here’s an example of a constant declaration:" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:130 +msgid "" +"The constant’s name is `THREE_HOURS_IN_SECONDS` and its value is set to the " +"result of multiplying 60 (the number of seconds in a minute) by 60 (the " +"number of minutes in an hour) by 3 (the number of hours we want to count in " +"this program). Rust’s naming convention for constants is to use all " +"uppercase with underscores between words. The compiler is able to evaluate a " +"limited set of operations at compile time, which lets us choose to write out " +"this value in a way that’s easier to understand and verify, rather than " +"setting this constant to the value 10,800. See the [Rust Reference’s section " +"on constant evaluation](../reference/const_eval.html) for more information " +"on what operations can be used when declaring constants." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:141 +msgid "" +"Constants are valid for the entire time a program runs, within the scope in " +"which they were declared. This property makes constants useful for values in " +"your application domain that multiple parts of the program might need to " +"know about, such as the maximum number of points any player of a game is " +"allowed to earn, or the speed of light." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:147 +msgid "" +"Naming hardcoded values used throughout your program as constants is useful " +"in conveying the meaning of that value to future maintainers of the code. It " +"also helps to have only one place in your code you would need to change if " +"the hardcoded value needed to be updated in the future." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:152 +msgid "Shadowing" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:154 +msgid "" +"As you saw in the guessing game tutorial in [Chapter 2](ch02-00-guessing-" +"game-tutorial.html#comparing-the-guess-to-the-secret-number), " +"you can declare a new variable with the same name as a previous variable. " +"Rustaceans say that the first variable is _shadowed_ by the second, which " +"means that the second variable is what the compiler will see when you use " +"the name of the variable. In effect, the second variable overshadows the " +"first, taking any uses of the variable name to itself until either it itself " +"is shadowed or the scope ends. We can shadow a variable by using the same " +"variable’s name and repeating the use of the `let` keyword as follows:" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:174 +msgid "\"The value of x in the inner scope is: {x}\"" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:181 +msgid "" +"This program first binds `x` to a value of `5`. Then it creates a new " +"variable `x` by repeating `let x =`, taking the original value and adding " +"`1` so the value of `x` is then `6`. Then, within an inner scope created " +"with the curly brackets, the third `let` statement also shadows `x` and " +"creates a new variable, multiplying the previous value by `2` to give `x` a " +"value of `12`. When that scope is over, the inner shadowing ends and `x` " +"returns to being `6`. When we run this program, it will output the following:" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:189 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling variables v0.1.0 (file:///projects/variables)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.31s\n" +" Running `target/debug/variables`\n" +"The value of x in the inner scope is: 12\n" +"The value of x is: 6\n" +"```" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:198 +msgid "" +"Shadowing is different from marking a variable as `mut` because we’ll get a " +"compile-time error if we accidentally try to reassign to this variable " +"without using the `let` keyword. By using `let`, we can perform a few " +"transformations on a value but have the variable be immutable after those " +"transformations have been completed." +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:204 +msgid "" +"The other difference between `mut` and shadowing is that because we’re " +"effectively creating a new variable when we use the `let` keyword again, we " +"can change the type of the value but reuse the same name. For example, say " +"our program asks a user to show how many spaces they want between some text " +"by inputting space characters, and then we want to store that input as a " +"number:" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:212 +#: src/ch03-01-variables-and-mutability.md:225 +msgid "\" \"" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:217 +msgid "" +"The first `spaces` variable is a string type and the second `spaces` " +"variable is a number type. Shadowing thus spares us from having to come up " +"with different names, such as `spaces_str` and `spaces_num`; instead, we can " +"reuse the simpler `spaces` name. However, if we try to use `mut` for this, " +"as shown here, we’ll get a compile-time error:" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:230 +msgid "The error says we’re not allowed to mutate a variable’s type:" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:232 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling variables v0.1.0 (file:///projects/variables)\n" +"error[E0308]: mismatched types\n" +" --> src/main.rs:3:14\n" +" |\n" +"2 | let mut spaces = \" \";\n" +" | ----- expected due to this value\n" +"3 | spaces = spaces.len();\n" +" | ^^^^^^^^^^^^ expected `&str`, found `usize`\n" +"\n" +"For more information about this error, try `rustc --explain E0308`.\n" +"error: could not compile `variables` (bin \"variables\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch03-01-variables-and-mutability.md:247 +msgid "" +"Now that we’ve explored how variables work, let’s look at more data types " +"they can have." +msgstr "" + +#: src/ch03-02-data-types.md:3 +msgid "" +"Every value in Rust is of a certain _data type_, which tells Rust what kind " +"of data is being specified so it knows how to work with that data. We’ll " +"look at two data type subsets: scalar and compound." +msgstr "" + +#: src/ch03-02-data-types.md:7 +msgid "" +"Keep in mind that Rust is a _statically typed_ language, which means that it " +"must know the types of all variables at compile time. The compiler can " +"usually infer what type we want to use based on the value and how we use it. " +"In cases when many types are possible, such as when we converted a `String` " +"to a numeric type using `parse` in the [“Comparing the Guess to the Secret " +"Number”](ch02-00-guessing-game-tutorial.html#comparing-the-guess-to-the-" +"secret-number) section in Chapter 2, we must add a type " +"annotation, like this:" +msgstr "" + +#: src/ch03-02-data-types.md:16 +msgid "\"42\"" +msgstr "" + +#: src/ch03-02-data-types.md:16 +msgid "\"Not a number!\"" +msgstr "" + +#: src/ch03-02-data-types.md:19 +msgid "" +"If we don’t add the `: u32` type annotation shown in the preceding code, " +"Rust will display the following error, which means the compiler needs more " +"information from us to know which type we want to use:" +msgstr "" + +#: src/ch03-02-data-types.md:23 +msgid "" +"```console\n" +"$ cargo build\n" +" Compiling no_type_annotations v0.1.0 (file:///projects/" +"no_type_annotations)\n" +"error[E0284]: type annotations needed\n" +" --> src/main.rs:2:9\n" +" |\n" +"2 | let guess = \"42\".parse().expect(\"Not a number!\");\n" +" | ^^^^^ ----- type must be known at this point\n" +" |\n" +" = note: cannot satisfy `<_ as FromStr>::Err == _`\n" +"help: consider giving `guess` an explicit type\n" +" |\n" +"2 | let guess: /* Type */ = \"42\".parse().expect(\"Not a number!\");\n" +" | ++++++++++++\n" +"\n" +"For more information about this error, try `rustc --explain E0284`.\n" +"error: could not compile `no_type_annotations` (bin \"no_type_annotations\") " +"due to 1 previous error\n" +"```" +msgstr "" + +#: src/ch03-02-data-types.md:42 +msgid "You’ll see different type annotations for other data types." +msgstr "" + +#: src/ch03-02-data-types.md:44 +msgid "Scalar Types" +msgstr "" + +#: src/ch03-02-data-types.md:46 +msgid "" +"A _scalar_ type represents a single value. Rust has four primary scalar " +"types: integers, floating-point numbers, Booleans, and characters. You may " +"recognize these from other programming languages. Let’s jump into how they " +"work in Rust." +msgstr "" + +#: src/ch03-02-data-types.md:50 +msgid "Integer Types" +msgstr "" + +#: src/ch03-02-data-types.md:52 +msgid "" +"An _integer_ is a number without a fractional component. We used one integer " +"type in Chapter 2, the `u32` type. This type declaration indicates that the " +"value it’s associated with should be an unsigned integer (signed integer " +"types start with `i` instead of `u`) that takes up 32 bits of space. Table " +"3-1 shows the built-in integer types in Rust. We can use any of these " +"variants to declare the type of an integer value." +msgstr "" + +#: src/ch03-02-data-types.md:59 +msgid "Table 3-1: Integer Types in Rust" +msgstr "" + +#: src/ch03-02-data-types.md:61 +msgid "Length" +msgstr "" + +#: src/ch03-02-data-types.md:61 +msgid "Signed" +msgstr "" + +#: src/ch03-02-data-types.md:61 +msgid "Unsigned" +msgstr "" + +#: src/ch03-02-data-types.md:63 +msgid "8-bit" +msgstr "" + +#: src/ch03-02-data-types.md:63 +msgid "`i8`" +msgstr "" + +#: src/ch03-02-data-types.md:63 +msgid "`u8`" +msgstr "" + +#: src/ch03-02-data-types.md:64 +msgid "16-bit" +msgstr "" + +#: src/ch03-02-data-types.md:64 +msgid "`i16`" +msgstr "" + +#: src/ch03-02-data-types.md:64 +msgid "`u16`" +msgstr "" + +#: src/ch03-02-data-types.md:65 +msgid "32-bit" +msgstr "" + +#: src/ch03-02-data-types.md:65 +msgid "`i32`" +msgstr "" + +#: src/ch03-02-data-types.md:65 +msgid "`u32`" +msgstr "" + +#: src/ch03-02-data-types.md:66 +msgid "64-bit" +msgstr "" + +#: src/ch03-02-data-types.md:66 +msgid "`i64`" +msgstr "" + +#: src/ch03-02-data-types.md:66 +msgid "`u64`" +msgstr "" + +#: src/ch03-02-data-types.md:67 +msgid "128-bit" +msgstr "" + +#: src/ch03-02-data-types.md:67 +msgid "`i128`" +msgstr "" + +#: src/ch03-02-data-types.md:67 +msgid "`u128`" +msgstr "" + +#: src/ch03-02-data-types.md:68 +msgid "arch" +msgstr "" + +#: src/ch03-02-data-types.md:68 +msgid "`isize`" +msgstr "" + +#: src/ch03-02-data-types.md:68 +msgid "`usize`" +msgstr "" + +#: src/ch03-02-data-types.md:70 +msgid "" +"Each variant can be either signed or unsigned and has an explicit size. " +"_Signed_ and _unsigned_ refer to whether it’s possible for the number to be " +"negative—in other words, whether the number needs to have a sign with it " +"(signed) or whether it will only ever be positive and can therefore be " +"represented without a sign (unsigned). It’s like writing numbers on paper: " +"when the sign matters, a number is shown with a plus sign or a minus sign; " +"however, when it’s safe to assume the number is positive, it’s shown with no " +"sign. Signed numbers are stored using [two’s complement](https://en." +"wikipedia.org/wiki/Two%27s_complement) representation." +msgstr "" + +#: src/ch03-02-data-types.md:80 +msgid "" +"Each signed variant can store numbers from -(2n - 1) to 2n - " +"1 - 1 inclusive, where _n_ is the number of bits that variant uses. So " +"an `i8` can store numbers from -(27) to 27 - 1, which " +"equals \\-128 to 127. Unsigned variants can store numbers from 0 to 2n - 1, so a `u8` can store numbers from 0 to 28 - 1, which " +"equals 0 to 255." +msgstr "" + +#: src/ch03-02-data-types.md:86 +msgid "" +"Additionally, the `isize` and `usize` types depend on the architecture of " +"the computer your program is running on, which is denoted in the table as " +"“arch”: 64 bits if you’re on a 64-bit architecture and 32 bits if you’re on " +"a 32-bit architecture." +msgstr "" + +#: src/ch03-02-data-types.md:91 +msgid "" +"You can write integer literals in any of the forms shown in Table 3-2. Note " +"that number literals that can be multiple numeric types allow a type suffix, " +"such as `57u8`, to designate the type. Number literals can also use `_` as a " +"visual separator to make the number easier to read, such as `1_000`, which " +"will have the same value as if you had specified `1000`." +msgstr "" + +#: src/ch03-02-data-types.md:97 +msgid "Table 3-2: Integer Literals in Rust" +msgstr "" + +#: src/ch03-02-data-types.md:99 +msgid "Number literals" +msgstr "" + +#: src/ch03-02-data-types.md:99 src/appendix-02-operators.md:16 +msgid "Example" +msgstr "" + +#: src/ch03-02-data-types.md:101 +msgid "Decimal" +msgstr "" + +#: src/ch03-02-data-types.md:101 +msgid "`98_222`" +msgstr "" + +#: src/ch03-02-data-types.md:102 +msgid "Hex" +msgstr "" + +#: src/ch03-02-data-types.md:102 +msgid "`0xff`" +msgstr "" + +#: src/ch03-02-data-types.md:103 +msgid "Octal" +msgstr "" + +#: src/ch03-02-data-types.md:103 +msgid "`0o77`" +msgstr "" + +#: src/ch03-02-data-types.md:104 +msgid "Binary" +msgstr "" + +#: src/ch03-02-data-types.md:104 +msgid "`0b1111_0000`" +msgstr "" + +#: src/ch03-02-data-types.md:105 +msgid "Byte (`u8` only)" +msgstr "" + +#: src/ch03-02-data-types.md:105 +msgid "`b'A'`" +msgstr "" + +#: src/ch03-02-data-types.md:107 +msgid "" +"So how do you know which type of integer to use? If you’re unsure, Rust’s " +"defaults are generally good places to start: integer types default to `i32`. " +"The primary situation in which you’d use `isize` or `usize` is when indexing " +"some sort of collection." +msgstr "" + +#: src/ch03-02-data-types.md:112 +msgid "Integer Overflow" +msgstr "" + +#: src/ch03-02-data-types.md:114 +msgid "" +"Let’s say you have a variable of type `u8` that can hold values between 0 " +"and 255. If you try to change the variable to a value outside that range, " +"such as 256, _integer overflow_ will occur, which can result in one of two " +"behaviors. When you’re compiling in debug mode, Rust includes checks for " +"integer overflow that cause your program to _panic_ at runtime if this " +"behavior occurs. Rust uses the term _panicking_ when a program exits with an " +"error; we’ll discuss panics in more depth in the [“Unrecoverable Errors with " +"`panic!`”](ch09-01-unrecoverable-errors-with-panic.html) " +"section in Chapter 9." +msgstr "" + +#: src/ch03-02-data-types.md:124 +msgid "" +"When you’re compiling in release mode with the `--release` flag, Rust does " +"_not_ include checks for integer overflow that cause panics. Instead, if " +"overflow occurs, Rust performs _two’s complement wrapping_. In short, values " +"greater than the maximum value the type can hold “wrap around” to the " +"minimum of the values the type can hold. In the case of a `u8`, the value " +"256 becomes 0, the value 257 becomes 1, and so on. The program won’t panic, " +"but the variable will have a value that probably isn’t what you were " +"expecting it to have. Relying on integer overflow’s wrapping behavior is " +"considered an error." +msgstr "" + +#: src/ch03-02-data-types.md:133 +msgid "" +"To explicitly handle the possibility of overflow, you can use these families " +"of methods provided by the standard library for primitive numeric types:" +msgstr "" + +#: src/ch03-02-data-types.md:136 +msgid "" +"Wrap in all modes with the `wrapping_*` methods, such as `wrapping_add`." +msgstr "" + +#: src/ch03-02-data-types.md:137 +msgid "" +"Return the `None` value if there is overflow with the `checked_*` methods." +msgstr "" + +#: src/ch03-02-data-types.md:138 +msgid "" +"Return the value and a boolean indicating whether there was overflow with " +"the `overflowing_*` methods." +msgstr "" + +#: src/ch03-02-data-types.md:140 +msgid "" +"Saturate at the value’s minimum or maximum values with the `saturating_*` " +"methods." +msgstr "" + +#: src/ch03-02-data-types.md:143 +msgid "Floating-Point Types" +msgstr "" + +#: src/ch03-02-data-types.md:145 +msgid "" +"Rust also has two primitive types for _floating-point numbers_, which are " +"numbers with decimal points. Rust’s floating-point types are `f32` and " +"`f64`, which are 32 bits and 64 bits in size, respectively. The default type " +"is `f64` because on modern CPUs, it’s roughly the same speed as `f32` but is " +"capable of more precision. All floating-point types are signed." +msgstr "" + +#: src/ch03-02-data-types.md:151 +msgid "Here’s an example that shows floating-point numbers in action:" +msgstr "" + +#: src/ch03-02-data-types.md:157 +msgid "// f64\n" +msgstr "" + +#: src/ch03-02-data-types.md:159 +msgid "// f32\n" +msgstr "" + +#: src/ch03-02-data-types.md:163 +msgid "" +"Floating-point numbers are represented according to the IEEE-754 standard. " +"The `f32` type is a single-precision float, and `f64` has double precision." +msgstr "" + +#: src/ch03-02-data-types.md:166 +msgid "Numeric Operations" +msgstr "" + +#: src/ch03-02-data-types.md:168 +msgid "" +"Rust supports the basic mathematical operations you’d expect for all the " +"number types: addition, subtraction, multiplication, division, and " +"remainder. Integer division truncates toward zero to the nearest integer. " +"The following code shows how you’d use each numeric operation in a `let` " +"statement:" +msgstr "" + +#: src/ch03-02-data-types.md:177 +msgid "// addition\n" +msgstr "" + +#: src/ch03-02-data-types.md:180 +msgid "// subtraction\n" +msgstr "" + +#: src/ch03-02-data-types.md:183 +msgid "// multiplication\n" +msgstr "" + +#: src/ch03-02-data-types.md:186 +msgid "// division\n" +msgstr "" + +#: src/ch03-02-data-types.md:188 +msgid "// Results in -1\n" +msgstr "" + +#: src/ch03-02-data-types.md:190 +msgid "// remainder\n" +msgstr "" + +#: src/ch03-02-data-types.md:195 +msgid "" +"Each expression in these statements uses a mathematical operator and " +"evaluates to a single value, which is then bound to a variable. [Appendix B]" +"(appendix-02-operators.md) contains a list of all operators " +"that Rust provides." +msgstr "" + +#: src/ch03-02-data-types.md:200 +msgid "The Boolean Type" +msgstr "" + +#: src/ch03-02-data-types.md:202 +msgid "" +"As in most other programming languages, a Boolean type in Rust has two " +"possible values: `true` and `false`. Booleans are one byte in size. The " +"Boolean type in Rust is specified using `bool`. For example:" +msgstr "" + +#: src/ch03-02-data-types.md:212 src/ch03-02-data-types.md:230 +msgid "// with explicit type annotation\n" +msgstr "" + +#: src/ch03-02-data-types.md:216 +msgid "" +"The main way to use Boolean values is through conditionals, such as an `if` " +"expression. We’ll cover how `if` expressions work in Rust in the [“Control " +"Flow”](ch03-05-control-flow.html#control-flow) section." +msgstr "" + +#: src/ch03-02-data-types.md:220 +msgid "The Character Type" +msgstr "" + +#: src/ch03-02-data-types.md:222 +msgid "" +"Rust’s `char` type is the language’s most primitive alphabetic type. Here " +"are some examples of declaring `char` values:" +msgstr "" + +#: src/ch03-02-data-types.md:229 src/ch18-03-pattern-syntax.md:146 +msgid "'z'" +msgstr "" + +#: src/ch03-02-data-types.md:230 +msgid "'ℤ'" +msgstr "" + +#: src/ch03-02-data-types.md:231 +msgid "'😻'" +msgstr "" + +#: src/ch03-02-data-types.md:235 +msgid "" +"Note that we specify `char` literals with single quotes, as opposed to " +"string literals, which use double quotes. Rust’s `char` type is four bytes " +"in size and represents a Unicode Scalar Value, which means it can represent " +"a lot more than just ASCII. Accented letters; Chinese, Japanese, and Korean " +"characters; emoji; and zero-width spaces are all valid `char` values in " +"Rust. Unicode Scalar Values range from `U+0000` to `U+D7FF` and `U+E000` to " +"`U+10FFFF` inclusive. However, a “character” isn’t really a concept in " +"Unicode, so your human intuition for what a “character” is may not match up " +"with what a `char` is in Rust. We’ll discuss this topic in detail in " +"[“Storing UTF-8 Encoded Text with Strings”](ch08-02-strings.html#storing-" +"utf-8-encoded-text-with-strings) in Chapter 8." +msgstr "" + +#: src/ch03-02-data-types.md:246 +msgid "Compound Types" +msgstr "" + +#: src/ch03-02-data-types.md:248 +msgid "" +"_Compound types_ can group multiple values into one type. Rust has two " +"primitive compound types: tuples and arrays." +msgstr "" + +#: src/ch03-02-data-types.md:251 +msgid "The Tuple Type" +msgstr "" + +#: src/ch03-02-data-types.md:253 +msgid "" +"A _tuple_ is a general way of grouping together a number of values with a " +"variety of types into one compound type. Tuples have a fixed length: once " +"declared, they cannot grow or shrink in size." +msgstr "" + +#: src/ch03-02-data-types.md:257 +msgid "" +"We create a tuple by writing a comma-separated list of values inside " +"parentheses. Each position in the tuple has a type, and the types of the " +"different values in the tuple don’t have to be the same. We’ve added " +"optional type annotations in this example:" +msgstr "" + +#: src/ch03-02-data-types.md:270 +msgid "" +"The variable `tup` binds to the entire tuple because a tuple is considered a " +"single compound element. To get the individual values out of a tuple, we can " +"use pattern matching to destructure a tuple value, like this:" +msgstr "" + +#: src/ch03-02-data-types.md:282 src/ch03-03-how-functions-work.md:230 +msgid "\"The value of y is: {y}\"" +msgstr "" + +#: src/ch03-02-data-types.md:286 +msgid "" +"This program first creates a tuple and binds it to the variable `tup`. It " +"then uses a pattern with `let` to take `tup` and turn it into three separate " +"variables, `x`, `y`, and `z`. This is called _destructuring_ because it " +"breaks the single tuple into three parts. Finally, the program prints the " +"value of `y`, which is `6.4`." +msgstr "" + +#: src/ch03-02-data-types.md:292 +msgid "" +"We can also access a tuple element directly by using a period (`.`) followed " +"by the index of the value we want to access. For example:" +msgstr "" + +#: src/ch03-02-data-types.md:309 +msgid "" +"This program creates the tuple `x` and then accesses each element of the " +"tuple using their respective indices. As with most programming languages, " +"the first index in a tuple is 0." +msgstr "" + +#: src/ch03-02-data-types.md:313 +msgid "" +"The tuple without any values has a special name, _unit_. This value and its " +"corresponding type are both written `()` and represent an empty value or an " +"empty return type. Expressions implicitly return the unit value if they " +"don’t return any other value." +msgstr "" + +#: src/ch03-02-data-types.md:318 +msgid "The Array Type" +msgstr "" + +#: src/ch03-02-data-types.md:320 +msgid "" +"Another way to have a collection of multiple values is with an _array_. " +"Unlike a tuple, every element of an array must have the same type. Unlike " +"arrays in some other languages, arrays in Rust have a fixed length." +msgstr "" + +#: src/ch03-02-data-types.md:324 +msgid "" +"We write the values in an array as a comma-separated list inside square " +"brackets:" +msgstr "" + +#: src/ch03-02-data-types.md:335 +msgid "" +"Arrays are useful when you want your data allocated on the stack rather than " +"the heap (we will discuss the stack and the heap more in [Chapter 4](ch04-01-" +"what-is-ownership.html#the-stack-and-the-heap)) or when you " +"want to ensure you always have a fixed number of elements. An array isn’t as " +"flexible as the vector type, though. A _vector_ is a similar collection type " +"provided by the standard library that _is_ allowed to grow or shrink in " +"size. If you’re unsure whether to use an array or a vector, chances are you " +"should use a vector. [Chapter 8](ch08-01-vectors.html) " +"discusses vectors in more detail." +msgstr "" + +#: src/ch03-02-data-types.md:344 +msgid "" +"However, arrays are more useful when you know the number of elements will " +"not need to change. For example, if you were using the names of the month in " +"a program, you would probably use an array rather than a vector because you " +"know it will always contain 12 elements:" +msgstr "" + +#: src/ch03-02-data-types.md:350 +msgid "\"January\"" +msgstr "" + +#: src/ch03-02-data-types.md:350 +msgid "\"February\"" +msgstr "" + +#: src/ch03-02-data-types.md:350 +msgid "\"March\"" +msgstr "" + +#: src/ch03-02-data-types.md:350 +msgid "\"April\"" +msgstr "" + +#: src/ch03-02-data-types.md:350 +msgid "\"May\"" +msgstr "" + +#: src/ch03-02-data-types.md:350 +msgid "\"June\"" +msgstr "" + +#: src/ch03-02-data-types.md:350 +msgid "\"July\"" +msgstr "" + +#: src/ch03-02-data-types.md:351 +msgid "\"August\"" +msgstr "" + +#: src/ch03-02-data-types.md:351 +msgid "\"September\"" +msgstr "" + +#: src/ch03-02-data-types.md:351 +msgid "\"October\"" +msgstr "" + +#: src/ch03-02-data-types.md:351 +msgid "\"November\"" +msgstr "" + +#: src/ch03-02-data-types.md:351 +msgid "\"December\"" +msgstr "" + +#: src/ch03-02-data-types.md:354 +msgid "" +"You write an array’s type using square brackets with the type of each " +"element, a semicolon, and then the number of elements in the array, like so:" +msgstr "" + +#: src/ch03-02-data-types.md:361 +msgid "" +"Here, `i32` is the type of each element. After the semicolon, the number `5` " +"indicates the array contains five elements." +msgstr "" + +#: src/ch03-02-data-types.md:364 +msgid "" +"You can also initialize an array to contain the same value for each element " +"by specifying the initial value, followed by a semicolon, and then the " +"length of the array in square brackets, as shown here:" +msgstr "" + +#: src/ch03-02-data-types.md:372 +msgid "" +"The array named `a` will contain `5` elements that will all be set to the " +"value `3` initially. This is the same as writing `let a = [3, 3, 3, 3, 3];` " +"but in a more concise way." +msgstr "" + +#: src/ch03-02-data-types.md:376 +msgid "Accessing Array Elements" +msgstr "" + +#: src/ch03-02-data-types.md:378 +msgid "" +"An array is a single chunk of memory of a known, fixed size that can be " +"allocated on the stack. You can access elements of an array using indexing, " +"like this:" +msgstr "" + +#: src/ch03-02-data-types.md:393 +msgid "" +"In this example, the variable named `first` will get the value `1` because " +"that is the value at index `[0]` in the array. The variable named `second` " +"will get the value `2` from index `[1]` in the array." +msgstr "" + +#: src/ch03-02-data-types.md:397 +msgid "Invalid Array Element Access" +msgstr "" + +#: src/ch03-02-data-types.md:399 +msgid "" +"Let’s see what happens if you try to access an element of an array that is " +"past the end of the array. Say you run this code, similar to the guessing " +"game in Chapter 2, to get an array index from the user:" +msgstr "" + +#: src/ch03-02-data-types.md:411 +msgid "\"Please enter an array index.\"" +msgstr "" + +#: src/ch03-02-data-types.md:422 +msgid "\"Index entered was not a number\"" +msgstr "" + +#: src/ch03-02-data-types.md:426 +msgid "\"The value of the element at index {index} is: {element}\"" +msgstr "" + +#: src/ch03-02-data-types.md:430 +msgid "" +"This code compiles successfully. If you run this code using `cargo run` and " +"enter `0`, `1`, `2`, `3`, or `4`, the program will print out the " +"corresponding value at that index in the array. If you instead enter a " +"number past the end of the array, such as `10`, you’ll see output like this:" +msgstr "" + +#: src/ch03-02-data-types.md:447 +msgid "" +"The program resulted in a _runtime_ error at the point of using an invalid " +"value in the indexing operation. The program exited with an error message " +"and didn’t execute the final `println!` statement. When you attempt to " +"access an element using indexing, Rust will check that the index you’ve " +"specified is less than the array length. If the index is greater than or " +"equal to the length, Rust will panic. This check has to happen at runtime, " +"especially in this case, because the compiler can’t possibly know what value " +"a user will enter when they run the code later." +msgstr "" + +#: src/ch03-02-data-types.md:456 +msgid "" +"This is an example of Rust’s memory safety principles in action. In many low-" +"level languages, this kind of check is not done, and when you provide an " +"incorrect index, invalid memory can be accessed. Rust protects you against " +"this kind of error by immediately exiting instead of allowing the memory " +"access and continuing. Chapter 9 discusses more of Rust’s error handling and " +"how you can write readable, safe code that neither panics nor allows invalid " +"memory access." +msgstr "" + +#: src/ch03-03-how-functions-work.md:3 +msgid "" +"Functions are prevalent in Rust code. You’ve already seen one of the most " +"important functions in the language: the `main` function, which is the entry " +"point of many programs. You’ve also seen the `fn` keyword, which allows you " +"to declare new functions." +msgstr "" + +#: src/ch03-03-how-functions-work.md:8 +msgid "" +"Rust code uses _snake case_ as the conventional style for function and " +"variable names, in which all letters are lowercase and underscores separate " +"words. Here’s a program that contains an example function definition:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:22 +msgid "\"Another function.\"" +msgstr "" + +#: src/ch03-03-how-functions-work.md:26 +msgid "" +"We define a function in Rust by entering `fn` followed by a function name " +"and a set of parentheses. The curly brackets tell the compiler where the " +"function body begins and ends." +msgstr "" + +#: src/ch03-03-how-functions-work.md:30 +msgid "" +"We can call any function we’ve defined by entering its name followed by a " +"set of parentheses. Because `another_function` is defined in the program, it " +"can be called from inside the `main` function. Note that we defined " +"`another_function` _after_ the `main` function in the source code; we could " +"have defined it before as well. Rust doesn’t care where you define your " +"functions, only that they’re defined somewhere in a scope that can be seen " +"by the caller." +msgstr "" + +#: src/ch03-03-how-functions-work.md:37 +msgid "" +"Let’s start a new binary project named _functions_ to explore functions " +"further. Place the `another_function` example in _src/main.rs_ and run it. " +"You should see the following output:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:41 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling functions v0.1.0 (file:///projects/functions)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.28s\n" +" Running `target/debug/functions`\n" +"Hello, world!\n" +"Another function.\n" +"```" +msgstr "" + +#: src/ch03-03-how-functions-work.md:50 +msgid "" +"The lines execute in the order in which they appear in the `main` function. " +"First the “Hello, world!” message prints, and then `another_function` is " +"called and its message is printed." +msgstr "" + +#: src/ch03-03-how-functions-work.md:54 +msgid "Parameters" +msgstr "" + +#: src/ch03-03-how-functions-work.md:56 +msgid "" +"We can define functions to have _parameters_, which are special variables " +"that are part of a function’s signature. When a function has parameters, you " +"can provide it with concrete values for those parameters. Technically, the " +"concrete values are called _arguments_, but in casual conversation, people " +"tend to use the words _parameter_ and _argument_ interchangeably for either " +"the variables in a function’s definition or the concrete values passed in " +"when you call a function." +msgstr "" + +#: src/ch03-03-how-functions-work.md:64 +msgid "In this version of `another_function` we add a parameter:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:78 +msgid "Try running this program; you should get the following output:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:80 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling functions v0.1.0 (file:///projects/functions)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.21s\n" +" Running `target/debug/functions`\n" +"The value of x is: 5\n" +"```" +msgstr "" + +#: src/ch03-03-how-functions-work.md:88 +msgid "" +"The declaration of `another_function` has one parameter named `x`. The type " +"of `x` is specified as `i32`. When we pass `5` in to `another_function`, the " +"`println!` macro puts `5` where the pair of curly brackets containing `x` " +"was in the format string." +msgstr "" + +#: src/ch03-03-how-functions-work.md:93 +msgid "" +"In function signatures, you _must_ declare the type of each parameter. This " +"is a deliberate decision in Rust’s design: requiring type annotations in " +"function definitions means the compiler almost never needs you to use them " +"elsewhere in the code to figure out what type you mean. The compiler is also " +"able to give more helpful error messages if it knows what types the function " +"expects." +msgstr "" + +#: src/ch03-03-how-functions-work.md:99 +msgid "" +"When defining multiple parameters, separate the parameter declarations with " +"commas, like this:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:106 +msgid "'h'" +msgstr "" + +#: src/ch03-03-how-functions-work.md:110 +msgid "\"The measurement is: {value}{unit_label}\"" +msgstr "" + +#: src/ch03-03-how-functions-work.md:114 +msgid "" +"This example creates a function named `print_labeled_measurement` with two " +"parameters. The first parameter is named `value` and is an `i32`. The second " +"is named `unit_label` and is type `char`. The function then prints text " +"containing both the `value` and the `unit_label`." +msgstr "" + +#: src/ch03-03-how-functions-work.md:119 +msgid "" +"Let’s try running this code. Replace the program currently in your " +"_functions_ project’s _src/main.rs_ file with the preceding example and run " +"it using `cargo run`:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:123 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling functions v0.1.0 (file:///projects/functions)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.31s\n" +" Running `target/debug/functions`\n" +"The measurement is: 5h\n" +"```" +msgstr "" + +#: src/ch03-03-how-functions-work.md:131 +msgid "" +"Because we called the function with `5` as the value for `value` and `'h'` " +"as the value for `unit_label`, the program output contains those values." +msgstr "" + +#: src/ch03-03-how-functions-work.md:134 +msgid "Statements and Expressions" +msgstr "" + +#: src/ch03-03-how-functions-work.md:136 +msgid "" +"Function bodies are made up of a series of statements optionally ending in " +"an expression. So far, the functions we’ve covered haven’t included an " +"ending expression, but you have seen an expression as part of a statement. " +"Because Rust is an expression-based language, this is an important " +"distinction to understand. Other languages don’t have the same distinctions, " +"so let’s look at what statements and expressions are and how their " +"differences affect the bodies of functions." +msgstr "" + +#: src/ch03-03-how-functions-work.md:144 +msgid "" +"**Statements** are instructions that perform some action and do not return a " +"value." +msgstr "" + +#: src/ch03-03-how-functions-work.md:146 +msgid "" +"**Expressions** evaluate to a resultant value. Let’s look at some examples." +msgstr "" + +#: src/ch03-03-how-functions-work.md:148 +msgid "" +"We’ve actually already used statements and expressions. Creating a variable " +"and assigning a value to it with the `let` keyword is a statement. In " +"Listing 3-1, `let y = 6;` is a statement." +msgstr "" + +#: src/ch03-03-how-functions-work.md:162 +msgid "" +"Function definitions are also statements; the entire preceding example is a " +"statement in itself. (As we will see below, _calling_ a function is not a " +"statement.)" +msgstr "" + +#: src/ch03-03-how-functions-work.md:166 +msgid "" +"Statements do not return values. Therefore, you can’t assign a `let` " +"statement to another variable, as the following code tries to do; you’ll get " +"an error:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:177 +msgid "When you run this program, the error you’ll get looks like this:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:179 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling functions v0.1.0 (file:///projects/functions)\n" +"error: expected expression, found `let` statement\n" +" --> src/main.rs:2:14\n" +" |\n" +"2 | let x = (let y = 6);\n" +" | ^^^\n" +" |\n" +" = note: only supported directly in conditions of `if` and `while` " +"expressions\n" +"\n" +"warning: unnecessary parentheses around assigned value\n" +" --> src/main.rs:2:13\n" +" |\n" +"2 | let x = (let y = 6);\n" +" | ^ ^\n" +" |\n" +" = note: `#[warn(unused_parens)]` on by default\n" +"help: remove these parentheses\n" +" |\n" +"2 - let x = (let y = 6);\n" +"2 + let x = let y = 6;\n" +" |\n" +"\n" +"warning: `functions` (bin \"functions\") generated 1 warning\n" +"error: could not compile `functions` (bin \"functions\") due to 1 previous " +"error; 1 warning emitted\n" +"```" +msgstr "" + +#: src/ch03-03-how-functions-work.md:207 +msgid "" +"The `let y = 6` statement does not return a value, so there isn’t anything " +"for `x` to bind to. This is different from what happens in other languages, " +"such as C and Ruby, where the assignment returns the value of the " +"assignment. In those languages, you can write `x = y = 6` and have both `x` " +"and `y` have the value `6`; that is not the case in Rust." +msgstr "" + +#: src/ch03-03-how-functions-work.md:213 +msgid "" +"Expressions evaluate to a value and make up most of the rest of the code " +"that you’ll write in Rust. Consider a math operation, such as `5 + 6`, which " +"is an expression that evaluates to the value `11`. Expressions can be part " +"of statements: in Listing 3-1, the `6` in the statement `let y = 6;` is an " +"expression that evaluates to the value `6`. Calling a function is an " +"expression. Calling a macro is an expression. A new scope block created with " +"curly brackets is an expression, for example:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:234 +msgid "This expression:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:243 +msgid "" +"is a block that, in this case, evaluates to `4`. That value gets bound to " +"`y` as part of the `let` statement. Note that the `x + 1` line doesn’t have " +"a semicolon at the end, which is unlike most of the lines you’ve seen so " +"far. Expressions do not include ending semicolons. If you add a semicolon to " +"the end of an expression, you turn it into a statement, and it will then not " +"return a value. Keep this in mind as you explore function return values and " +"expressions next." +msgstr "" + +#: src/ch03-03-how-functions-work.md:251 +msgid "Functions with Return Values" +msgstr "" + +#: src/ch03-03-how-functions-work.md:253 +msgid "" +"Functions can return values to the code that calls them. We don’t name " +"return values, but we must declare their type after an arrow (`->`). In " +"Rust, the return value of the function is synonymous with the value of the " +"final expression in the block of the body of a function. You can return " +"early from a function by using the `return` keyword and specifying a value, " +"but most functions return the last expression implicitly. Here’s an example " +"of a function that returns a value:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:275 +msgid "" +"There are no function calls, macros, or even `let` statements in the `five` " +"function—just the number `5` by itself. That’s a perfectly valid function in " +"Rust. Note that the function’s return type is specified too, as `-> i32`. " +"Try running this code; the output should look like this:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:280 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling functions v0.1.0 (file:///projects/functions)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.30s\n" +" Running `target/debug/functions`\n" +"The value of x is: 5\n" +"```" +msgstr "" + +#: src/ch03-03-how-functions-work.md:288 +msgid "" +"The `5` in `five` is the function’s return value, which is why the return " +"type is `i32`. Let’s examine this in more detail. There are two important " +"bits: first, the line `let x = five();` shows that we’re using the return " +"value of a function to initialize a variable. Because the function `five` " +"returns a `5`, that line is the same as the following:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:298 +msgid "" +"Second, the `five` function has no parameters and defines the type of the " +"return value, but the body of the function is a lonely `5` with no semicolon " +"because it’s an expression whose value we want to return." +msgstr "" + +#: src/ch03-03-how-functions-work.md:302 +msgid "Let’s look at another example:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:318 +msgid "" +"Running this code will print `The value of x is: 6`. But if we place a " +"semicolon at the end of the line containing `x + 1`, changing it from an " +"expression to a statement, we’ll get an error:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:336 +msgid "Compiling this code produces an error, as follows:" +msgstr "" + +#: src/ch03-03-how-functions-work.md:338 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling functions v0.1.0 (file:///projects/functions)\n" +"error[E0308]: mismatched types\n" +" --> src/main.rs:7:24\n" +" |\n" +"7 | fn plus_one(x: i32) -> i32 {\n" +" | -------- ^^^ expected `i32`, found `()`\n" +" | |\n" +" | implicitly returns `()` as its body has no tail or `return` " +"expression\n" +"8 | x + 1;\n" +" | - help: remove this semicolon to return this value\n" +"\n" +"For more information about this error, try `rustc --explain E0308`.\n" +"error: could not compile `functions` (bin \"functions\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch03-03-how-functions-work.md:355 +msgid "" +"The main error message, `mismatched types`, reveals the core issue with this " +"code. The definition of the function `plus_one` says that it will return an " +"`i32`, but statements don’t evaluate to a value, which is expressed by `()`, " +"the unit type. Therefore, nothing is returned, which contradicts the " +"function definition and results in an error. In this output, Rust provides a " +"message to possibly help rectify this issue: it suggests removing the " +"semicolon, which would fix the error." +msgstr "" + +#: src/ch03-04-comments.md:3 +msgid "" +"All programmers strive to make their code easy to understand, but sometimes " +"extra explanation is warranted. In these cases, programmers leave _comments_ " +"in their source code that the compiler will ignore but people reading the " +"source code may find useful." +msgstr "" + +#: src/ch03-04-comments.md:8 +msgid "Here’s a simple comment:" +msgstr "" + +#: src/ch03-04-comments.md:11 +msgid "// hello, world\n" +msgstr "" + +#: src/ch03-04-comments.md:14 +msgid "" +"In Rust, the idiomatic comment style starts a comment with two slashes, and " +"the comment continues until the end of the line. For comments that extend " +"beyond a single line, you’ll need to include `//` on each line, like this:" +msgstr "" + +#: src/ch03-04-comments.md:19 +msgid "" +"// So we’re doing something complicated here, long enough that we need\n" +"// multiple lines of comments to do it! Whew! Hopefully, this comment will\n" +"// explain what’s going on.\n" +msgstr "" + +#: src/ch03-04-comments.md:24 +msgid "Comments can also be placed at the end of lines containing code:" +msgstr "" + +#: src/ch03-04-comments.md:30 src/ch03-04-comments.md:41 +msgid "// I’m feeling lucky today\n" +msgstr "" + +#: src/ch03-04-comments.md:34 +msgid "" +"But you’ll more often see them used in this format, with the comment on a " +"separate line above the code it’s annotating:" +msgstr "" + +#: src/ch03-04-comments.md:46 +msgid "" +"Rust also has another kind of comment, documentation comments, which we’ll " +"discuss in the [“Publishing a Crate to Crates.io”](ch14-02-publishing-to-" +"crates-io.html) section of Chapter 14." +msgstr "" + +#: src/ch03-05-control-flow.md:3 +msgid "" +"The ability to run some code depending on whether a condition is `true` and " +"to run some code repeatedly while a condition is `true` are basic building " +"blocks in most programming languages. The most common constructs that let " +"you control the flow of execution of Rust code are `if` expressions and " +"loops." +msgstr "" + +#: src/ch03-05-control-flow.md:8 +msgid "`if` Expressions" +msgstr "" + +#: src/ch03-05-control-flow.md:10 +msgid "" +"An `if` expression allows you to branch your code depending on conditions. " +"You provide a condition and then state, “If this condition is met, run this " +"block of code. If the condition is not met, do not run this block of code.”" +msgstr "" + +#: src/ch03-05-control-flow.md:14 +msgid "" +"Create a new project called _branches_ in your _projects_ directory to " +"explore the `if` expression. In the _src/main.rs_ file, input the following:" +msgstr "" + +#: src/ch03-05-control-flow.md:24 src/ch03-05-control-flow.md:64 +msgid "\"condition was true\"" +msgstr "" + +#: src/ch03-05-control-flow.md:26 src/ch03-05-control-flow.md:66 +msgid "\"condition was false\"" +msgstr "" + +#: src/ch03-05-control-flow.md:31 +msgid "" +"All `if` expressions start with the keyword `if`, followed by a condition. " +"In this case, the condition checks whether or not the variable `number` has " +"a value less than 5. We place the block of code to execute if the condition " +"is `true` immediately after the condition inside curly brackets. Blocks of " +"code associated with the conditions in `if` expressions are sometimes called " +"_arms_, just like the arms in `match` expressions that we discussed in the " +"[“Comparing the Guess to the Secret Number”](ch02-00-guessing-game-tutorial." +"html#comparing-the-guess-to-the-secret-number) section of Chapter 2." +msgstr "" + +#: src/ch03-05-control-flow.md:40 +msgid "" +"Optionally, we can also include an `else` expression, which we chose to do " +"here, to give the program an alternative block of code to execute should the " +"condition evaluate to `false`. If you don’t provide an `else` expression and " +"the condition is `false`, the program will just skip the `if` block and move " +"on to the next bit of code." +msgstr "" + +#: src/ch03-05-control-flow.md:46 +msgid "Try running this code; you should see the following output:" +msgstr "" + +#: src/ch03-05-control-flow.md:48 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling branches v0.1.0 (file:///projects/branches)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.31s\n" +" Running `target/debug/branches`\n" +"condition was true\n" +"```" +msgstr "" + +#: src/ch03-05-control-flow.md:56 +msgid "" +"Let’s try changing the value of `number` to a value that makes the condition " +"`false` to see what happens:" +msgstr "" + +#: src/ch03-05-control-flow.md:71 +msgid "Run the program again, and look at the output:" +msgstr "" + +#: src/ch03-05-control-flow.md:73 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling branches v0.1.0 (file:///projects/branches)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.31s\n" +" Running `target/debug/branches`\n" +"condition was false\n" +"```" +msgstr "" + +#: src/ch03-05-control-flow.md:81 +msgid "" +"It’s also worth noting that the condition in this code _must_ be a `bool`. " +"If the condition isn’t a `bool`, we’ll get an error. For example, try " +"running the following code:" +msgstr "" + +#: src/ch03-05-control-flow.md:92 +msgid "\"number was three\"" +msgstr "" + +#: src/ch03-05-control-flow.md:97 +msgid "" +"The `if` condition evaluates to a value of `3` this time, and Rust throws an " +"error:" +msgstr "" + +#: src/ch03-05-control-flow.md:100 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling branches v0.1.0 (file:///projects/branches)\n" +"error[E0308]: mismatched types\n" +" --> src/main.rs:4:8\n" +" |\n" +"4 | if number {\n" +" | ^^^^^^ expected `bool`, found integer\n" +"\n" +"For more information about this error, try `rustc --explain E0308`.\n" +"error: could not compile `branches` (bin \"branches\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch03-05-control-flow.md:113 +msgid "" +"The error indicates that Rust expected a `bool` but got an integer. Unlike " +"languages such as Ruby and JavaScript, Rust will not automatically try to " +"convert non-Boolean types to a Boolean. You must be explicit and always " +"provide `if` with a Boolean as its condition. If we want the `if` code block " +"to run only when a number is not equal to `0`, for example, we can change " +"the `if` expression to the following:" +msgstr "" + +#: src/ch03-05-control-flow.md:127 +msgid "\"number was something other than zero\"" +msgstr "" + +#: src/ch03-05-control-flow.md:132 +msgid "Running this code will print `number was something other than zero`." +msgstr "" + +#: src/ch03-05-control-flow.md:134 +msgid "Handling Multiple Conditions with `else if`" +msgstr "" + +#: src/ch03-05-control-flow.md:136 +msgid "" +"You can use multiple conditions by combining `if` and `else` in an `else if` " +"expression. For example:" +msgstr "" + +#: src/ch03-05-control-flow.md:146 +msgid "\"number is divisible by 4\"" +msgstr "" + +#: src/ch03-05-control-flow.md:148 +msgid "\"number is divisible by 3\"" +msgstr "" + +#: src/ch03-05-control-flow.md:150 +msgid "\"number is divisible by 2\"" +msgstr "" + +#: src/ch03-05-control-flow.md:152 +msgid "\"number is not divisible by 4, 3, or 2\"" +msgstr "" + +#: src/ch03-05-control-flow.md:157 +msgid "" +"This program has four possible paths it can take. After running it, you " +"should see the following output:" +msgstr "" + +#: src/ch03-05-control-flow.md:160 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling branches v0.1.0 (file:///projects/branches)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.31s\n" +" Running `target/debug/branches`\n" +"number is divisible by 3\n" +"```" +msgstr "" + +#: src/ch03-05-control-flow.md:168 +msgid "" +"When this program executes, it checks each `if` expression in turn and " +"executes the first body for which the condition evaluates to `true`. Note " +"that even though 6 is divisible by 2, we don’t see the output `number is " +"divisible by 2`, nor do we see the `number is not divisible by 4, 3, or 2` " +"text from the `else` block. That’s because Rust only executes the block for " +"the first `true` condition, and once it finds one, it doesn’t even check the " +"rest." +msgstr "" + +#: src/ch03-05-control-flow.md:175 +msgid "" +"Using too many `else if` expressions can clutter your code, so if you have " +"more than one, you might want to refactor your code. Chapter 6 describes a " +"powerful Rust branching construct called `match` for these cases." +msgstr "" + +#: src/ch03-05-control-flow.md:179 +msgid "Using `if` in a `let` Statement" +msgstr "" + +#: src/ch03-05-control-flow.md:181 +msgid "" +"Because `if` is an expression, we can use it on the right side of a `let` " +"statement to assign the outcome to a variable, as in Listing 3-2." +msgstr "" + +#: src/ch03-05-control-flow.md:191 src/ch03-05-control-flow.md:224 +msgid "\"The value of number is: {number}\"" +msgstr "" + +#: src/ch03-05-control-flow.md:197 +msgid "" +"The `number` variable will be bound to a value based on the outcome of the " +"`if` expression. Run this code to see what happens:" +msgstr "" + +#: src/ch03-05-control-flow.md:200 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling branches v0.1.0 (file:///projects/branches)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.30s\n" +" Running `target/debug/branches`\n" +"The value of number is: 5\n" +"```" +msgstr "" + +#: src/ch03-05-control-flow.md:208 +msgid "" +"Remember that blocks of code evaluate to the last expression in them, and " +"numbers by themselves are also expressions. In this case, the value of the " +"whole `if` expression depends on which block of code executes. This means " +"the values that have the potential to be results from each arm of the `if` " +"must be the same type; in Listing 3-2, the results of both the `if` arm and " +"the `else` arm were `i32` integers. If the types are mismatched, as in the " +"following example, we’ll get an error:" +msgstr "" + +#: src/ch03-05-control-flow.md:222 +msgid "\"six\"" +msgstr "" + +#: src/ch03-05-control-flow.md:228 +msgid "" +"When we try to compile this code, we’ll get an error. The `if` and `else` " +"arms have value types that are incompatible, and Rust indicates exactly " +"where to find the problem in the program:" +msgstr "" + +#: src/ch03-05-control-flow.md:232 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling branches v0.1.0 (file:///projects/branches)\n" +"error[E0308]: `if` and `else` have incompatible types\n" +" --> src/main.rs:4:44\n" +" |\n" +"4 | let number = if condition { 5 } else { \"six\" };\n" +" | - ^^^^^ expected integer, found " +"`&str`\n" +" | |\n" +" | expected because of this\n" +"\n" +"For more information about this error, try `rustc --explain E0308`.\n" +"error: could not compile `branches` (bin \"branches\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch03-05-control-flow.md:247 +msgid "" +"The expression in the `if` block evaluates to an integer, and the expression " +"in the `else` block evaluates to a string. This won’t work because variables " +"must have a single type, and Rust needs to know at compile time what type " +"the `number` variable is, definitively. Knowing the type of `number` lets " +"the compiler verify the type is valid everywhere we use `number`. Rust " +"wouldn’t be able to do that if the type of `number` was only determined at " +"runtime; the compiler would be more complex and would make fewer guarantees " +"about the code if it had to keep track of multiple hypothetical types for " +"any variable." +msgstr "" + +#: src/ch03-05-control-flow.md:256 +msgid "Repetition with Loops" +msgstr "" + +#: src/ch03-05-control-flow.md:258 +msgid "" +"It’s often useful to execute a block of code more than once. For this task, " +"Rust provides several _loops_, which will run through the code inside the " +"loop body to the end and then start immediately back at the beginning. To " +"experiment with loops, let’s make a new project called _loops_." +msgstr "" + +#: src/ch03-05-control-flow.md:263 +msgid "" +"Rust has three kinds of loops: `loop`, `while`, and `for`. Let’s try each " +"one." +msgstr "" + +#: src/ch03-05-control-flow.md:265 +msgid "Repeating Code with `loop`" +msgstr "" + +#: src/ch03-05-control-flow.md:267 +msgid "" +"The `loop` keyword tells Rust to execute a block of code over and over again " +"forever or until you explicitly tell it to stop." +msgstr "" + +#: src/ch03-05-control-flow.md:270 +msgid "" +"As an example, change the _src/main.rs_ file in your _loops_ directory to " +"look like this:" +msgstr "" + +#: src/ch03-05-control-flow.md:278 +msgid "\"again!\"" +msgstr "" + +#: src/ch03-05-control-flow.md:283 +msgid "" +"When we run this program, we’ll see `again!` printed over and over " +"continuously until we stop the program manually. Most terminals support the " +"keyboard shortcut ctrl\\-c to interrupt a program that " +"is stuck in a continual loop. Give it a try:" +msgstr "" + +#: src/ch03-05-control-flow.md:294 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling loops v0.1.0 (file:///projects/loops)\n" +" Finished dev [unoptimized + debuginfo] target(s) in 0.29s\n" +" Running `target/debug/loops`\n" +"again!\n" +"again!\n" +"again!\n" +"again!\n" +"^Cagain!\n" +"```" +msgstr "" + +#: src/ch03-05-control-flow.md:306 +msgid "" +"The symbol `^C` represents where you pressed ctrl\\-c. " +"You may or may not see the word `again!` printed after the `^C`, depending " +"on where the code was in the loop when it received the interrupt signal." +msgstr "" + +#: src/ch03-05-control-flow.md:310 +msgid "" +"Fortunately, Rust also provides a way to break out of a loop using code. You " +"can place the `break` keyword within the loop to tell the program when to " +"stop executing the loop. Recall that we did this in the guessing game in the " +"[“Quitting After a Correct Guess”](ch02-00-guessing-game-tutorial." +"html#quitting-after-a-correct-guess) section of Chapter 2 to exit the program when the user won the game by " +"guessing the correct number." +msgstr "" + +#: src/ch03-05-control-flow.md:317 +msgid "" +"We also used `continue` in the guessing game, which in a loop tells the " +"program to skip over any remaining code in this iteration of the loop and go " +"to the next iteration." +msgstr "" + +#: src/ch03-05-control-flow.md:321 +msgid "Returning Values from Loops" +msgstr "" + +#: src/ch03-05-control-flow.md:323 +msgid "" +"One of the uses of a `loop` is to retry an operation you know might fail, " +"such as checking whether a thread has completed its job. You might also need " +"to pass the result of that operation out of the loop to the rest of your " +"code. To do this, you can add the value you want returned after the `break` " +"expression you use to stop the loop; that value will be returned out of the " +"loop so you can use it, as shown here:" +msgstr "" + +#: src/ch03-05-control-flow.md:342 +msgid "\"The result is {result}\"" +msgstr "" + +#: src/ch03-05-control-flow.md:346 +msgid "" +"Before the loop, we declare a variable named `counter` and initialize it to " +"`0`. Then we declare a variable named `result` to hold the value returned " +"from the loop. On every iteration of the loop, we add `1` to the `counter` " +"variable, and then check whether the `counter` is equal to `10`. When it is, " +"we use the `break` keyword with the value `counter * 2`. After the loop, we " +"use a semicolon to end the statement that assigns the value to `result`. " +"Finally, we print the value in `result`, which in this case is `20`." +msgstr "" + +#: src/ch03-05-control-flow.md:354 +msgid "" +"You can also `return` from inside a loop. While `break` only exits the " +"current loop, `return` always exits the current function." +msgstr "" + +#: src/ch03-05-control-flow.md:357 +msgid "Loop Labels to Disambiguate Between Multiple Loops" +msgstr "" + +#: src/ch03-05-control-flow.md:359 +msgid "" +"If you have loops within loops, `break` and `continue` apply to the " +"innermost loop at that point. You can optionally specify a _loop label_ on a " +"loop that you can then use with `break` or `continue` to specify that those " +"keywords apply to the labeled loop instead of the innermost loop. Loop " +"labels must begin with a single quote. Here’s an example with two nested " +"loops:" +msgstr "" + +#: src/ch03-05-control-flow.md:369 +msgid "\"count = {count}\"" +msgstr "" + +#: src/ch03-05-control-flow.md:373 +msgid "\"remaining = {remaining}\"" +msgstr "" + +#: src/ch03-05-control-flow.md:385 +msgid "\"End count = {count}\"" +msgstr "" + +#: src/ch03-05-control-flow.md:389 +msgid "" +"The outer loop has the label `'counting_up`, and it will count up from 0 to " +"2. The inner loop without a label counts down from 10 to 9. The first " +"`break` that doesn’t specify a label will exit the inner loop only. The " +"`break 'counting_up;` statement will exit the outer loop. This code prints:" +msgstr "" + +#: src/ch03-05-control-flow.md:394 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling loops v0.1.0 (file:///projects/loops)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.58s\n" +" Running `target/debug/loops`\n" +"count = 0\n" +"remaining = 10\n" +"remaining = 9\n" +"count = 1\n" +"remaining = 10\n" +"remaining = 9\n" +"count = 2\n" +"remaining = 10\n" +"End count = 2\n" +"```" +msgstr "" + +#: src/ch03-05-control-flow.md:410 +msgid "Conditional Loops with `while`" +msgstr "" + +#: src/ch03-05-control-flow.md:412 +msgid "" +"A program will often need to evaluate a condition within a loop. While the " +"condition is `true`, the loop runs. When the condition ceases to be `true`, " +"the program calls `break`, stopping the loop. It’s possible to implement " +"behavior like this using a combination of `loop`, `if`, `else`, and `break`; " +"you could try that now in a program, if you’d like. However, this pattern is " +"so common that Rust has a built-in language construct for it, called a " +"`while` loop. In Listing 3-3, we use `while` to loop the program three " +"times, counting down each time, and then, after the loop, print a message " +"and exit." +msgstr "" + +#: src/ch03-05-control-flow.md:428 src/ch03-05-control-flow.md:536 +msgid "\"{number}!\"" +msgstr "" + +#: src/ch03-05-control-flow.md:433 src/ch03-05-control-flow.md:538 +msgid "\"LIFTOFF!!!\"" +msgstr "" + +#: src/ch03-05-control-flow.md:439 +msgid "" +"This construct eliminates a lot of nesting that would be necessary if you " +"used `loop`, `if`, `else`, and `break`, and it’s clearer. While a condition " +"evaluates to `true`, the code runs; otherwise, it exits the loop." +msgstr "" + +#: src/ch03-05-control-flow.md:443 +msgid "Looping Through a Collection with `for`" +msgstr "" + +#: src/ch03-05-control-flow.md:445 +msgid "" +"You can also use the `while` construct to loop over the elements of a " +"collection, such as an array. For example, the loop in Listing 3-4 prints " +"each element in the array `a`." +msgstr "" + +#: src/ch03-05-control-flow.md:457 +msgid "\"the value is: {}\"" +msgstr "" + +#: src/ch03-05-control-flow.md:466 +msgid "" +"Here, the code counts up through the elements in the array. It starts at " +"index `0`, and then loops until it reaches the final index in the array " +"(that is, when `index < 5` is no longer `true`). Running this code will " +"print every element in the array:" +msgstr "" + +#: src/ch03-05-control-flow.md:471 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling loops v0.1.0 (file:///projects/loops)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.32s\n" +" Running `target/debug/loops`\n" +"the value is: 10\n" +"the value is: 20\n" +"the value is: 30\n" +"the value is: 40\n" +"the value is: 50\n" +"```" +msgstr "" + +#: src/ch03-05-control-flow.md:483 +msgid "" +"All five array values appear in the terminal, as expected. Even though " +"`index` will reach a value of `5` at some point, the loop stops executing " +"before trying to fetch a sixth value from the array." +msgstr "" + +#: src/ch03-05-control-flow.md:487 +msgid "" +"However, this approach is error prone; we could cause the program to panic " +"if the index value or test condition is incorrect. For example, if you " +"changed the definition of the `a` array to have four elements but forgot to " +"update the condition to `while index < 4`, the code would panic. It’s also " +"slow, because the compiler adds runtime code to perform the conditional " +"check of whether the index is within the bounds of the array on every " +"iteration through the loop." +msgstr "" + +#: src/ch03-05-control-flow.md:494 +msgid "" +"As a more concise alternative, you can use a `for` loop and execute some " +"code for each item in a collection. A `for` loop looks like the code in " +"Listing 3-5." +msgstr "" + +#: src/ch03-05-control-flow.md:504 +msgid "\"the value is: {element}\"" +msgstr "" + +#: src/ch03-05-control-flow.md:511 +msgid "" +"When we run this code, we’ll see the same output as in Listing 3-4. More " +"importantly, we’ve now increased the safety of the code and eliminated the " +"chance of bugs that might result from going beyond the end of the array or " +"not going far enough and missing some items." +msgstr "" + +#: src/ch03-05-control-flow.md:516 +msgid "" +"Using the `for` loop, you wouldn’t need to remember to change any other code " +"if you changed the number of values in the array, as you would with the " +"method used in Listing 3-4." +msgstr "" + +#: src/ch03-05-control-flow.md:520 +msgid "" +"The safety and conciseness of `for` loops make them the most commonly used " +"loop construct in Rust. Even in situations in which you want to run some " +"code a certain number of times, as in the countdown example that used a " +"`while` loop in Listing 3-3, most Rustaceans would use a `for` loop. The way " +"to do that would be to use a `Range`, provided by the standard library, " +"which generates all numbers in sequence starting from one number and ending " +"before another number." +msgstr "" + +#: src/ch03-05-control-flow.md:528 +msgid "" +"Here’s what the countdown would look like using a `for` loop and another " +"method we’ve not yet talked about, `rev`, to reverse the range:" +msgstr "" + +#: src/ch03-05-control-flow.md:542 +msgid "This code is a bit nicer, isn’t it?" +msgstr "" + +#: src/ch03-05-control-flow.md:546 +msgid "" +"You made it! This was a sizable chapter: you learned about variables, scalar " +"and compound data types, functions, comments, `if` expressions, and loops! " +"To practice with the concepts discussed in this chapter, try building " +"programs to do the following:" +msgstr "" + +#: src/ch03-05-control-flow.md:551 +msgid "Convert temperatures between Fahrenheit and Celsius." +msgstr "" + +#: src/ch03-05-control-flow.md:552 +msgid "Generate the _n_th Fibonacci number." +msgstr "" + +#: src/ch03-05-control-flow.md:553 +msgid "" +"Print the lyrics to the Christmas carol “The Twelve Days of Christmas,” " +"taking advantage of the repetition in the song." +msgstr "" + +#: src/ch03-05-control-flow.md:556 +msgid "" +"When you’re ready to move on, we’ll talk about a concept in Rust that " +"_doesn’t_ commonly exist in other programming languages: ownership." +msgstr "" + +#: src/ch04-00-understanding-ownership.md:3 +msgid "" +"Ownership is Rust’s most unique feature and has deep implications for the " +"rest of the language. It enables Rust to make memory safety guarantees " +"without needing a garbage collector, so it’s important to understand how " +"ownership works. In this chapter, we’ll talk about ownership as well as " +"several related features: borrowing, slices, and how Rust lays data out in " +"memory." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:1 +msgid "What Is Ownership?" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:3 +msgid "" +"_Ownership_ is a set of rules that govern how a Rust program manages memory. " +"All programs have to manage the way they use a computer’s memory while " +"running. Some languages have garbage collection that regularly looks for no-" +"longer-used memory as the program runs; in other languages, the programmer " +"must explicitly allocate and free the memory. Rust uses a third approach: " +"memory is managed through a system of ownership with a set of rules that the " +"compiler checks. If any of the rules are violated, the program won’t " +"compile. None of the features of ownership will slow down your program while " +"it’s running." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:12 +msgid "" +"Because ownership is a new concept for many programmers, it does take some " +"time to get used to. The good news is that the more experienced you become " +"with Rust and the rules of the ownership system, the easier you’ll find it " +"to naturally develop code that is safe and efficient. Keep at it!" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:17 +msgid "" +"When you understand ownership, you’ll have a solid foundation for " +"understanding the features that make Rust unique. In this chapter, you’ll " +"learn ownership by working through some examples that focus on a very common " +"data structure: strings." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:22 +msgid "The Stack and the Heap" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:24 +msgid "" +"Many programming languages don’t require you to think about the stack and " +"the heap very often. But in a systems programming language like Rust, " +"whether a value is on the stack or the heap affects how the language behaves " +"and why you have to make certain decisions. Parts of ownership will be " +"described in relation to the stack and the heap later in this chapter, so " +"here is a brief explanation in preparation." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:31 +msgid "" +"Both the stack and the heap are parts of memory available to your code to " +"use at runtime, but they are structured in different ways. The stack stores " +"values in the order it gets them and removes the values in the opposite " +"order. This is referred to as _last in, first out_. Think of a stack of " +"plates: when you add more plates, you put them on top of the pile, and when " +"you need a plate, you take one off the top. Adding or removing plates from " +"the middle or bottom wouldn’t work as well! Adding data is called _pushing " +"onto the stack_, and removing data is called _popping off the stack_. All " +"data stored on the stack must have a known, fixed size. Data with an unknown " +"size at compile time or a size that might change must be stored on the heap " +"instead." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:43 +msgid "" +"The heap is less organized: when you put data on the heap, you request a " +"certain amount of space. The memory allocator finds an empty spot in the " +"heap that is big enough, marks it as being in use, and returns a _pointer_, " +"which is the address of that location. This process is called _allocating on " +"the heap_ and is sometimes abbreviated as just _allocating_ (pushing values " +"onto the stack is not considered allocating). Because the pointer to the " +"heap is a known, fixed size, you can store the pointer on the stack, but " +"when you want the actual data, you must follow the pointer. Think of being " +"seated at a restaurant. When you enter, you state the number of people in " +"your group, and the host finds an empty table that fits everyone and leads " +"you there. If someone in your group comes late, they can ask where you’ve " +"been seated to find you." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:56 +msgid "" +"Pushing to the stack is faster than allocating on the heap because the " +"allocator never has to search for a place to store new data; that location " +"is always at the top of the stack. Comparatively, allocating space on the " +"heap requires more work because the allocator must first find a big enough " +"space to hold the data and then perform bookkeeping to prepare for the next " +"allocation." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:63 +msgid "" +"Accessing data in the heap is slower than accessing data on the stack " +"because you have to follow a pointer to get there. Contemporary processors " +"are faster if they jump around less in memory. Continuing the analogy, " +"consider a server at a restaurant taking orders from many tables. It’s most " +"efficient to get all the orders at one table before moving on to the next " +"table. Taking an order from table A, then an order from table B, then one " +"from A again, and then one from B again would be a much slower process. By " +"the same token, a processor can do its job better if it works on data that’s " +"close to other data (as it is on the stack) rather than farther away (as it " +"can be on the heap)." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:74 +msgid "" +"When your code calls a function, the values passed into the function " +"(including, potentially, pointers to data on the heap) and the function’s " +"local variables get pushed onto the stack. When the function is over, those " +"values get popped off the stack." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:79 +msgid "" +"Keeping track of what parts of code are using what data on the heap, " +"minimizing the amount of duplicate data on the heap, and cleaning up unused " +"data on the heap so you don’t run out of space are all problems that " +"ownership addresses. Once you understand ownership, you won’t need to think " +"about the stack and the heap very often, but knowing that the main purpose " +"of ownership is to manage heap data can help explain why it works the way it " +"does." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:86 +msgid "Ownership Rules" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:88 +msgid "" +"First, let’s take a look at the ownership rules. Keep these rules in mind as " +"we work through the examples that illustrate them:" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:91 +msgid "Each value in Rust has an _owner_." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:92 +msgid "There can only be one owner at a time." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:93 +msgid "When the owner goes out of scope, the value will be dropped." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:95 +msgid "Variable Scope" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:97 +msgid "" +"Now that we’re past basic Rust syntax, we won’t include all the `fn main() " +"{` code in examples, so if you’re following along, make sure to put the " +"following examples inside a `main` function manually. As a result, our " +"examples will be a bit more concise, letting us focus on the actual details " +"rather than boilerplate code." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:103 +msgid "" +"As a first example of ownership, we’ll look at the _scope_ of some " +"variables. A scope is the range within a program for which an item is valid. " +"Take the following variable:" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:108 src/ch04-01-what-is-ownership.md:119 +#: src/ch04-01-what-is-ownership.md:165 src/ch04-01-what-is-ownership.md:179 +#: src/ch04-01-what-is-ownership.md:228 src/ch04-01-what-is-ownership.md:281 +#: src/ch04-01-what-is-ownership.md:350 src/ch04-01-what-is-ownership.md:421 +#: src/ch04-01-what-is-ownership.md:496 src/ch04-01-what-is-ownership.md:541 +#: src/ch04-01-what-is-ownership.md:588 +#: src/ch04-02-references-and-borrowing.md:19 +#: src/ch04-02-references-and-borrowing.md:53 +#: src/ch04-02-references-and-borrowing.md:74 +#: src/ch04-02-references-and-borrowing.md:105 +#: src/ch04-02-references-and-borrowing.md:149 +#: src/ch04-02-references-and-borrowing.md:172 +#: src/ch04-02-references-and-borrowing.md:227 +#: src/ch04-02-references-and-borrowing.md:242 +#: src/ch04-02-references-and-borrowing.md:288 +#: src/ch04-02-references-and-borrowing.md:332 +#: src/ch04-02-references-and-borrowing.md:392 +#: src/ch04-02-references-and-borrowing.md:412 src/ch04-03-slices.md:213 +#: src/ch04-03-slices.md:223 src/ch04-03-slices.md:235 +#: src/ch06-01-defining-an-enum.md:295 src/ch08-02-strings.md:270 +#: src/ch13-01-closures.md:241 src/ch19-03-advanced-traits.md:795 +#: src/ch19-04-advanced-types.md:277 +msgid "\"hello\"" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:111 +msgid "" +"The variable `s` refers to a string literal, where the value of the string " +"is hardcoded into the text of our program. The variable is valid from the " +"point at which it’s declared until the end of the current _scope_. Listing " +"4-1 shows a program with comments annotating where the variable `s` would be " +"valid." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:118 +msgid "// s is not valid here, it’s not yet declared\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:119 src/ch04-01-what-is-ownership.md:228 +msgid "// s is valid from this point forward\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:121 src/ch04-01-what-is-ownership.md:230 +msgid "// do stuff with s\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:122 +msgid "// this scope is now over, and s is no longer valid\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:126 +msgid "" +"Listing 4-1: A variable and the scope in which it is " +"valid" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:129 +msgid "In other words, there are two important points in time here:" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:131 +msgid "When `s` comes _into_ scope, it is valid." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:132 +msgid "It remains valid until it goes _out of_ scope." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:134 +msgid "" +"At this point, the relationship between scopes and when variables are valid " +"is similar to that in other programming languages. Now we’ll build on top of " +"this understanding by introducing the `String` type." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:138 +msgid "The `String` Type" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:140 +msgid "" +"To illustrate the rules of ownership, we need a data type that is more " +"complex than those we covered in the [“Data Types”](ch03-02-data-types." +"html#data-types) section of Chapter 3. The types covered " +"previously are of a known size, can be stored on the stack and popped off " +"the stack when their scope is over, and can be quickly and trivially copied " +"to make a new, independent instance if another part of code needs to use the " +"same value in a different scope. But we want to look at data that is stored " +"on the heap and explore how Rust knows when to clean up that data, and the " +"`String` type is a great example." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:149 +msgid "" +"We’ll concentrate on the parts of `String` that relate to ownership. These " +"aspects also apply to other complex data types, whether they are provided by " +"the standard library or created by you. We’ll discuss `String` in more depth " +"in [Chapter 8](ch08-02-strings.html)." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:154 +msgid "" +"We’ve already seen string literals, where a string value is hardcoded into " +"our program. String literals are convenient, but they aren’t suitable for " +"every situation in which we may want to use text. One reason is that they’re " +"immutable. Another is that not every string value can be known when we write " +"our code: for example, what if we want to take user input and store it? For " +"these situations, Rust has a second string type, `String`. This type manages " +"data allocated on the heap and as such is able to store an amount of text " +"that is unknown to us at compile time. You can create a `String` from a " +"string literal using the `from` function, like so:" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:168 +msgid "" +"The double colon `::` operator allows us to namespace this particular `from` " +"function under the `String` type rather than using some sort of name like " +"`string_from`. We’ll discuss this syntax more in the [“Method Syntax”]" +"(ch05-03-method-syntax.html#method-syntax) section of Chapter " +"5, and when we talk about namespacing with modules in [“Paths for Referring " +"to an Item in the Module Tree”](ch07-03-paths-for-referring-to-an-item-in-" +"the-module-tree.html) in Chapter 7." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:175 +msgid "This kind of string _can_ be mutated:" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:181 +msgid "\", world!\"" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:181 +msgid "// push_str() appends a literal to a String\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:183 +msgid "\"{s}\"" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:183 +msgid "// This will print `hello, world!`\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:187 +msgid "" +"So, what’s the difference here? Why can `String` be mutated but literals " +"cannot? The difference is in how these two types deal with memory." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:190 +msgid "Memory and Allocation" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:192 +msgid "" +"In the case of a string literal, we know the contents at compile time, so " +"the text is hardcoded directly into the final executable. This is why string " +"literals are fast and efficient. But these properties only come from the " +"string literal’s immutability. Unfortunately, we can’t put a blob of memory " +"into the binary for each piece of text whose size is unknown at compile time " +"and whose size might change while running the program." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:199 +msgid "" +"With the `String` type, in order to support a mutable, growable piece of " +"text, we need to allocate an amount of memory on the heap, unknown at " +"compile time, to hold the contents. This means:" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:203 +msgid "The memory must be requested from the memory allocator at runtime." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:204 +msgid "" +"We need a way of returning this memory to the allocator when we’re done with " +"our `String`." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:207 +msgid "" +"That first part is done by us: when we call `String::from`, its " +"implementation requests the memory it needs. This is pretty much universal " +"in programming languages." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:211 +msgid "" +"However, the second part is different. In languages with a _garbage " +"collector (GC)_, the GC keeps track of and cleans up memory that isn’t being " +"used anymore, and we don’t need to think about it. In most languages without " +"a GC, it’s our responsibility to identify when memory is no longer being " +"used and to call code to explicitly free it, just as we did to request it. " +"Doing this correctly has historically been a difficult programming problem. " +"If we forget, we’ll waste memory. If we do it too early, we’ll have an " +"invalid variable. If we do it twice, that’s a bug too. We need to pair " +"exactly one `allocate` with exactly one `free`." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:221 +msgid "" +"Rust takes a different path: the memory is automatically returned once the " +"variable that owns it goes out of scope. Here’s a version of our scope " +"example from Listing 4-1 using a `String` instead of a string literal:" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:231 +msgid "" +"// this scope is now over, and s is no\n" +" // longer valid\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:236 +msgid "" +"There is a natural point at which we can return the memory our `String` " +"needs to the allocator: when `s` goes out of scope. When a variable goes out " +"of scope, Rust calls a special function for us. This function is called " +"[`drop`](../std/ops/trait.Drop.html#tymethod.drop), and it’s " +"where the author of `String` can put the code to return the memory. Rust " +"calls `drop` automatically at the closing curly bracket." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:243 +msgid "" +"Note: In C++, this pattern of deallocating resources at the end of an item’s " +"lifetime is sometimes called _Resource Acquisition Is Initialization " +"(RAII)_. The `drop` function in Rust will be familiar to you if you’ve used " +"RAII patterns." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:248 +msgid "" +"This pattern has a profound impact on the way Rust code is written. It may " +"seem simple right now, but the behavior of code can be unexpected in more " +"complicated situations when we want to have multiple variables use the data " +"we’ve allocated on the heap. Let’s explore some of those situations now." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:254 +msgid "" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:256 +msgid "Variables and Data Interacting with Move" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:258 +msgid "" +"Multiple variables can interact with the same data in different ways in " +"Rust. Let’s look at an example using an integer in Listing 4-2." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:268 +msgid "" +"Listing 4-2: Assigning the integer value of variable " +"`x` to `y`" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:271 +msgid "" +"We can probably guess what this is doing: “bind the value `5` to `x`; then " +"make a copy of the value in `x` and bind it to `y`.” We now have two " +"variables, `x` and `y`, and both equal `5`. This is indeed what is " +"happening, because integers are simple values with a known, fixed size, and " +"these two `5` values are pushed onto the stack." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:277 +msgid "Now let’s look at the `String` version:" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:286 +msgid "" +"This looks very similar, so we might assume that the way it works would be " +"the same: that is, the second line would make a copy of the value in `s1` " +"and bind it to `s2`. But this isn’t quite what happens." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:290 +msgid "" +"Take a look at Figure 4-1 to see what is happening to `String` under the " +"covers. A `String` is made up of three parts, shown on the left: a pointer " +"to the memory that holds the contents of the string, a length, and a " +"capacity. This group of data is stored on the stack. On the right is the " +"memory on the heap that holds the contents." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:296 +msgid "" +"\"Two" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:302 +msgid "" +"Figure 4-1: Representation in memory of a `String` " +"holding the value `\"hello\"` bound to `s1`" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:305 +msgid "" +"The length is how much memory, in bytes, the contents of the `String` are " +"currently using. The capacity is the total amount of memory, in bytes, that " +"the `String` has received from the allocator. The difference between length " +"and capacity matters, but not in this context, so for now, it’s fine to " +"ignore the capacity." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:311 +msgid "" +"When we assign `s1` to `s2`, the `String` data is copied, meaning we copy " +"the pointer, the length, and the capacity that are on the stack. We do not " +"copy the data on the heap that the pointer refers to. In other words, the " +"data representation in memory looks like Figure 4-2." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:316 +msgid "" +"\"Three" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:320 +msgid "" +"Figure 4-2: Representation in memory of the variable " +"`s2` that has a copy of the pointer, length, and capacity of `s1`" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:323 +msgid "" +"The representation does _not_ look like Figure 4-3, which is what memory " +"would look like if Rust instead copied the heap data as well. If Rust did " +"this, the operation `s2 = s1` could be very expensive in terms of runtime " +"performance if the data on the heap were large." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:328 +msgid "" +"\"Four" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:332 +msgid "" +"Figure 4-3: Another possibility for what `s2 = s1` " +"might do if Rust copied the heap data as well" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:335 +msgid "" +"Earlier, we said that when a variable goes out of scope, Rust automatically " +"calls the `drop` function and cleans up the heap memory for that variable. " +"But Figure 4-2 shows both data pointers pointing to the same location. This " +"is a problem: when `s2` and `s1` go out of scope, they will both try to free " +"the same memory. This is known as a _double free_ error and is one of the " +"memory safety bugs we mentioned previously. Freeing memory twice can lead to " +"memory corruption, which can potentially lead to security vulnerabilities." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:343 +msgid "" +"To ensure memory safety, after the line `let s2 = s1;`, Rust considers `s1` " +"as no longer valid. Therefore, Rust doesn’t need to free anything when `s1` " +"goes out of scope. Check out what happens when you try to use `s1` after " +"`s2` is created; it won’t work:" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:353 +msgid "\"{s1}, world!\"" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:357 +msgid "" +"You’ll get an error like this because Rust prevents you from using the " +"invalidated reference:" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:360 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling ownership v0.1.0 (file:///projects/ownership)\n" +"error[E0382]: borrow of moved value: `s1`\n" +" --> src/main.rs:5:15\n" +" |\n" +"2 | let s1 = String::from(\"hello\");\n" +" | -- move occurs because `s1` has type `String`, which does not " +"implement the `Copy` trait\n" +"3 | let s2 = s1;\n" +" | -- value moved here\n" +"4 |\n" +"5 | println!(\"{s1}, world!\");\n" +" | ^^^^ value borrowed here after move\n" +" |\n" +" = note: this error originates in the macro `$crate::format_args_nl` which " +"comes from the expansion of the macro `println` (in Nightly builds, run with " +"-Z macro-backtrace for more info)\n" +"help: consider cloning the value if the performance cost is acceptable\n" +" |\n" +"3 | let s2 = s1.clone();\n" +" | ++++++++\n" +"\n" +"For more information about this error, try `rustc --explain E0382`.\n" +"error: could not compile `ownership` (bin \"ownership\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:384 +msgid "" +"If you’ve heard the terms _shallow copy_ and _deep copy_ while working with " +"other languages, the concept of copying the pointer, length, and capacity " +"without copying the data probably sounds like making a shallow copy. But " +"because Rust also invalidates the first variable, instead of being called a " +"shallow copy, it’s known as a _move_. In this example, we would say that " +"`s1` was _moved_ into `s2`. So, what actually happens is shown in Figure 4-4." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:391 +msgid "" +"\"Three" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:397 +msgid "" +"Figure 4-4: Representation in memory after `s1` has " +"been invalidated" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:400 +msgid "" +"That solves our problem! With only `s2` valid, when it goes out of scope it " +"alone will free the memory, and we’re done." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:403 +msgid "" +"In addition, there’s a design choice that’s implied by this: Rust will never " +"automatically create “deep” copies of your data. Therefore, any _automatic_ " +"copying can be assumed to be inexpensive in terms of runtime performance." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:408 +msgid "" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:410 +msgid "Variables and Data Interacting with Clone" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:412 +msgid "" +"If we _do_ want to deeply copy the heap data of the `String`, not just the " +"stack data, we can use a common method called `clone`. We’ll discuss method " +"syntax in Chapter 5, but because methods are a common feature in many " +"programming languages, you’ve probably seen them before." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:417 +msgid "Here’s an example of the `clone` method in action:" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:424 +msgid "\"s1 = {s1}, s2 = {s2}\"" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:428 +msgid "" +"This works just fine and explicitly produces the behavior shown in Figure " +"4-3, where the heap data _does_ get copied." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:431 +msgid "" +"When you see a call to `clone`, you know that some arbitrary code is being " +"executed and that code may be expensive. It’s a visual indicator that " +"something different is going on." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:435 +msgid "Stack-Only Data: Copy" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:437 +msgid "" +"There’s another wrinkle we haven’t talked about yet. This code using integers" +"—part of which was shown in Listing 4-2—works and is valid:" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:445 +msgid "\"x = {x}, y = {y}\"" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:449 +msgid "" +"But this code seems to contradict what we just learned: we don’t have a call " +"to `clone`, but `x` is still valid and wasn’t moved into `y`." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:452 +msgid "" +"The reason is that types such as integers that have a known size at compile " +"time are stored entirely on the stack, so copies of the actual values are " +"quick to make. That means there’s no reason we would want to prevent `x` " +"from being valid after we create the variable `y`. In other words, there’s " +"no difference between deep and shallow copying here, so calling `clone` " +"wouldn’t do anything different from the usual shallow copying, and we can " +"leave it out." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:459 +msgid "" +"Rust has a special annotation called the `Copy` trait that we can place on " +"types that are stored on the stack, as integers are (we’ll talk more about " +"traits in [Chapter 10](ch10-02-traits.html)). If a type " +"implements the `Copy` trait, variables that use it do not move, but rather " +"are trivially copied, making them still valid after assignment to another " +"variable." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:465 +msgid "" +"Rust won’t let us annotate a type with `Copy` if the type, or any of its " +"parts, has implemented the `Drop` trait. If the type needs something special " +"to happen when the value goes out of scope and we add the `Copy` annotation " +"to that type, we’ll get a compile-time error. To learn about how to add the " +"`Copy` annotation to your type to implement the trait, see [“Derivable " +"Traits”](appendix-03-derivable-traits.html) in Appendix C." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:472 +msgid "" +"So, what types implement the `Copy` trait? You can check the documentation " +"for the given type to be sure, but as a general rule, any group of simple " +"scalar values can implement `Copy`, and nothing that requires allocation or " +"is some form of resource can implement `Copy`. Here are some of the types " +"that implement `Copy`:" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:478 +msgid "All the integer types, such as `u32`." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:479 +msgid "The Boolean type, `bool`, with values `true` and `false`." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:480 +msgid "All the floating-point types, such as `f64`." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:481 +msgid "The character type, `char`." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:482 +msgid "" +"Tuples, if they only contain types that also implement `Copy`. For example, " +"`(i32, i32)` implements `Copy`, but `(i32, String)` does not." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:485 +msgid "Ownership and Functions" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:487 +msgid "" +"The mechanics of passing a value to a function are similar to those when " +"assigning a value to a variable. Passing a variable to a function will move " +"or copy, just as assignment does. Listing 4-3 has an example with some " +"annotations showing where variables go into and out of scope." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:496 +msgid "// s comes into scope\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:498 +msgid "" +"// s's value moves into the function...\n" +" // ... and so is no longer valid here\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:501 +msgid "// x comes into scope\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:503 +msgid "" +"// x would move into the function,\n" +" // but i32 is Copy, so it's okay to " +"still\n" +" // use x afterward\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:507 +msgid "" +"// Here, x goes out of scope, then s. But because s's value was moved, " +"nothing\n" +" // special happens.\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:510 src/ch04-01-what-is-ownership.md:553 +msgid "// some_string comes into scope\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:511 +msgid "\"{some_string}\"" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:512 +msgid "" +"// Here, some_string goes out of scope and `drop` is called. The backing\n" +" // memory is freed.\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:515 +msgid "// some_integer comes into scope\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:516 +msgid "\"{some_integer}\"" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:517 +msgid "// Here, some_integer goes out of scope. Nothing special happens.\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:520 +msgid "" +"Listing 4-3: Functions with ownership and scope " +"annotated" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:523 +msgid "" +"If we tried to use `s` after the call to `takes_ownership`, Rust would throw " +"a compile-time error. These static checks protect us from mistakes. Try " +"adding code to `main` that uses `s` and `x` to see where you can use them " +"and where the ownership rules prevent you from doing so." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:528 +msgid "Return Values and Scope" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:530 +msgid "" +"Returning values can also transfer ownership. Listing 4-4 shows an example " +"of a function that returns some value, with similar annotations as those in " +"Listing 4-3." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:538 +msgid "" +"// gives_ownership moves its return\n" +" // value into s1\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:541 +msgid "// s2 comes into scope\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:543 +msgid "" +"// s2 is moved into\n" +" // takes_and_gives_back, which also\n" +" // moves its return value into s3\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:546 +msgid "" +"// Here, s3 goes out of scope and is dropped. s2 was moved, so nothing\n" +" // happens. s1 goes out of scope and is dropped.\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:549 +msgid "" +"// gives_ownership will move its\n" +" // return value into the " +"function\n" +" // that calls it\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:553 +msgid "\"yours\"" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:555 +msgid "" +"// some_string is returned and\n" +" // moves out to the calling\n" +" // function\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:559 +msgid "// This function takes a String and returns one\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:561 +msgid "" +"// a_string comes into\n" +" // scope\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:564 +msgid "// a_string is returned and moves out to the calling function\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:568 +msgid "" +"Listing 4-4: Transferring ownership of return " +"values" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:571 +msgid "" +"The ownership of a variable follows the same pattern every time: assigning a " +"value to another variable moves it. When a variable that includes data on " +"the heap goes out of scope, the value will be cleaned up by `drop` unless " +"ownership of the data has been moved to another variable." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:576 +msgid "" +"While this works, taking ownership and then returning ownership with every " +"function is a bit tedious. What if we want to let a function use a value but " +"not take ownership? It’s quite annoying that anything we pass in also needs " +"to be passed back if we want to use it again, in addition to any data " +"resulting from the body of the function that we might want to return as well." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:582 +msgid "" +"Rust does let us return multiple values using a tuple, as shown in Listing " +"4-5." +msgstr "" + +#: src/ch04-01-what-is-ownership.md:592 +msgid "\"The length of '{s2}' is {len}.\"" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:596 +msgid "// len() returns the length of a String\n" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:602 +msgid "" +"Listing 4-5: Returning ownership of parameters" +msgstr "" + +#: src/ch04-01-what-is-ownership.md:604 +msgid "" +"But this is too much ceremony and a lot of work for a concept that should be " +"common. Luckily for us, Rust has a feature for using a value without " +"transferring ownership, called _references_." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:3 +msgid "" +"The issue with the tuple code in Listing 4-5 is that we have to return the " +"`String` to the calling function so we can still use the `String` after the " +"call to `calculate_length`, because the `String` was moved into " +"`calculate_length`. Instead, we can provide a reference to the `String` " +"value. A _reference_ is like a pointer in that it’s an address we can follow " +"to access the data stored at that address; that data is owned by some other " +"variable. Unlike a pointer, a reference is guaranteed to point to a valid " +"value of a particular type for the life of that reference." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:12 +msgid "" +"Here is how you would define and use a `calculate_length` function that has " +"a reference to an object as a parameter instead of taking ownership of the " +"value:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:23 +#: src/ch04-02-references-and-borrowing.md:57 +#: src/ch04-02-references-and-borrowing.md:78 +msgid "\"The length of '{s1}' is {len}.\"" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:31 +msgid "" +"First, notice that all the tuple code in the variable declaration and the " +"function return value is gone. Second, note that we pass `&s1` into " +"`calculate_length` and, in its definition, we take `&String` rather than " +"`String`. These ampersands represent _references_, and they allow you to " +"refer to some value without taking ownership of it. Figure 4-5 depicts this " +"concept." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:37 +msgid "" +"\"Three" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:41 +msgid "" +"Figure 4-5: A diagram of `&String s` pointing at " +"`String s1`" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:44 +msgid "" +"Note: The opposite of referencing by using `&` is _dereferencing_, which is " +"accomplished with the dereference operator, `*`. We’ll see some uses of the " +"dereference operator in Chapter 8 and discuss details of dereferencing in " +"Chapter 15." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:49 +msgid "Let’s take a closer look at the function call here:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:65 +msgid "" +"The `&s1` syntax lets us create a reference that _refers_ to the value of " +"`s1` but does not own it. Because it does not own it, the value it points to " +"will not be dropped when the reference stops being used." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:69 +msgid "" +"Likewise, the signature of the function uses `&` to indicate that the type " +"of the parameter `s` is a reference. Let’s add some explanatory annotations:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:81 +msgid "// s is a reference to a String\n" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:83 +msgid "" +"// Here, s goes out of scope. But because it does not have ownership of " +"what\n" +" // it refers to, it is not dropped.\n" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:87 +msgid "" +"The scope in which the variable `s` is valid is the same as any function " +"parameter’s scope, but the value pointed to by the reference is not dropped " +"when `s` stops being used, because `s` doesn’t have ownership. When " +"functions have references as parameters instead of the actual values, we " +"won’t need to return the values in order to give back ownership, because we " +"never had ownership." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:94 +msgid "" +"We call the action of creating a reference _borrowing_. As in real life, if " +"a person owns something, you can borrow it from them. When you’re done, you " +"have to give it back. You don’t own it." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:98 +msgid "" +"So, what happens if we try to modify something we’re borrowing? Try the code " +"in Listing 4-6. Spoiler alert: it doesn’t work!" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:111 +#: src/ch04-02-references-and-borrowing.md:155 +msgid "\", world\"" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:115 +msgid "" +"Listing 4-6: Attempting to modify a borrowed value" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:117 +#: src/ch04-02-references-and-borrowing.md:181 +#: src/ch04-02-references-and-borrowing.md:252 +#: src/ch04-02-references-and-borrowing.md:338 +msgid "Here’s the error:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:119 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling ownership v0.1.0 (file:///projects/ownership)\n" +"error[E0596]: cannot borrow `*some_string` as mutable, as it is behind a `&` " +"reference\n" +" --> src/main.rs:8:5\n" +" |\n" +"8 | some_string.push_str(\", world\");\n" +" | ^^^^^^^^^^^ `some_string` is a `&` reference, so the data it refers " +"to cannot be borrowed as mutable\n" +" |\n" +"help: consider changing this to be a mutable reference\n" +" |\n" +"7 | fn change(some_string: &mut String) {\n" +" | +++\n" +"\n" +"For more information about this error, try `rustc --explain E0596`.\n" +"error: could not compile `ownership` (bin \"ownership\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:137 +msgid "" +"Just as variables are immutable by default, so are references. We’re not " +"allowed to modify something we have a reference to." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:140 +msgid "Mutable References" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:142 +msgid "" +"We can fix the code from Listing 4-6 to allow us to modify a borrowed value " +"with just a few small tweaks that use, instead, a _mutable reference_:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:159 +msgid "" +"First we change `s` to be `mut`. Then we create a mutable reference with " +"`&mut s` where we call the `change` function, and update the function " +"signature to accept a mutable reference with `some_string: &mut String`. " +"This makes it very clear that the `change` function will mutate the value it " +"borrows." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:164 +msgid "" +"Mutable references have one big restriction: if you have a mutable reference " +"to a value, you can have no other references to that value. This code that " +"attempts to create two mutable references to `s` will fail:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:177 +msgid "\"{}, {}\"" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:183 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling ownership v0.1.0 (file:///projects/ownership)\n" +"error[E0499]: cannot borrow `s` as mutable more than once at a time\n" +" --> src/main.rs:5:14\n" +" |\n" +"4 | let r1 = &mut s;\n" +" | ------ first mutable borrow occurs here\n" +"5 | let r2 = &mut s;\n" +" | ^^^^^^ second mutable borrow occurs here\n" +"6 |\n" +"7 | println!(\"{}, {}\", r1, r2);\n" +" | -- first borrow later used here\n" +"\n" +"For more information about this error, try `rustc --explain E0499`.\n" +"error: could not compile `ownership` (bin \"ownership\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:201 +msgid "" +"This error says that this code is invalid because we cannot borrow `s` as " +"mutable more than once at a time. The first mutable borrow is in `r1` and " +"must last until it’s used in the `println!`, but between the creation of " +"that mutable reference and its usage, we tried to create another mutable " +"reference in `r2` that borrows the same data as `r1`." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:207 +msgid "" +"The restriction preventing multiple mutable references to the same data at " +"the same time allows for mutation but in a very controlled fashion. It’s " +"something that new Rustaceans struggle with because most languages let you " +"mutate whenever you’d like. The benefit of having this restriction is that " +"Rust can prevent data races at compile time. A _data race_ is similar to a " +"race condition and happens when these three behaviors occur:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:214 +msgid "Two or more pointers access the same data at the same time." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:215 +msgid "At least one of the pointers is being used to write to the data." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:216 +msgid "There’s no mechanism being used to synchronize access to the data." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:218 +msgid "" +"Data races cause undefined behavior and can be difficult to diagnose and fix " +"when you’re trying to track them down at runtime; Rust prevents this problem " +"by refusing to compile code with data races!" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:222 +msgid "" +"As always, we can use curly brackets to create a new scope, allowing for " +"multiple mutable references, just not _simultaneous_ ones:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:231 +msgid "" +"// r1 goes out of scope here, so we can make a new reference with no " +"problems.\n" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:237 +msgid "" +"Rust enforces a similar rule for combining mutable and immutable references. " +"This code results in an error:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:244 +#: src/ch04-02-references-and-borrowing.md:245 +#: src/ch04-02-references-and-borrowing.md:290 +#: src/ch04-02-references-and-borrowing.md:291 +#: src/ch04-02-references-and-borrowing.md:295 +msgid "// no problem\n" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:246 +msgid "// BIG PROBLEM\n" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:248 +msgid "\"{}, {}, and {}\"" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:254 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling ownership v0.1.0 (file:///projects/ownership)\n" +"error[E0502]: cannot borrow `s` as mutable because it is also borrowed as " +"immutable\n" +" --> src/main.rs:6:14\n" +" |\n" +"4 | let r1 = &s; // no problem\n" +" | -- immutable borrow occurs here\n" +"5 | let r2 = &s; // no problem\n" +"6 | let r3 = &mut s; // BIG PROBLEM\n" +" | ^^^^^^ mutable borrow occurs here\n" +"7 |\n" +"8 | println!(\"{}, {}, and {}\", r1, r2, r3);\n" +" | -- immutable borrow later used here\n" +"\n" +"For more information about this error, try `rustc --explain E0502`.\n" +"error: could not compile `ownership` (bin \"ownership\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:273 +msgid "" +"Whew! We _also_ cannot have a mutable reference while we have an immutable " +"one to the same value." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:276 +msgid "" +"Users of an immutable reference don’t expect the value to suddenly change " +"out from under them! However, multiple immutable references are allowed " +"because no one who is just reading the data has the ability to affect anyone " +"else’s reading of the data." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:281 +msgid "" +"Note that a reference’s scope starts from where it is introduced and " +"continues through the last time that reference is used. For instance, this " +"code will compile because the last usage of the immutable references, the " +"`println!`, occurs before the mutable reference is introduced:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:292 +msgid "\"{r1} and {r2}\"" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:293 +msgid "// variables r1 and r2 will not be used after this point\n" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:296 +msgid "\"{r3}\"" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:300 +msgid "" +"The scopes of the immutable references `r1` and `r2` end after the `println!" +"` where they are last used, which is before the mutable reference `r3` is " +"created. These scopes don’t overlap, so this code is allowed: the compiler " +"can tell that the reference is no longer being used at a point before the " +"end of the scope." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:306 +msgid "" +"Even though borrowing errors may be frustrating at times, remember that it’s " +"the Rust compiler pointing out a potential bug early (at compile time rather " +"than at runtime) and showing you exactly where the problem is. Then you " +"don’t have to track down why your data isn’t what you thought it was." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:311 +msgid "Dangling References" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:313 +msgid "" +"In languages with pointers, it’s easy to erroneously create a _dangling " +"pointer_—a pointer that references a location in memory that may have been " +"given to someone else—by freeing some memory while preserving a pointer to " +"that memory. In Rust, by contrast, the compiler guarantees that references " +"will never be dangling references: if you have a reference to some data, the " +"compiler will ensure that the data will not go out of scope before the " +"reference to the data does." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:321 +msgid "" +"Let’s try to create a dangling reference to see how Rust prevents them with " +"a compile-time error:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:340 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling ownership v0.1.0 (file:///projects/ownership)\n" +"error[E0106]: missing lifetime specifier\n" +" --> src/main.rs:5:16\n" +" |\n" +"5 | fn dangle() -> &String {\n" +" | ^ expected named lifetime parameter\n" +" |\n" +" = help: this function's return type contains a borrowed value, but there " +"is no value for it to be borrowed from\n" +"help: consider using the `'static` lifetime, but this is uncommon unless " +"you're returning a borrowed value from a `const` or a `static`\n" +" |\n" +"5 | fn dangle() -> &'static String {\n" +" | +++++++\n" +"help: instead, you are more likely to want to return an owned value\n" +" |\n" +"5 - fn dangle() -> &String {\n" +"5 + fn dangle() -> String {\n" +" |\n" +"\n" +"error[E0515]: cannot return reference to local variable `s`\n" +" --> src/main.rs:8:5\n" +" |\n" +"8 | &s\n" +" | ^^ returns a reference to data owned by the current function\n" +"\n" +"Some errors have detailed explanations: E0106, E0515.\n" +"For more information about an error, try `rustc --explain E0106`.\n" +"error: could not compile `ownership` (bin \"ownership\") due to 2 previous " +"errors\n" +"```" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:371 +msgid "" +"This error message refers to a feature we haven’t covered yet: lifetimes. " +"We’ll discuss lifetimes in detail in Chapter 10. But, if you disregard the " +"parts about lifetimes, the message does contain the key to why this code is " +"a problem:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:380 +msgid "" +"Let’s take a closer look at exactly what’s happening at each stage of our " +"`dangle` code:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:390 +msgid "// dangle returns a reference to a String\n" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:392 +msgid "// s is a new String\n" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:394 +msgid "// we return a reference to the String, s\n" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:395 +msgid "" +"// Here, s goes out of scope, and is dropped. Its memory goes away.\n" +" // Danger!\n" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:399 +msgid "" +"Because `s` is created inside `dangle`, when the code of `dangle` is " +"finished, `s` will be deallocated. But we tried to return a reference to it. " +"That means this reference would be pointing to an invalid `String`. That’s " +"no good! Rust won’t let us do this." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:404 +msgid "The solution here is to return the `String` directly:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:418 +msgid "" +"This works without any problems. Ownership is moved out, and nothing is " +"deallocated." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:421 +msgid "The Rules of References" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:423 +msgid "Let’s recap what we’ve discussed about references:" +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:425 +msgid "" +"At any given time, you can have _either_ one mutable reference _or_ any " +"number of immutable references." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:427 +#: src/ch15-05-interior-mutability.md:27 +msgid "References must always be valid." +msgstr "" + +#: src/ch04-02-references-and-borrowing.md:429 +msgid "Next, we’ll look at a different kind of reference: slices." +msgstr "" + +#: src/ch04-03-slices.md:3 +msgid "" +"_Slices_ let you reference a contiguous sequence of elements in a " +"[collection](ch08-00-common-collections.md) rather than the whole " +"collection. A slice is a kind of reference, so it does not have ownership." +msgstr "" + +#: src/ch04-03-slices.md:7 +msgid "" +"Here’s a small programming problem: write a function that takes a string of " +"words separated by spaces and returns the first word it finds in that " +"string. If the function doesn’t find a space in the string, the whole string " +"must be one word, so the entire string should be returned." +msgstr "" + +#: src/ch04-03-slices.md:12 +msgid "" +"Let’s work through how we’d write the signature of this function without " +"using slices, to understand the problem that slices will solve:" +msgstr "" + +#: src/ch04-03-slices.md:19 +msgid "" +"The `first_word` function has a `&String` as a parameter. We don’t want " +"ownership, so this is fine. But what should we return? We don’t really have " +"a way to talk about _part_ of a string. However, we could return the index " +"of the end of the word, indicated by a space. Let’s try that, as shown in " +"Listing 4-7." +msgstr "" + +#: src/ch04-03-slices.md:31 src/ch04-03-slices.md:54 src/ch04-03-slices.md:72 +#: src/ch04-03-slices.md:106 src/ch04-03-slices.md:131 +#: src/ch04-03-slices.md:260 src/ch04-03-slices.md:303 +#: src/ch04-03-slices.md:386 src/ch04-03-slices.md:435 +#: src/ch10-03-lifetime-syntax.md:587 +msgid "b' '" +msgstr "" + +#: src/ch04-03-slices.md:42 +msgid "" +"Listing 4-7: The `first_word` function that returns " +"a byte index value into the `String` parameter" +msgstr "" + +#: src/ch04-03-slices.md:45 +msgid "" +"Because we need to go through the `String` element by element and check " +"whether a value is a space, we’ll convert our `String` to an array of bytes " +"using the `as_bytes` method." +msgstr "" + +#: src/ch04-03-slices.md:65 +msgid "" +"Next, we create an iterator over the array of bytes using the `iter` method:" +msgstr "" + +#: src/ch04-03-slices.md:83 +msgid "" +"We’ll discuss iterators in more detail in [Chapter 13](ch13-02-iterators." +"html). For now, know that `iter` is a method that returns " +"each element in a collection and that `enumerate` wraps the result of `iter` " +"and returns each element as part of a tuple instead. The first element of " +"the tuple returned from `enumerate` is the index, and the second element is " +"a reference to the element. This is a bit more convenient than calculating " +"the index ourselves." +msgstr "" + +#: src/ch04-03-slices.md:90 +msgid "" +"Because the `enumerate` method returns a tuple, we can use patterns to " +"destructure that tuple. We’ll be discussing patterns more in [Chapter 6]" +"(ch06-02-match.html#patterns-that-bind-to-values). In the " +"`for` loop, we specify a pattern that has `i` for the index in the tuple and " +"`&item` for the single byte in the tuple. Because we get a reference to the " +"element from `.iter().enumerate()`, we use `&` in the pattern." +msgstr "" + +#: src/ch04-03-slices.md:97 +msgid "" +"Inside the `for` loop, we search for the byte that represents the space by " +"using the byte literal syntax. If we find a space, we return the position. " +"Otherwise, we return the length of the string by using `s.len()`." +msgstr "" + +#: src/ch04-03-slices.md:117 +msgid "" +"We now have a way to find out the index of the end of the first word in the " +"string, but there’s a problem. We’re returning a `usize` on its own, but " +"it’s only a meaningful number in the context of the `&String`. In other " +"words, because it’s a separate value from the `String`, there’s no guarantee " +"that it will still be valid in the future. Consider the program in Listing " +"4-8 that uses the `first_word` function from Listing 4-7." +msgstr "" + +#: src/ch04-03-slices.md:140 src/ch04-03-slices.md:181 +#: src/ch04-03-slices.md:312 src/ch04-03-slices.md:395 +#: src/ch04-03-slices.md:404 src/ch04-03-slices.md:444 +#: src/ch04-03-slices.md:453 src/ch10-03-lifetime-syntax.md:596 +#: src/ch10-03-lifetime-syntax.md:601 +msgid "\"hello world\"" +msgstr "" + +#: src/ch04-03-slices.md:142 +msgid "// word will get the value 5\n" +msgstr "" + +#: src/ch04-03-slices.md:144 +msgid "// this empties the String, making it equal to \"\"\n" +msgstr "" + +#: src/ch04-03-slices.md:146 +msgid "" +"// word still has the value 5 here, but there's no more string that\n" +" // we could meaningfully use the value 5 with. word is now totally " +"invalid!\n" +msgstr "" + +#: src/ch04-03-slices.md:151 +msgid "" +"Listing 4-8: Storing the result from calling the " +"`first_word` function and then changing the `String` contents" +msgstr "" + +#: src/ch04-03-slices.md:154 +msgid "" +"This program compiles without any errors and would also do so if we used " +"`word` after calling `s.clear()`. Because `word` isn’t connected to the " +"state of `s` at all, `word` still contains the value `5`. We could use that " +"value `5` with the variable `s` to try to extract the first word out, but " +"this would be a bug because the contents of `s` have changed since we saved " +"`5` in `word`." +msgstr "" + +#: src/ch04-03-slices.md:160 +msgid "" +"Having to worry about the index in `word` getting out of sync with the data " +"in `s` is tedious and error prone! Managing these indices is even more " +"brittle if we write a `second_word` function. Its signature would have to " +"look like this:" +msgstr "" + +#: src/ch04-03-slices.md:168 +msgid "" +"Now we’re tracking a starting _and_ an ending index, and we have even more " +"values that were calculated from data in a particular state but aren’t tied " +"to that state at all. We have three unrelated variables floating around that " +"need to be kept in sync." +msgstr "" + +#: src/ch04-03-slices.md:173 +msgid "Luckily, Rust has a solution to this problem: string slices." +msgstr "" + +#: src/ch04-03-slices.md:175 +msgid "String Slices" +msgstr "" + +#: src/ch04-03-slices.md:177 +msgid "" +"A _string slice_ is a reference to part of a `String`, and it looks like " +"this:" +msgstr "" + +#: src/ch04-03-slices.md:188 +msgid "" +"Rather than a reference to the entire `String`, `hello` is a reference to a " +"portion of the `String`, specified in the extra `[0..5]` bit. We create " +"slices using a range within brackets by specifying `[starting_index.." +"ending_index]`, where `starting_index` is the first position in the slice " +"and `ending_index` is one more than the last position in the slice. " +"Internally, the slice data structure stores the starting position and the " +"length of the slice, which corresponds to `ending_index` minus " +"`starting_index`. So, in the case of `let world = &s[6..11];`, `world` would " +"be a slice that contains a pointer to the byte at index 6 of `s` with a " +"length value of `5`." +msgstr "" + +#: src/ch04-03-slices.md:198 +msgid "Figure 4-6 shows this in a diagram." +msgstr "" + +#: src/ch04-03-slices.md:200 +msgid "" +"\"Three" +msgstr "" + +#: src/ch04-03-slices.md:206 +msgid "" +"Figure 4-6: String slice referring to part of a " +"`String`" +msgstr "" + +#: src/ch04-03-slices.md:209 +msgid "" +"With Rust’s `..` range syntax, if you want to start at index 0, you can drop " +"the value before the two periods. In other words, these are equal:" +msgstr "" + +#: src/ch04-03-slices.md:219 +msgid "" +"By the same token, if your slice includes the last byte of the `String`, you " +"can drop the trailing number. That means these are equal:" +msgstr "" + +#: src/ch04-03-slices.md:231 +msgid "" +"You can also drop both values to take a slice of the entire string. So these " +"are equal:" +msgstr "" + +#: src/ch04-03-slices.md:243 +msgid "" +"Note: String slice range indices must occur at valid UTF-8 character " +"boundaries. If you attempt to create a string slice in the middle of a " +"multibyte character, your program will exit with an error. For the purposes " +"of introducing string slices, we are assuming ASCII only in this section; a " +"more thorough discussion of UTF-8 handling is in the [“Storing UTF-8 Encoded " +"Text with Strings”](ch08-02-strings.html#storing-utf-8-encoded-text-with-" +"strings) section of Chapter 8." +msgstr "" + +#: src/ch04-03-slices.md:250 +msgid "" +"With all this information in mind, let’s rewrite `first_word` to return a " +"slice. The type that signifies “string slice” is written as `&str`:" +msgstr "" + +#: src/ch04-03-slices.md:271 +msgid "" +"We get the index for the end of the word the same way we did in Listing 4-7, " +"by looking for the first occurrence of a space. When we find a space, we " +"return a string slice using the start of the string and the index of the " +"space as the starting and ending indices." +msgstr "" + +#: src/ch04-03-slices.md:276 +msgid "" +"Now when we call `first_word`, we get back a single value that is tied to " +"the underlying data. The value is made up of a reference to the starting " +"point of the slice and the number of elements in the slice." +msgstr "" + +#: src/ch04-03-slices.md:280 +msgid "Returning a slice would also work for a `second_word` function:" +msgstr "" + +#: src/ch04-03-slices.md:286 +msgid "" +"We now have a straightforward API that’s much harder to mess up because the " +"compiler will ensure the references into the `String` remain valid. Remember " +"the bug in the program in Listing 4-8, when we got the index to the end of " +"the first word but then cleared the string so our index was invalid? That " +"code was logically incorrect but didn’t show any immediate errors. The " +"problems would show up later if we kept trying to use the first word index " +"with an emptied string. Slices make this bug impossible and let us know we " +"have a problem with our code much sooner. Using the slice version of " +"`first_word` will throw a compile-time error:" +msgstr "" + +#: src/ch04-03-slices.md:316 +msgid "// error!\n" +msgstr "" + +#: src/ch04-03-slices.md:318 +msgid "\"the first word is: {word}\"" +msgstr "" + +#: src/ch04-03-slices.md:322 +msgid "Here’s the compiler error:" +msgstr "" + +#: src/ch04-03-slices.md:324 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling ownership v0.1.0 (file:///projects/ownership)\n" +"error[E0502]: cannot borrow `s` as mutable because it is also borrowed as " +"immutable\n" +" --> src/main.rs:18:5\n" +" |\n" +"16 | let word = first_word(&s);\n" +" | -- immutable borrow occurs here\n" +"17 |\n" +"18 | s.clear(); // error!\n" +" | ^^^^^^^^^ mutable borrow occurs here\n" +"19 |\n" +"20 | println!(\"the first word is: {word}\");\n" +" | ------ immutable borrow later used " +"here\n" +"\n" +"For more information about this error, try `rustc --explain E0502`.\n" +"error: could not compile `ownership` (bin \"ownership\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch04-03-slices.md:343 +msgid "" +"Recall from the borrowing rules that if we have an immutable reference to " +"something, we cannot also take a mutable reference. Because `clear` needs to " +"truncate the `String`, it needs to get a mutable reference. The `println!` " +"after the call to `clear` uses the reference in `word`, so the immutable " +"reference must still be active at that point. Rust disallows the mutable " +"reference in `clear` and the immutable reference in `word` from existing at " +"the same time, and compilation fails. Not only has Rust made our API easier " +"to use, but it has also eliminated an entire class of errors at compile time!" +msgstr "" + +#: src/ch04-03-slices.md:353 +msgid "" +msgstr "" + +#: src/ch04-03-slices.md:355 +msgid "String Literals as Slices" +msgstr "" + +#: src/ch04-03-slices.md:357 +msgid "" +"Recall that we talked about string literals being stored inside the binary. " +"Now that we know about slices, we can properly understand string literals:" +msgstr "" + +#: src/ch04-03-slices.md:364 +msgid "" +"The type of `s` here is `&str`: it’s a slice pointing to that specific point " +"of the binary. This is also why string literals are immutable; `&str` is an " +"immutable reference." +msgstr "" + +#: src/ch04-03-slices.md:368 +msgid "String Slices as Parameters" +msgstr "" + +#: src/ch04-03-slices.md:370 +msgid "" +"Knowing that you can take slices of literals and `String` values leads us to " +"one more improvement on `first_word`, and that’s its signature:" +msgstr "" + +#: src/ch04-03-slices.md:377 +msgid "" +"A more experienced Rustacean would write the signature shown in Listing 4-9 " +"instead because it allows us to use the same function on both `&String` " +"values and `&str` values." +msgstr "" + +#: src/ch04-03-slices.md:397 src/ch04-03-slices.md:446 +msgid "" +"// `first_word` works on slices of `String`s, whether partial or whole\n" +msgstr "" + +#: src/ch04-03-slices.md:400 +msgid "" +"// `first_word` also works on references to `String`s, which are equivalent\n" +msgstr "" + +#: src/ch04-03-slices.md:401 +msgid "// to whole slices of `String`s\n" +msgstr "" + +#: src/ch04-03-slices.md:406 src/ch04-03-slices.md:455 +msgid "" +"// `first_word` works on slices of string literals, whether partial or " +"whole\n" +msgstr "" + +#: src/ch04-03-slices.md:410 src/ch10-03-lifetime-syntax.md:606 +msgid "// Because string literals *are* string slices already,\n" +msgstr "" + +#: src/ch04-03-slices.md:411 src/ch10-03-lifetime-syntax.md:607 +msgid "// this works too, without the slice syntax!\n" +msgstr "" + +#: src/ch04-03-slices.md:416 +msgid "" +"Listing 4-9: Improving the `first_word` function by " +"using a string slice for the type of the `s` parameter" +msgstr "" + +#: src/ch04-03-slices.md:419 +msgid "" +"If we have a string slice, we can pass that directly. If we have a `String`, " +"we can pass a slice of the `String` or a reference to the `String`. This " +"flexibility takes advantage of _deref coercions_, a feature we will cover in " +"the [“Implicit Deref Coercions with Functions and Methods”](ch15-02-deref." +"html#implicit-deref-coercions-with-functions-and-methods) " +"section of Chapter 15." +msgstr "" + +#: src/ch04-03-slices.md:425 +msgid "" +"Defining a function to take a string slice instead of a reference to a " +"`String` makes our API more general and useful without losing any " +"functionality:" +msgstr "" + +#: src/ch04-03-slices.md:449 +msgid "" +"// `first_word` also works on references to `String`s, which are equivalent\n" +" // to whole slices of `String`s\n" +msgstr "" + +#: src/ch04-03-slices.md:459 +msgid "" +"// Because string literals *are* string slices already,\n" +" // this works too, without the slice syntax!\n" +msgstr "" + +#: src/ch04-03-slices.md:465 +msgid "Other Slices" +msgstr "" + +#: src/ch04-03-slices.md:467 +msgid "" +"String slices, as you might imagine, are specific to strings. But there’s a " +"more general slice type too. Consider this array:" +msgstr "" + +#: src/ch04-03-slices.md:474 +msgid "" +"Just as we might want to refer to part of a string, we might want to refer " +"to part of an array. We’d do so like this:" +msgstr "" + +#: src/ch04-03-slices.md:485 +msgid "" +"This slice has the type `&[i32]`. It works the same way as string slices do, " +"by storing a reference to the first element and a length. You’ll use this " +"kind of slice for all sorts of other collections. We’ll discuss these " +"collections in detail when we talk about vectors in Chapter 8." +msgstr "" + +#: src/ch04-03-slices.md:492 +msgid "" +"The concepts of ownership, borrowing, and slices ensure memory safety in " +"Rust programs at compile time. The Rust language gives you control over your " +"memory usage in the same way as other systems programming languages, but " +"having the owner of data automatically clean up that data when the owner " +"goes out of scope means you don’t have to write and debug extra code to get " +"this control." +msgstr "" + +#: src/ch04-03-slices.md:498 +msgid "" +"Ownership affects how lots of other parts of Rust work, so we’ll talk about " +"these concepts further throughout the rest of the book. Let’s move on to " +"Chapter 5 and look at grouping pieces of data together in a `struct`." +msgstr "" + +#: src/ch05-00-structs.md:3 +msgid "" +"A _struct_, or _structure_, is a custom data type that lets you package " +"together and name multiple related values that make up a meaningful group. " +"If you’re familiar with an object-oriented language, a _struct_ is like an " +"object’s data attributes. In this chapter, we’ll compare and contrast tuples " +"with structs to build on what you already know and demonstrate when structs " +"are a better way to group data." +msgstr "" + +#: src/ch05-00-structs.md:10 +msgid "" +"We’ll demonstrate how to define and instantiate structs. We’ll discuss how " +"to define associated functions, especially the kind of associated functions " +"called _methods_, to specify behavior associated with a struct type. Structs " +"and enums (discussed in Chapter 6) are the building blocks for creating new " +"types in your program’s domain to take full advantage of Rust’s compile-time " +"type checking." +msgstr "" + +#: src/ch05-01-defining-structs.md:3 +msgid "" +"Structs are similar to tuples, discussed in [“The Tuple Type”](ch03-02-data-" +"types.html#the-tuple-type) section, in that both hold multiple related values. Like tuples, " +"the pieces of a struct can be different types. Unlike with tuples, in a " +"struct you’ll name each piece of data so it’s clear what the values mean. " +"Adding these names means that structs are more flexible than tuples: you " +"don’t have to rely on the order of the data to specify or access the values " +"of an instance." +msgstr "" + +#: src/ch05-01-defining-structs.md:10 +msgid "" +"To define a struct, we enter the keyword `struct` and name the entire " +"struct. A struct’s name should describe the significance of the pieces of " +"data being grouped together. Then, inside curly brackets, we define the " +"names and types of the pieces of data, which we call _fields_. For example, " +"Listing 5-1 shows a struct that stores information about a user account." +msgstr "" + +#: src/ch05-01-defining-structs.md:29 +msgid "Listing 5-1: A `User` struct definition" +msgstr "" + +#: src/ch05-01-defining-structs.md:31 +msgid "" +"To use a struct after we’ve defined it, we create an _instance_ of that " +"struct by specifying concrete values for each of the fields. We create an " +"instance by stating the name of the struct and then add curly brackets " +"containing _key: value_ pairs, where the keys are the names of the fields " +"and the values are the data we want to store in those fields. We don’t have " +"to specify the fields in the same order in which we declared them in the " +"struct. In other words, the struct definition is like a general template for " +"the type, and instances fill in that template with particular data to create " +"values of the type. For example, we can declare a particular user as shown " +"in Listing 5-2." +msgstr "" + +#: src/ch05-01-defining-structs.md:54 src/ch05-01-defining-structs.md:83 +#: src/ch05-01-defining-structs.md:126 src/ch05-01-defining-structs.md:171 +#: src/ch05-01-defining-structs.md:211 src/ch05-01-defining-structs.md:247 +#: src/ch05-01-defining-structs.md:374 +msgid "\"someusername123\"" +msgstr "" + +#: src/ch05-01-defining-structs.md:55 src/ch05-01-defining-structs.md:84 +#: src/ch05-01-defining-structs.md:125 src/ch05-01-defining-structs.md:170 +#: src/ch05-01-defining-structs.md:210 src/ch05-01-defining-structs.md:246 +#: src/ch05-01-defining-structs.md:375 +msgid "\"someone@example.com\"" +msgstr "" + +#: src/ch05-01-defining-structs.md:61 +msgid "" +"Listing 5-2: Creating an instance of the `User` " +"struct" +msgstr "" + +#: src/ch05-01-defining-structs.md:64 +msgid "" +"To get a specific value from a struct, we use dot notation. For example, to " +"access this user’s email address, we use `user1.email`. If the instance is " +"mutable, we can change a value by using the dot notation and assigning into " +"a particular field. Listing 5-3 shows how to change the value in the `email` " +"field of a mutable `User` instance." +msgstr "" + +#: src/ch05-01-defining-structs.md:88 +msgid "\"anotheremail@example.com\"" +msgstr "" + +#: src/ch05-01-defining-structs.md:92 +msgid "" +"Listing 5-3: Changing the value in the `email` field " +"of a `User` instance" +msgstr "" + +#: src/ch05-01-defining-structs.md:95 +msgid "" +"Note that the entire instance must be mutable; Rust doesn’t allow us to mark " +"only certain fields as mutable. As with any expression, we can construct a " +"new instance of the struct as the last expression in the function body to " +"implicitly return that new instance." +msgstr "" + +#: src/ch05-01-defining-structs.md:100 +msgid "" +"Listing 5-4 shows a `build_user` function that returns a `User` instance " +"with the given email and username. The `active` field gets the value of " +"`true`, and the `sign_in_count` gets a value of `1`." +msgstr "" + +#: src/ch05-01-defining-structs.md:131 +msgid "" +"Listing 5-4: A `build_user` function that takes an " +"email and username and returns a `User` instance" +msgstr "" + +#: src/ch05-01-defining-structs.md:134 +msgid "" +"It makes sense to name the function parameters with the same name as the " +"struct fields, but having to repeat the `email` and `username` field names " +"and variables is a bit tedious. If the struct had more fields, repeating " +"each name would get even more annoying. Luckily, there’s a convenient " +"shorthand!" +msgstr "" + +#: src/ch05-01-defining-structs.md:140 +msgid "" +"" +msgstr "" + +#: src/ch05-01-defining-structs.md:142 +msgid "Using the Field Init Shorthand" +msgstr "" + +#: src/ch05-01-defining-structs.md:144 +msgid "" +"Because the parameter names and the struct field names are exactly the same " +"in Listing 5-4, we can use the _field init shorthand_ syntax to rewrite " +"`build_user` so it behaves exactly the same but doesn’t have the repetition " +"of `username` and `email`, as shown in Listing 5-5." +msgstr "" + +#: src/ch05-01-defining-structs.md:176 +msgid "" +"Listing 5-5: A `build_user` function that uses field " +"init shorthand because the `username` and `email` parameters have the same " +"name as struct fields" +msgstr "" + +#: src/ch05-01-defining-structs.md:180 +msgid "" +"Here, we’re creating a new instance of the `User` struct, which has a field " +"named `email`. We want to set the `email` field’s value to the value in the " +"`email` parameter of the `build_user` function. Because the `email` field " +"and the `email` parameter have the same name, we only need to write `email` " +"rather than `email: email`." +msgstr "" + +#: src/ch05-01-defining-structs.md:186 +msgid "Creating Instances from Other Instances with Struct Update Syntax" +msgstr "" + +#: src/ch05-01-defining-structs.md:188 +msgid "" +"It’s often useful to create a new instance of a struct that includes most of " +"the values from another instance, but changes some. You can do this using " +"_struct update syntax_." +msgstr "" + +#: src/ch05-01-defining-structs.md:192 +msgid "" +"First, in Listing 5-6 we show how to create a new `User` instance in `user2` " +"regularly, without the update syntax. We set a new value for `email` but " +"otherwise use the same values from `user1` that we created in Listing 5-2." +msgstr "" + +#: src/ch05-01-defining-structs.md:219 src/ch05-01-defining-structs.md:253 +msgid "\"another@example.com\"" +msgstr "" + +#: src/ch05-01-defining-structs.md:225 +msgid "" +"Listing 5-6: Creating a new `User` instance using " +"all but one of the values from `user1`" +msgstr "" + +#: src/ch05-01-defining-structs.md:228 +msgid "" +"Using struct update syntax, we can achieve the same effect with less code, " +"as shown in Listing 5-7. The syntax `..` specifies that the remaining fields " +"not explicitly set should have the same value as the fields in the given " +"instance." +msgstr "" + +#: src/ch05-01-defining-structs.md:259 +msgid "" +"Listing 5-7: Using struct update syntax to set a new " +"`email` value for a `User` instance but to use the rest of the values from " +"`user1`" +msgstr "" + +#: src/ch05-01-defining-structs.md:263 +msgid "" +"The code in Listing 5-7 also creates an instance in `user2` that has a " +"different value for `email` but has the same values for the `username`, " +"`active`, and `sign_in_count` fields from `user1`. The `..user1` must come " +"last to specify that any remaining fields should get their values from the " +"corresponding fields in `user1`, but we can choose to specify values for as " +"many fields as we want in any order, regardless of the order of the fields " +"in the struct’s definition." +msgstr "" + +#: src/ch05-01-defining-structs.md:271 +msgid "" +"Note that the struct update syntax uses `=` like an assignment; this is " +"because it moves the data, just as we saw in the [“Variables and Data " +"Interacting with Move”](ch04-01-what-is-ownership.html#variables-and-data-" +"interacting-with-move) section. In this example, we can no " +"longer use `user1` as a whole after creating `user2` because the `String` in " +"the `username` field of `user1` was moved into `user2`. If we had given " +"`user2` new `String` values for both `email` and `username`, and thus only " +"used the `active` and `sign_in_count` values from `user1`, then `user1` " +"would still be valid after creating `user2`. Both `active` and " +"`sign_in_count` are types that implement the `Copy` trait, so the behavior " +"we discussed in the [“Stack-Only Data: Copy”](ch04-01-what-is-ownership." +"html#stack-only-data-copy) section would apply." +msgstr "" + +#: src/ch05-01-defining-structs.md:282 +msgid "Using Tuple Structs Without Named Fields to Create Different Types" +msgstr "" + +#: src/ch05-01-defining-structs.md:284 +msgid "" +"Rust also supports structs that look similar to tuples, called _tuple " +"structs_. Tuple structs have the added meaning the struct name provides but " +"don’t have names associated with their fields; rather, they just have the " +"types of the fields. Tuple structs are useful when you want to give the " +"whole tuple a name and make the tuple a different type from other tuples, " +"and when naming each field as in a regular struct would be verbose or " +"redundant." +msgstr "" + +#: src/ch05-01-defining-structs.md:291 +msgid "" +"To define a tuple struct, start with the `struct` keyword and the struct " +"name followed by the types in the tuple. For example, here we define and use " +"two tuple structs named `Color` and `Point`:" +msgstr "" + +#: src/ch05-01-defining-structs.md:307 +msgid "" +"Note that the `black` and `origin` values are different types because " +"they’re instances of different tuple structs. Each struct you define is its " +"own type, even though the fields within the struct might have the same " +"types. For example, a function that takes a parameter of type `Color` cannot " +"take a `Point` as an argument, even though both types are made up of three " +"`i32` values. Otherwise, tuple struct instances are similar to tuples in " +"that you can destructure them into their individual pieces, and you can use " +"a `.` followed by the index to access an individual value." +msgstr "" + +#: src/ch05-01-defining-structs.md:316 +msgid "Unit-Like Structs Without Any Fields" +msgstr "" + +#: src/ch05-01-defining-structs.md:318 +msgid "" +"You can also define structs that don’t have any fields! These are called " +"_unit-like structs_ because they behave similarly to `()`, the unit type " +"that we mentioned in [“The Tuple Type”](ch03-02-data-types.html#the-tuple-" +"type) section. Unit-like structs can be useful when you need " +"to implement a trait on some type but don’t have any data that you want to " +"store in the type itself. We’ll discuss traits in Chapter 10. Here’s an " +"example of declaring and instantiating a unit struct named `AlwaysEqual`:" +msgstr "" + +#: src/ch05-01-defining-structs.md:336 +msgid "" +"To define `AlwaysEqual`, we use the `struct` keyword, the name we want, and " +"then a semicolon. No need for curly brackets or parentheses! Then we can get " +"an instance of `AlwaysEqual` in the `subject` variable in a similar way: " +"using the name we defined, without any curly brackets or parentheses. " +"Imagine that later we’ll implement behavior for this type such that every " +"instance of `AlwaysEqual` is always equal to every instance of any other " +"type, perhaps to have a known result for testing purposes. We wouldn’t need " +"any data to implement that behavior! You’ll see in Chapter 10 how to define " +"traits and implement them on any type, including unit-like structs." +msgstr "" + +#: src/ch05-01-defining-structs.md:346 +msgid "Ownership of Struct Data" +msgstr "" + +#: src/ch05-01-defining-structs.md:348 +msgid "" +"In the `User` struct definition in Listing 5-1, we used the owned `String` " +"type rather than the `&str` string slice type. This is a deliberate choice " +"because we want each instance of this struct to own all of its data and for " +"that data to be valid for as long as the entire struct is valid." +msgstr "" + +#: src/ch05-01-defining-structs.md:353 +msgid "" +"It’s also possible for structs to store references to data owned by " +"something else, but to do so requires the use of _lifetimes_, a Rust feature " +"that we’ll discuss in Chapter 10. Lifetimes ensure that the data referenced " +"by a struct is valid for as long as the struct is. Let’s say you try to " +"store a reference in a struct without specifying lifetimes, like the " +"following; this won’t work:" +msgstr "" + +#: src/ch05-01-defining-structs.md:381 +msgid "The compiler will complain that it needs lifetime specifiers:" +msgstr "" + +#: src/ch05-01-defining-structs.md:383 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling structs v0.1.0 (file:///projects/structs)\n" +"error[E0106]: missing lifetime specifier\n" +" --> src/main.rs:3:15\n" +" |\n" +"3 | username: &str,\n" +" | ^ expected named lifetime parameter\n" +" |\n" +"help: consider introducing a named lifetime parameter\n" +" |\n" +"1 ~ struct User<'a> {\n" +"2 | active: bool,\n" +"3 ~ username: &'a str,\n" +" |\n" +"\n" +"error[E0106]: missing lifetime specifier\n" +" --> src/main.rs:4:12\n" +" |\n" +"4 | email: &str,\n" +" | ^ expected named lifetime parameter\n" +" |\n" +"help: consider introducing a named lifetime parameter\n" +" |\n" +"1 ~ struct User<'a> {\n" +"2 | active: bool,\n" +"3 | username: &str,\n" +"4 ~ email: &'a str,\n" +" |\n" +"\n" +"For more information about this error, try `rustc --explain E0106`.\n" +"error: could not compile `structs` (bin \"structs\") due to 2 previous " +"errors\n" +"```" +msgstr "" + +#: src/ch05-01-defining-structs.md:417 +msgid "" +"In Chapter 10, we’ll discuss how to fix these errors so you can store " +"references in structs, but for now, we’ll fix errors like these using owned " +"types like `String` instead of references like `&str`." +msgstr "" + +#: src/ch05-02-example-structs.md:3 +msgid "" +"To understand when we might want to use structs, let’s write a program that " +"calculates the area of a rectangle. We’ll start by using single variables, " +"and then refactor the program until we’re using structs instead." +msgstr "" + +#: src/ch05-02-example-structs.md:7 +msgid "" +"Let’s make a new binary project with Cargo called _rectangles_ that will " +"take the width and height of a rectangle specified in pixels and calculate " +"the area of the rectangle. Listing 5-8 shows a short program with one way of " +"doing exactly that in our project’s _src/main.rs_." +msgstr "" + +#: src/ch05-02-example-structs.md:20 src/ch05-02-example-structs.md:55 +#: src/ch05-02-example-structs.md:83 src/ch05-02-example-structs.md:129 +#: src/ch05-03-method-syntax.md:40 +msgid "\"The area of the rectangle is {} square pixels.\"" +msgstr "" + +#: src/ch05-02-example-structs.md:30 +msgid "" +"Listing 5-8: Calculating the area of a rectangle " +"specified by separate width and height variables" +msgstr "" + +#: src/ch05-02-example-structs.md:33 +msgid "Now, run this program using `cargo run`:" +msgstr "" + +#: src/ch05-02-example-structs.md:35 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling rectangles v0.1.0 (file:///projects/rectangles)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.42s\n" +" Running `target/debug/rectangles`\n" +"The area of the rectangle is 1500 square pixels.\n" +"```" +msgstr "" + +#: src/ch05-02-example-structs.md:43 +msgid "" +"This code succeeds in figuring out the area of the rectangle by calling the " +"`area` function with each dimension, but we can do more to make this code " +"clear and readable." +msgstr "" + +#: src/ch05-02-example-structs.md:47 +msgid "The issue with this code is evident in the signature of `area`:" +msgstr "" + +#: src/ch05-02-example-structs.md:65 +msgid "" +"The `area` function is supposed to calculate the area of one rectangle, but " +"the function we wrote has two parameters, and it’s not clear anywhere in our " +"program that the parameters are related. It would be more readable and more " +"manageable to group width and height together. We’ve already discussed one " +"way we might do that in [“The Tuple Type”](ch03-02-data-types.html#the-tuple-" +"type) section of Chapter 3: by using tuples." +msgstr "" + +#: src/ch05-02-example-structs.md:72 +msgid "Refactoring with Tuples" +msgstr "" + +#: src/ch05-02-example-structs.md:74 +msgid "Listing 5-9 shows another version of our program that uses tuples." +msgstr "" + +#: src/ch05-02-example-structs.md:93 +msgid "" +"Listing 5-9: Specifying the width and height of the " +"rectangle with a tuple" +msgstr "" + +#: src/ch05-02-example-structs.md:96 +msgid "" +"In one way, this program is better. Tuples let us add a bit of structure, " +"and we’re now passing just one argument. But in another way, this version is " +"less clear: tuples don’t name their elements, so we have to index into the " +"parts of the tuple, making our calculation less obvious." +msgstr "" + +#: src/ch05-02-example-structs.md:101 +msgid "" +"Mixing up the width and height wouldn’t matter for the area calculation, but " +"if we want to draw the rectangle on the screen, it would matter! We would " +"have to keep in mind that `width` is the tuple index `0` and `height` is the " +"tuple index `1`. This would be even harder for someone else to figure out " +"and keep in mind if they were to use our code. Because we haven’t conveyed " +"the meaning of our data in our code, it’s now easier to introduce errors." +msgstr "" + +#: src/ch05-02-example-structs.md:108 +msgid "Refactoring with Structs: Adding More Meaning" +msgstr "" + +#: src/ch05-02-example-structs.md:110 +msgid "" +"We use structs to add meaning by labeling the data. We can transform the " +"tuple we’re using into a struct with a name for the whole as well as names " +"for the parts, as shown in Listing 5-10." +msgstr "" + +#: src/ch05-02-example-structs.md:139 +msgid "" +"Listing 5-10: Defining a `Rectangle` struct" +msgstr "" + +#: src/ch05-02-example-structs.md:141 +msgid "" +"Here we’ve defined a struct and named it `Rectangle`. Inside the curly " +"brackets, we defined the fields as `width` and `height`, both of which have " +"type `u32`. Then, in `main`, we created a particular instance of `Rectangle` " +"that has a width of `30` and a height of `50`." +msgstr "" + +#: src/ch05-02-example-structs.md:146 +msgid "" +"Our `area` function is now defined with one parameter, which we’ve named " +"`rectangle`, whose type is an immutable borrow of a struct `Rectangle` " +"instance. As mentioned in Chapter 4, we want to borrow the struct rather " +"than take ownership of it. This way, `main` retains its ownership and can " +"continue using `rect1`, which is the reason we use the `&` in the function " +"signature and where we call the function." +msgstr "" + +#: src/ch05-02-example-structs.md:153 +msgid "" +"The `area` function accesses the `width` and `height` fields of the " +"`Rectangle` instance (note that accessing fields of a borrowed struct " +"instance does not move the field values, which is why you often see borrows " +"of structs). Our function signature for `area` now says exactly what we " +"mean: calculate the area of `Rectangle`, using its `width` and `height` " +"fields. This conveys that the width and height are related to each other, " +"and it gives descriptive names to the values rather than using the tuple " +"index values of `0` and `1`. This is a win for clarity." +msgstr "" + +#: src/ch05-02-example-structs.md:162 +msgid "Adding Useful Functionality with Derived Traits" +msgstr "" + +#: src/ch05-02-example-structs.md:164 +msgid "" +"It’d be useful to be able to print an instance of `Rectangle` while we’re " +"debugging our program and see the values for all its fields. Listing 5-11 " +"tries using the [`println!` macro](../std/macro.println.html) " +"as we have used in previous chapters. This won’t work, however." +msgstr "" + +#: src/ch05-02-example-structs.md:183 +msgid "\"rect1 is {}\"" +msgstr "" + +#: src/ch05-02-example-structs.md:187 +msgid "" +"Listing 5-11: Attempting to print a `Rectangle` " +"instance" +msgstr "" + +#: src/ch05-02-example-structs.md:190 +msgid "When we compile this code, we get an error with this core message:" +msgstr "" + +#: src/ch05-02-example-structs.md:196 +msgid "" +"The `println!` macro can do many kinds of formatting, and by default, the " +"curly brackets tell `println!` to use formatting known as `Display`: output " +"intended for direct end user consumption. The primitive types we’ve seen so " +"far implement `Display` by default because there’s only one way you’d want " +"to show a `1` or any other primitive type to a user. But with structs, the " +"way `println!` should format the output is less clear because there are more " +"display possibilities: Do you want commas or not? Do you want to print the " +"curly brackets? Should all the fields be shown? Due to this ambiguity, Rust " +"doesn’t try to guess what we want, and structs don’t have a provided " +"implementation of `Display` to use with `println!` and the `{}` placeholder." +msgstr "" + +#: src/ch05-02-example-structs.md:207 +msgid "If we continue reading the errors, we’ll find this helpful note:" +msgstr "" + +#: src/ch05-02-example-structs.md:214 +msgid "" +"Let’s try it! The `println!` macro call will now look like `println!(\"rect1 " +"is {rect1:?}\");`. Putting the specifier `:?` inside the curly brackets " +"tells `println!` we want to use an output format called `Debug`. The `Debug` " +"trait enables us to print our struct in a way that is useful for developers " +"so we can see its value while we’re debugging our code." +msgstr "" + +#: src/ch05-02-example-structs.md:220 +msgid "Compile the code with this change. Drat! We still get an error:" +msgstr "" + +#: src/ch05-02-example-structs.md:226 +msgid "But again, the compiler gives us a helpful note:" +msgstr "" + +#: src/ch05-02-example-structs.md:233 +msgid "" +"Rust _does_ include functionality to print out debugging information, but we " +"have to explicitly opt in to make that functionality available for our " +"struct. To do that, we add the outer attribute `#[derive(Debug)]` just " +"before the struct definition, as shown in Listing 5-12." +msgstr "" + +#: src/ch05-02-example-structs.md:253 +msgid "\"rect1 is {rect1:?}\"" +msgstr "" + +#: src/ch05-02-example-structs.md:257 +msgid "" +"Listing 5-12: Adding the attribute to derive the " +"`Debug` trait and printing the `Rectangle` instance using debug formatting" +msgstr "" + +#: src/ch05-02-example-structs.md:260 +msgid "" +"Now when we run the program, we won’t get any errors, and we’ll see the " +"following output:" +msgstr "" + +#: src/ch05-02-example-structs.md:263 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling rectangles v0.1.0 (file:///projects/rectangles)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.48s\n" +" Running `target/debug/rectangles`\n" +"rect1 is Rectangle { width: 30, height: 50 }\n" +"```" +msgstr "" + +#: src/ch05-02-example-structs.md:271 +msgid "" +"Nice! It’s not the prettiest output, but it shows the values of all the " +"fields for this instance, which would definitely help during debugging. When " +"we have larger structs, it’s useful to have output that’s a bit easier to " +"read; in those cases, we can use `{:#?}` instead of `{:?}` in the `println!` " +"string. In this example, using the `{:#?}` style will output the following:" +msgstr "" + +#: src/ch05-02-example-structs.md:277 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling rectangles v0.1.0 (file:///projects/rectangles)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.48s\n" +" Running `target/debug/rectangles`\n" +"rect1 is Rectangle {\n" +" width: 30,\n" +" height: 50,\n" +"}\n" +"```" +msgstr "" + +#: src/ch05-02-example-structs.md:288 +msgid "" +"Another way to print out a value using the `Debug` format is to use the " +"[`dbg!` macro](../std/macro.dbg.html), which takes ownership " +"of an expression (as opposed to `println!`, which takes a reference), prints " +"the file and line number of where that `dbg!` macro call occurs in your code " +"along with the resultant value of that expression, and returns ownership of " +"the value." +msgstr "" + +#: src/ch05-02-example-structs.md:294 +msgid "" +"Note: Calling the `dbg!` macro prints to the standard error console stream " +"(`stderr`), as opposed to `println!`, which prints to the standard output " +"console stream (`stdout`). We’ll talk more about `stderr` and `stdout` in " +"the [“Writing Error Messages to Standard Error Instead of Standard Output” " +"section in Chapter 12](ch12-06-writing-to-stderr-instead-of-stdout.html)." +msgstr "" + +#: src/ch05-02-example-structs.md:300 +msgid "" +"Here’s an example where we’re interested in the value that gets assigned to " +"the `width` field, as well as the value of the whole struct in `rect1`:" +msgstr "" + +#: src/ch05-02-example-structs.md:321 +msgid "" +"We can put `dbg!` around the expression `30 * scale` and, because `dbg!` " +"returns ownership of the expression’s value, the `width` field will get the " +"same value as if we didn’t have the `dbg!` call there. We don’t want `dbg!` " +"to take ownership of `rect1`, so we use a reference to `rect1` in the next " +"call. Here’s what the output of this example looks like:" +msgstr "" + +#: src/ch05-02-example-structs.md:327 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling rectangles v0.1.0 (file:///projects/rectangles)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.61s\n" +" Running `target/debug/rectangles`\n" +"[src/main.rs:10:16] 30 * scale = 60\n" +"[src/main.rs:14:5] &rect1 = Rectangle {\n" +" width: 60,\n" +" height: 50,\n" +"}\n" +"```" +msgstr "" + +#: src/ch05-02-example-structs.md:339 +msgid "" +"We can see the first bit of output came from _src/main.rs_ line 10 where " +"we’re debugging the expression `30 * scale`, and its resultant value is `60` " +"(the `Debug` formatting implemented for integers is to print only their " +"value). The `dbg!` call on line 14 of _src/main.rs_ outputs the value of " +"`&rect1`, which is the `Rectangle` struct. This output uses the pretty " +"`Debug` formatting of the `Rectangle` type. The `dbg!` macro can be really " +"helpful when you’re trying to figure out what your code is doing!" +msgstr "" + +#: src/ch05-02-example-structs.md:347 +msgid "" +"In addition to the `Debug` trait, Rust has provided a number of traits for " +"us to use with the `derive` attribute that can add useful behavior to our " +"custom types. Those traits and their behaviors are listed in [Appendix C]" +"(appendix-03-derivable-traits.md). We’ll cover how to implement these traits with custom behavior " +"as well as how to create your own traits in Chapter 10. There are also many " +"attributes other than `derive`; for more information, see [the “Attributes” " +"section of the Rust Reference](../reference/attributes.html)." +msgstr "" + +#: src/ch05-02-example-structs.md:355 +msgid "" +"Our `area` function is very specific: it only computes the area of " +"rectangles. It would be helpful to tie this behavior more closely to our " +"`Rectangle` struct because it won’t work with any other type. Let’s look at " +"how we can continue to refactor this code by turning the `area` function " +"into an `area` _method_ defined on our `Rectangle` type." +msgstr "" + +#: src/ch05-03-method-syntax.md:3 +msgid "" +"_Methods_ are similar to functions: we declare them with the `fn` keyword " +"and a name, they can have parameters and a return value, and they contain " +"some code that’s run when the method is called from somewhere else. Unlike " +"functions, methods are defined within the context of a struct (or an enum or " +"a trait object, which we cover in [Chapter 6](ch06-00-enums.html) and [Chapter 17](ch17-02-trait-objects.md), " +"respectively), and their first parameter is always `self`, which represents " +"the instance of the struct the method is being called on." +msgstr "" + +#: src/ch05-03-method-syntax.md:12 +msgid "Defining Methods" +msgstr "" + +#: src/ch05-03-method-syntax.md:14 +msgid "" +"Let’s change the `area` function that has a `Rectangle` instance as a " +"parameter and instead make an `area` method defined on the `Rectangle` " +"struct, as shown in Listing 5-13." +msgstr "" + +#: src/ch05-03-method-syntax.md:46 +msgid "" +"Listing 5-13: Defining an `area` method on the " +"`Rectangle` struct" +msgstr "" + +#: src/ch05-03-method-syntax.md:49 +msgid "" +"To define the function within the context of `Rectangle`, we start an `impl` " +"(implementation) block for `Rectangle`. Everything within this `impl` block " +"will be associated with the `Rectangle` type. Then we move the `area` " +"function within the `impl` curly brackets and change the first (and in this " +"case, only) parameter to be `self` in the signature and everywhere within " +"the body. In `main`, where we called the `area` function and passed `rect1` " +"as an argument, we can instead use _method syntax_ to call the `area` method " +"on our `Rectangle` instance. The method syntax goes after an instance: we " +"add a dot followed by the method name, parentheses, and any arguments." +msgstr "" + +#: src/ch05-03-method-syntax.md:59 +msgid "" +"In the signature for `area`, we use `&self` instead of `rectangle: " +"&Rectangle`. The `&self` is actually short for `self: &Self`. Within an " +"`impl` block, the type `Self` is an alias for the type that the `impl` block " +"is for. Methods must have a parameter named `self` of type `Self` for their " +"first parameter, so Rust lets you abbreviate this with only the name `self` " +"in the first parameter spot. Note that we still need to use the `&` in front " +"of the `self` shorthand to indicate that this method borrows the `Self` " +"instance, just as we did in `rectangle: &Rectangle`. Methods can take " +"ownership of `self`, borrow `self` immutably, as we’ve done here, or borrow " +"`self` mutably, just as they can any other parameter." +msgstr "" + +#: src/ch05-03-method-syntax.md:70 +msgid "" +"We chose `&self` here for the same reason we used `&Rectangle` in the " +"function version: we don’t want to take ownership, and we just want to read " +"the data in the struct, not write to it. If we wanted to change the instance " +"that we’ve called the method on as part of what the method does, we’d use " +"`&mut self` as the first parameter. Having a method that takes ownership of " +"the instance by using just `self` as the first parameter is rare; this " +"technique is usually used when the method transforms `self` into something " +"else and you want to prevent the caller from using the original instance " +"after the transformation." +msgstr "" + +#: src/ch05-03-method-syntax.md:79 +msgid "" +"The main reason for using methods instead of functions, in addition to " +"providing method syntax and not having to repeat the type of `self` in every " +"method’s signature, is for organization. We’ve put all the things we can do " +"with an instance of a type in one `impl` block rather than making future " +"users of our code search for capabilities of `Rectangle` in various places " +"in the library we provide." +msgstr "" + +#: src/ch05-03-method-syntax.md:86 +msgid "" +"Note that we can choose to give a method the same name as one of the " +"struct’s fields. For example, we can define a method on `Rectangle` that is " +"also named `width`:" +msgstr "" + +#: src/ch05-03-method-syntax.md:112 +msgid "\"The rectangle has a nonzero width; it is {}\"" +msgstr "" + +#: src/ch05-03-method-syntax.md:117 +msgid "" +"Here, we’re choosing to make the `width` method return `true` if the value " +"in the instance’s `width` field is greater than `0` and `false` if the value " +"is `0`: we can use a field within a method of the same name for any purpose. " +"In `main`, when we follow `rect1.width` with parentheses, Rust knows we mean " +"the method `width`. When we don’t use parentheses, Rust knows we mean the " +"field `width`." +msgstr "" + +#: src/ch05-03-method-syntax.md:124 +msgid "" +"Often, but not always, when we give a method the same name as a field we " +"want it to only return the value in the field and do nothing else. Methods " +"like this are called _getters_, and Rust does not implement them " +"automatically for struct fields as some other languages do. Getters are " +"useful because you can make the field private but the method public, and " +"thus enable read-only access to that field as part of the type’s public API. " +"We will discuss what public and private are and how to designate a field or " +"method as public or private in [Chapter 7](ch07-03-paths-for-referring-to-an-" +"item-in-the-module-tree.html#exposing-paths-with-the-pub-keyword)." +msgstr "" + +#: src/ch05-03-method-syntax.md:133 +msgid "Where’s the `->` Operator?" +msgstr "" + +#: src/ch05-03-method-syntax.md:135 +msgid "" +"In C and C++, two different operators are used for calling methods: you use " +"`.` if you’re calling a method on the object directly and `->` if you’re " +"calling the method on a pointer to the object and need to dereference the " +"pointer first. In other words, if `object` is a pointer, `object-" +">something()` is similar to `(*object).something()`." +msgstr "" + +#: src/ch05-03-method-syntax.md:141 +msgid "" +"Rust doesn’t have an equivalent to the `->` operator; instead, Rust has a " +"feature called _automatic referencing and dereferencing_. Calling methods is " +"one of the few places in Rust that has this behavior." +msgstr "" + +#: src/ch05-03-method-syntax.md:145 +msgid "" +"Here’s how it works: when you call a method with `object.something()`, Rust " +"automatically adds in `&`, `&mut`, or `*` so `object` matches the signature " +"of the method. In other words, the following are the same:" +msgstr "" + +#: src/ch05-03-method-syntax.md:171 +msgid "" +"The first one looks much cleaner. This automatic referencing behavior works " +"because methods have a clear receiver—the type of `self`. Given the receiver " +"and name of a method, Rust can figure out definitively whether the method is " +"reading (`&self`), mutating (`&mut self`), or consuming (`self`). The fact " +"that Rust makes borrowing implicit for method receivers is a big part of " +"making ownership ergonomic in practice." +msgstr "" + +#: src/ch05-03-method-syntax.md:178 +msgid "Methods with More Parameters" +msgstr "" + +#: src/ch05-03-method-syntax.md:180 +msgid "" +"Let’s practice using methods by implementing a second method on the " +"`Rectangle` struct. This time we want an instance of `Rectangle` to take " +"another instance of `Rectangle` and return `true` if the second `Rectangle` " +"can fit completely within `self` (the first `Rectangle`); otherwise, it " +"should return `false`. That is, once we’ve defined the `can_hold` method, we " +"want to be able to write the program shown in Listing 5-14." +msgstr "" + +#: src/ch05-03-method-syntax.md:204 src/ch05-03-method-syntax.md:268 +#: src/ch05-03-method-syntax.md:370 +msgid "\"Can rect1 hold rect2? {}\"" +msgstr "" + +#: src/ch05-03-method-syntax.md:205 src/ch05-03-method-syntax.md:269 +#: src/ch05-03-method-syntax.md:371 +msgid "\"Can rect1 hold rect3? {}\"" +msgstr "" + +#: src/ch05-03-method-syntax.md:209 +msgid "" +"Listing 5-14: Using the as-yet-unwritten `can_hold` " +"method" +msgstr "" + +#: src/ch05-03-method-syntax.md:212 +msgid "" +"The expected output would look like the following because both dimensions of " +"`rect2` are smaller than the dimensions of `rect1`, but `rect3` is wider " +"than `rect1`:" +msgstr "" + +#: src/ch05-03-method-syntax.md:221 +msgid "" +"We know we want to define a method, so it will be within the `impl " +"Rectangle` block. The method name will be `can_hold`, and it will take an " +"immutable borrow of another `Rectangle` as a parameter. We can tell what the " +"type of the parameter will be by looking at the code that calls the method: " +"`rect1.can_hold(&rect2)` passes in `&rect2`, which is an immutable borrow to " +"`rect2`, an instance of `Rectangle`. This makes sense because we only need " +"to read `rect2` (rather than write, which would mean we’d need a mutable " +"borrow), and we want `main` to retain ownership of `rect2` so we can use it " +"again after calling the `can_hold` method. The return value of `can_hold` " +"will be a Boolean, and the implementation will check whether the width and " +"height of `self` are greater than the width and height of the other " +"`Rectangle`, respectively. Let’s add the new `can_hold` method to the `impl` " +"block from Listing 5-13, shown in Listing 5-15." +msgstr "" + +#: src/ch05-03-method-syntax.md:273 +msgid "" +"Listing 5-15: Implementing the `can_hold` method on " +"`Rectangle` that takes another `Rectangle` instance as a parameter" +msgstr "" + +#: src/ch05-03-method-syntax.md:276 +msgid "" +"When we run this code with the `main` function in Listing 5-14, we’ll get " +"our desired output. Methods can take multiple parameters that we add to the " +"signature after the `self` parameter, and those parameters work just like " +"parameters in functions." +msgstr "" + +#: src/ch05-03-method-syntax.md:281 +msgid "Associated Functions" +msgstr "" + +#: src/ch05-03-method-syntax.md:283 +msgid "" +"All functions defined within an `impl` block are called _associated " +"functions_ because they’re associated with the type named after the `impl`. " +"We can define associated functions that don’t have `self` as their first " +"parameter (and thus are not methods) because they don’t need an instance of " +"the type to work with. We’ve already used one function like this: the " +"`String::from` function that’s defined on the `String` type." +msgstr "" + +#: src/ch05-03-method-syntax.md:290 +msgid "" +"Associated functions that aren’t methods are often used for constructors " +"that will return a new instance of the struct. These are often called `new`, " +"but `new` isn’t a special name and isn’t built into the language. For " +"example, we could choose to provide an associated function named `square` " +"that would have one dimension parameter and use that as both width and " +"height, thus making it easier to create a square `Rectangle` rather than " +"having to specify the same value twice:" +msgstr "" + +#: src/ch05-03-method-syntax.md:321 +msgid "" +"The `Self` keywords in the return type and in the body of the function are " +"aliases for the type that appears after the `impl` keyword, which in this " +"case is `Rectangle`." +msgstr "" + +#: src/ch05-03-method-syntax.md:325 +msgid "" +"To call this associated function, we use the `::` syntax with the struct " +"name; `let sq = Rectangle::square(3);` is an example. This function is " +"namespaced by the struct: the `::` syntax is used for both associated " +"functions and namespaces created by modules. We’ll discuss modules in " +"[Chapter 7](ch07-02-defining-modules-to-control-scope-and-privacy.html)." +msgstr "" + +#: src/ch05-03-method-syntax.md:331 +msgid "Multiple `impl` Blocks" +msgstr "" + +#: src/ch05-03-method-syntax.md:333 +msgid "" +"Each struct is allowed to have multiple `impl` blocks. For example, Listing " +"5-15 is equivalent to the code shown in Listing 5-16, which has each method " +"in its own `impl` block." +msgstr "" + +#: src/ch05-03-method-syntax.md:375 +msgid "" +"Listing 5-16: Rewriting Listing 5-15 using multiple " +"`impl` blocks" +msgstr "" + +#: src/ch05-03-method-syntax.md:378 +msgid "" +"There’s no reason to separate these methods into multiple `impl` blocks " +"here, but this is valid syntax. We’ll see a case in which multiple `impl` " +"blocks are useful in Chapter 10, where we discuss generic types and traits." +msgstr "" + +#: src/ch05-03-method-syntax.md:384 +msgid "" +"Structs let you create custom types that are meaningful for your domain. By " +"using structs, you can keep associated pieces of data connected to each " +"other and name each piece to make your code clear. In `impl` blocks, you can " +"define functions that are associated with your type, and methods are a kind " +"of associated function that let you specify the behavior that instances of " +"your structs have." +msgstr "" + +#: src/ch05-03-method-syntax.md:391 +msgid "" +"But structs aren’t the only way you can create custom types: let’s turn to " +"Rust’s enum feature to add another tool to your toolbox." +msgstr "" + +#: src/ch06-00-enums.md:3 +msgid "" +"In this chapter, we’ll look at _enumerations_, also referred to as _enums_. " +"Enums allow you to define a type by enumerating its possible _variants_. " +"First we’ll define and use an enum to show how an enum can encode meaning " +"along with data. Next, we’ll explore a particularly useful enum, called " +"`Option`, which expresses that a value can be either something or nothing. " +"Then we’ll look at how pattern matching in the `match` expression makes it " +"easy to run different code for different values of an enum. Finally, we’ll " +"cover how the `if let` construct is another convenient and concise idiom " +"available to handle enums in your code." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:3 +msgid "" +"Where structs give you a way of grouping together related fields and data, " +"like a `Rectangle` with its `width` and `height`, enums give you a way of " +"saying a value is one of a possible set of values. For example, we may want " +"to say that `Rectangle` is one of a set of possible shapes that also " +"includes `Circle` and `Triangle`. To do this, Rust allows us to encode these " +"possibilities as an enum." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:9 +msgid "" +"Let’s look at a situation we might want to express in code and see why enums " +"are useful and more appropriate than structs in this case. Say we need to " +"work with IP addresses. Currently, two major standards are used for IP " +"addresses: version four and version six. Because these are the only " +"possibilities for an IP address that our program will come across, we can " +"_enumerate_ all possible variants, which is where enumeration gets its name." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:16 +msgid "" +"Any IP address can be either a version four or a version six address, but " +"not both at the same time. That property of IP addresses makes the enum data " +"structure appropriate because an enum value can only be one of its variants. " +"Both version four and version six addresses are still fundamentally IP " +"addresses, so they should be treated as the same type when the code is " +"handling situations that apply to any kind of IP address." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:23 +msgid "" +"We can express this concept in code by defining an `IpAddrKind` enumeration " +"and listing the possible kinds an IP address can be, `V4` and `V6`. These " +"are the variants of the enum:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:44 +msgid "" +"`IpAddrKind` is now a custom data type that we can use elsewhere in our code." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:46 +msgid "Enum Values" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:48 +msgid "" +"We can create instances of each of the two variants of `IpAddrKind` like " +"this:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:67 +msgid "" +"Note that the variants of the enum are namespaced under its identifier, and " +"we use a double colon to separate the two. This is useful because now both " +"values `IpAddrKind::V4` and `IpAddrKind::V6` are of the same type: " +"`IpAddrKind`. We can then, for instance, define a function that takes any " +"`IpAddrKind`:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:89 +msgid "And we can call this function with either variant:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:108 +msgid "" +"Using enums has even more advantages. Thinking more about our IP address " +"type, at the moment we don’t have a way to store the actual IP address " +"_data_; we only know what _kind_ it is. Given that you just learned about " +"structs in Chapter 5, you might be tempted to tackle this problem with " +"structs as shown in Listing 6-1." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:128 src/ch06-01-defining-an-enum.md:162 +#: src/ch09-03-to-panic-or-not-to-panic.md:53 +msgid "\"127.0.0.1\"" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:133 src/ch06-01-defining-an-enum.md:164 +#: src/ch06-01-defining-an-enum.md:192 +msgid "\"::1\"" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:138 +msgid "" +"Listing 6-1: Storing the data and `IpAddrKind` " +"variant of an IP address using a `struct`" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:141 +msgid "" +"Here, we’ve defined a struct `IpAddr` that has two fields: a `kind` field " +"that is of type `IpAddrKind` (the enum we defined previously) and an " +"`address` field of type `String`. We have two instances of this struct. The " +"first is `home`, and it has the value `IpAddrKind::V4` as its `kind` with " +"associated address data of `127.0.0.1`. The second instance is `loopback`. " +"It has the other variant of `IpAddrKind` as its `kind` value, `V6`, and has " +"address `::1` associated with it. We’ve used a struct to bundle the `kind` " +"and `address` values together, so now the variant is associated with the " +"value." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:150 +msgid "" +"However, representing the same concept using just an enum is more concise: " +"rather than an enum inside a struct, we can put data directly into each enum " +"variant. This new definition of the `IpAddr` enum says that both `V4` and " +"`V6` variants will have associated `String` values:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:168 +msgid "" +"We attach data to each variant of the enum directly, so there is no need for " +"an extra struct. Here, it’s also easier to see another detail of how enums " +"work: the name of each enum variant that we define also becomes a function " +"that constructs an instance of the enum. That is, `IpAddr::V4()` is a " +"function call that takes a `String` argument and returns an instance of the " +"`IpAddr` type. We automatically get this constructor function defined as a " +"result of defining the enum." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:176 +msgid "" +"There’s another advantage to using an enum rather than a struct: each " +"variant can have different types and amounts of associated data. Version " +"four IP addresses will always have four numeric components that will have " +"values between 0 and 255. If we wanted to store `V4` addresses as four `u8` " +"values but still express `V6` addresses as one `String` value, we wouldn’t " +"be able to with a struct. Enums handle this case with ease:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:196 +msgid "" +"We’ve shown several different ways to define data structures to store " +"version four and version six IP addresses. However, as it turns out, wanting " +"to store IP addresses and encode which kind they are is so common that [the " +"standard library has a definition we can use!](../std/net/enum.IpAddr." +"html) Let’s look at how the standard library defines " +"`IpAddr`: it has the exact enum and variants that we’ve defined and used, " +"but it embeds the address data inside the variants in the form of two " +"different structs, which are defined differently for each variant:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:220 +msgid "" +"This code illustrates that you can put any kind of data inside an enum " +"variant: strings, numeric types, or structs, for example. You can even " +"include another enum! Also, standard library types are often not much more " +"complicated than what you might come up with." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:225 +msgid "" +"Note that even though the standard library contains a definition for " +"`IpAddr`, we can still create and use our own definition without conflict " +"because we haven’t brought the standard library’s definition into our scope. " +"We’ll talk more about bringing types into scope in Chapter 7." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:230 +msgid "" +"Let’s look at another example of an enum in Listing 6-2: this one has a wide " +"variety of types embedded in its variants." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:244 +msgid "" +"Listing 6-2: A `Message` enum whose variants each " +"store different amounts and types of values" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:247 +msgid "This enum has four variants with different types:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:249 +msgid "`Quit` has no data associated with it at all." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:250 +msgid "`Move` has named fields, like a struct does." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:251 +msgid "`Write` includes a single `String`." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:252 +msgid "`ChangeColor` includes three `i32` values." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:254 +msgid "" +"Defining an enum with variants such as the ones in Listing 6-2 is similar to " +"defining different kinds of struct definitions, except the enum doesn’t use " +"the `struct` keyword and all the variants are grouped together under the " +"`Message` type. The following structs could hold the same data that the " +"preceding enum variants hold:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:261 +msgid "// unit struct\n" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:266 src/ch06-01-defining-an-enum.md:267 +msgid "// tuple struct\n" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:272 +msgid "" +"But if we used the different structs, each of which has its own type, we " +"couldn’t as easily define a function to take any of these kinds of messages " +"as we could with the `Message` enum defined in Listing 6-2, which is a " +"single type." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:276 +msgid "" +"There is one more similarity between enums and structs: just as we’re able " +"to define methods on structs using `impl`, we’re also able to define methods " +"on enums. Here’s a method named `call` that we could define on our `Message` " +"enum:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:291 +msgid "// method body would be defined here\n" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:300 +msgid "" +"The body of the method would use `self` to get the value that we called the " +"method on. In this example, we’ve created a variable `m` that has the value " +"`Message::Write(String::from(\"hello\"))`, and that is what `self` will be " +"in the body of the `call` method when `m.call()` runs." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:305 +msgid "" +"Let’s look at another enum in the standard library that is very common and " +"useful: `Option`." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:308 +msgid "The `Option` Enum and Its Advantages Over Null Values" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:310 +msgid "" +"This section explores a case study of `Option`, which is another enum " +"defined by the standard library. The `Option` type encodes the very common " +"scenario in which a value could be something or it could be nothing." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:314 +msgid "" +"For example, if you request the first item in a non-empty list, you would " +"get a value. If you request the first item in an empty list, you would get " +"nothing. Expressing this concept in terms of the type system means the " +"compiler can check whether you’ve handled all the cases you should be " +"handling; this functionality can prevent bugs that are extremely common in " +"other programming languages." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:321 +msgid "" +"Programming language design is often thought of in terms of which features " +"you include, but the features you exclude are important too. Rust doesn’t " +"have the null feature that many other languages have. _Null_ is a value that " +"means there is no value there. In languages with null, variables can always " +"be in one of two states: null or not-null." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:327 +msgid "" +"In his 2009 presentation “Null References: The Billion Dollar Mistake,” Tony " +"Hoare, the inventor of null, has this to say:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:330 +msgid "" +"I call it my billion-dollar mistake. At that time, I was designing the first " +"comprehensive type system for references in an object-oriented language. My " +"goal was to ensure that all use of references should be absolutely safe, " +"with checking performed automatically by the compiler. But I couldn’t resist " +"the temptation to put in a null reference, simply because it was so easy to " +"implement. This has led to innumerable errors, vulnerabilities, and system " +"crashes, which have probably caused a billion dollars of pain and damage in " +"the last forty years." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:339 +msgid "" +"The problem with null values is that if you try to use a null value as a not-" +"null value, you’ll get an error of some kind. Because this null or not-null " +"property is pervasive, it’s extremely easy to make this kind of error." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:343 +msgid "" +"However, the concept that null is trying to express is still a useful one: a " +"null is a value that is currently invalid or absent for some reason." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:346 +msgid "" +"The problem isn’t really with the concept but with the particular " +"implementation. As such, Rust does not have nulls, but it does have an enum " +"that can encode the concept of a value being present or absent. This enum is " +"`Option`, and it is [defined by the standard library](../std/option/enum." +"Option.html) as follows:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:359 +msgid "" +"The `Option` enum is so useful that it’s even included in the prelude; " +"you don’t need to bring it into scope explicitly. Its variants are also " +"included in the prelude: you can use `Some` and `None` directly without the " +"`Option::` prefix. The `Option` enum is still just a regular enum, and " +"`Some(T)` and `None` are still variants of type `Option`." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:365 +msgid "" +"The `` syntax is a feature of Rust we haven’t talked about yet. It’s a " +"generic type parameter, and we’ll cover generics in more detail in Chapter " +"10. For now, all you need to know is that `` means that the `Some` " +"variant of the `Option` enum can hold one piece of data of any type, and " +"that each concrete type that gets used in place of `T` makes the overall " +"`Option` type a different type. Here are some examples of using `Option` " +"values to hold number types and string types:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:376 +msgid "'e'" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:382 +msgid "" +"The type of `some_number` is `Option`. The type of `some_char` is " +"`Option`, which is a different type. Rust can infer these types " +"because we’ve specified a value inside the `Some` variant. For " +"`absent_number`, Rust requires us to annotate the overall `Option` type: the " +"compiler can’t infer the type that the corresponding `Some` variant will " +"hold by looking only at a `None` value. Here, we tell Rust that we mean for " +"`absent_number` to be of type `Option`." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:390 +msgid "" +"When we have a `Some` value, we know that a value is present and the value " +"is held within the `Some`. When we have a `None` value, in some sense it " +"means the same thing as null: we don’t have a valid value. So why is having " +"`Option` any better than having null?" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:395 +msgid "" +"In short, because `Option` and `T` (where `T` can be any type) are " +"different types, the compiler won’t let us use an `Option` value as if it " +"were definitely a valid value. For example, this code won’t compile, because " +"it’s trying to add an `i8` to an `Option`:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:409 +msgid "If we run this code, we get an error message like this one:" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:411 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling enums v0.1.0 (file:///projects/enums)\n" +"error[E0277]: cannot add `Option` to `i8`\n" +" --> src/main.rs:5:17\n" +" |\n" +"5 | let sum = x + y;\n" +" | ^ no implementation for `i8 + Option`\n" +" |\n" +" = help: the trait `Add>` is not implemented for `i8`\n" +" = help: the following other types implement trait `Add`:\n" +" <&'a i8 as Add>\n" +" <&i8 as Add<&i8>>\n" +" >\n" +" \n" +"\n" +"For more information about this error, try `rustc --explain E0277`.\n" +"error: could not compile `enums` (bin \"enums\") due to 1 previous error\n" +"```" +msgstr "" + +#: src/ch06-01-defining-an-enum.md:431 +msgid "" +"Intense! In effect, this error message means that Rust doesn’t understand " +"how to add an `i8` and an `Option`, because they’re different types. " +"When we have a value of a type like `i8` in Rust, the compiler will ensure " +"that we always have a valid value. We can proceed confidently without having " +"to check for null before using that value. Only when we have an `Option` " +"(or whatever type of value we’re working with) do we have to worry about " +"possibly not having a value, and the compiler will make sure we handle that " +"case before using the value." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:440 +msgid "" +"In other words, you have to convert an `Option` to a `T` before you can " +"perform `T` operations with it. Generally, this helps catch one of the most " +"common issues with null: assuming that something isn’t null when it actually " +"is." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:444 +msgid "" +"Eliminating the risk of incorrectly assuming a not-null value helps you to " +"be more confident in your code. In order to have a value that can possibly " +"be null, you must explicitly opt in by making the type of that value " +"`Option`. Then, when you use that value, you are required to explicitly " +"handle the case when the value is null. Everywhere that a value has a type " +"that isn’t an `Option`, you _can_ safely assume that the value isn’t " +"null. This was a deliberate design decision for Rust to limit null’s " +"pervasiveness and increase the safety of Rust code." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:453 +msgid "" +"So how do you get the `T` value out of a `Some` variant when you have a " +"value of type `Option` so that you can use that value? The `Option` " +"enum has a large number of methods that are useful in a variety of " +"situations; you can check them out in [its documentation](../std/option/enum." +"Option.html). Becoming familiar with the methods on " +"`Option` will be extremely useful in your journey with Rust." +msgstr "" + +#: src/ch06-01-defining-an-enum.md:460 +msgid "" +"In general, in order to use an `Option` value, you want to have code that " +"will handle each variant. You want some code that will run only when you " +"have a `Some(T)` value, and this code is allowed to use the inner `T`. You " +"want some other code to run only if you have a `None` value, and that code " +"doesn’t have a `T` value available. The `match` expression is a control flow " +"construct that does just this when used with enums: it will run different " +"code depending on which variant of the enum it has, and that code can use " +"the data inside the matching value." +msgstr "" + +#: src/ch06-02-match.md:2 +msgid "" +msgstr "" + +#: src/ch06-02-match.md:5 +msgid "" +"Rust has an extremely powerful control flow construct called `match` that " +"allows you to compare a value against a series of patterns and then execute " +"code based on which pattern matches. Patterns can be made up of literal " +"values, variable names, wildcards, and many other things; [Chapter 18]" +"(ch18-00-patterns.html) covers all the different kinds of " +"patterns and what they do. The power of `match` comes from the " +"expressiveness of the patterns and the fact that the compiler confirms that " +"all possible cases are handled." +msgstr "" + +#: src/ch06-02-match.md:14 +msgid "" +"Think of a `match` expression as being like a coin-sorting machine: coins " +"slide down a track with variously sized holes along it, and each coin falls " +"through the first hole it encounters that it fits into. In the same way, " +"values go through each pattern in a `match`, and at the first pattern the " +"value “fits,” the value falls into the associated code block to be used " +"during execution." +msgstr "" + +#: src/ch06-02-match.md:20 +msgid "" +"Speaking of coins, let’s use them as an example using `match`! We can write " +"a function that takes an unknown US coin and, in a similar way as the " +"counting machine, determines which coin it is and returns its value in " +"cents, as shown in Listing 6-3." +msgstr "" + +#: src/ch06-02-match.md:45 +msgid "" +"Listing 6-3: An enum and a `match` expression that " +"has the variants of the enum as its patterns" +msgstr "" + +#: src/ch06-02-match.md:48 +msgid "" +"Let’s break down the `match` in the `value_in_cents` function. First we list " +"the `match` keyword followed by an expression, which in this case is the " +"value `coin`. This seems very similar to a conditional expression used with " +"`if`, but there’s a big difference: with `if`, the condition needs to " +"evaluate to a Boolean value, but here it can be any type. The type of `coin` " +"in this example is the `Coin` enum that we defined on the first line." +msgstr "" + +#: src/ch06-02-match.md:55 +msgid "" +"Next are the `match` arms. An arm has two parts: a pattern and some code. " +"The first arm here has a pattern that is the value `Coin::Penny` and then " +"the `=>` operator that separates the pattern and the code to run. The code " +"in this case is just the value `1`. Each arm is separated from the next with " +"a comma." +msgstr "" + +#: src/ch06-02-match.md:60 +msgid "" +"When the `match` expression executes, it compares the resultant value " +"against the pattern of each arm, in order. If a pattern matches the value, " +"the code associated with that pattern is executed. If that pattern doesn’t " +"match the value, execution continues to the next arm, much as in a coin-" +"sorting machine. We can have as many arms as we need: in Listing 6-3, our " +"`match` has four arms." +msgstr "" + +#: src/ch06-02-match.md:66 +msgid "" +"The code associated with each arm is an expression, and the resultant value " +"of the expression in the matching arm is the value that gets returned for " +"the entire `match` expression." +msgstr "" + +#: src/ch06-02-match.md:70 +msgid "" +"We don’t typically use curly brackets if the match arm code is short, as it " +"is in Listing 6-3 where each arm just returns a value. If you want to run " +"multiple lines of code in a match arm, you must use curly brackets, and the " +"comma following the arm is then optional. For example, the following code " +"prints “Lucky penny!” every time the method is called with a `Coin::Penny`, " +"but still returns the last value of the block, `1`:" +msgstr "" + +#: src/ch06-02-match.md:88 +msgid "\"Lucky penny!\"" +msgstr "" + +#: src/ch06-02-match.md:100 +msgid "Patterns That Bind to Values" +msgstr "" + +#: src/ch06-02-match.md:102 +msgid "" +"Another useful feature of match arms is that they can bind to the parts of " +"the values that match the pattern. This is how we can extract values out of " +"enum variants." +msgstr "" + +#: src/ch06-02-match.md:106 +msgid "" +"As an example, let’s change one of our enum variants to hold data inside it. " +"From 1999 through 2008, the United States minted quarters with different " +"designs for each of the 50 states on one side. No other coins got state " +"designs, so only quarters have this extra value. We can add this information " +"to our `enum` by changing the `Quarter` variant to include a `UsState` value " +"stored inside it, which we’ve done in Listing 6-4." +msgstr "" + +#: src/ch06-02-match.md:114 +msgid "// so we can inspect the state in a minute\n" +msgstr "" + +#: src/ch06-02-match.md:131 +msgid "" +"Listing 6-4: A `Coin` enum in which the `Quarter` " +"variant also holds a `UsState` value" +msgstr "" + +#: src/ch06-02-match.md:134 +msgid "" +"Let’s imagine that a friend is trying to collect all 50 state quarters. " +"While we sort our loose change by coin type, we’ll also call out the name of " +"the state associated with each quarter so that if it’s one our friend " +"doesn’t have, they can add it to their collection." +msgstr "" + +#: src/ch06-02-match.md:139 +msgid "" +"In the match expression for this code, we add a variable called `state` to " +"the pattern that matches values of the variant `Coin::Quarter`. When a " +"`Coin::Quarter` matches, the `state` variable will bind to the value of that " +"quarter’s state. Then we can use `state` in the code for that arm, like so:" +msgstr "" + +#: src/ch06-02-match.md:165 src/ch06-03-if-let.md:84 src/ch06-03-if-let.md:111 +msgid "\"State quarter from {state:?}!\"" +msgstr "" + +#: src/ch06-02-match.md:176 +msgid "" +"If we were to call `value_in_cents(Coin::Quarter(UsState::Alaska))`, `coin` " +"would be `Coin::Quarter(UsState::Alaska)`. When we compare that value with " +"each of the match arms, none of them match until we reach `Coin::" +"Quarter(state)`. At that point, the binding for `state` will be the value " +"`UsState::Alaska`. We can then use that binding in the `println!` " +"expression, thus getting the inner state value out of the `Coin` enum " +"variant for `Quarter`." +msgstr "" + +#: src/ch06-02-match.md:183 +msgid "Matching with `Option`" +msgstr "" + +#: src/ch06-02-match.md:185 +msgid "" +"In the previous section, we wanted to get the inner `T` value out of the " +"`Some` case when using `Option`; we can also handle `Option` using " +"`match`, as we did with the `Coin` enum! Instead of comparing coins, we’ll " +"compare the variants of `Option`, but the way the `match` expression " +"works remains the same." +msgstr "" + +#: src/ch06-02-match.md:191 +msgid "" +"Let’s say we want to write a function that takes an `Option` and, if " +"there’s a value inside, adds 1 to that value. If there isn’t a value inside, " +"the function should return the `None` value and not attempt to perform any " +"operations." +msgstr "" + +#: src/ch06-02-match.md:196 +msgid "" +"This function is very easy to write, thanks to `match`, and will look like " +"Listing 6-5." +msgstr "" + +#: src/ch06-02-match.md:214 +msgid "" +"Listing 6-5: A function that uses a `match` " +"expression on an `Option`" +msgstr "" + +#: src/ch06-02-match.md:217 +msgid "" +"Let’s examine the first execution of `plus_one` in more detail. When we call " +"`plus_one(five)`, the variable `x` in the body of `plus_one` will have the " +"value `Some(5)`. We then compare that against each match arm:" +msgstr "" + +#: src/ch06-02-match.md:236 +msgid "" +"The `Some(5)` value doesn’t match the pattern `None`, so we continue to the " +"next arm:" +msgstr "" + +#: src/ch06-02-match.md:254 +msgid "" +"Does `Some(5)` match `Some(i)`? It does! We have the same variant. The `i` " +"binds to the value contained in `Some`, so `i` takes the value `5`. The code " +"in the match arm is then executed, so we add 1 to the value of `i` and " +"create a new `Some` value with our total `6` inside." +msgstr "" + +#: src/ch06-02-match.md:259 +msgid "" +"Now let’s consider the second call of `plus_one` in Listing 6-5, where `x` " +"is `None`. We enter the `match` and compare to the first arm:" +msgstr "" + +#: src/ch06-02-match.md:277 +msgid "" +"It matches! There’s no value to add to, so the program stops and returns the " +"`None` value on the right side of `=>`. Because the first arm matched, no " +"other arms are compared." +msgstr "" + +#: src/ch06-02-match.md:281 +msgid "" +"Combining `match` and enums is useful in many situations. You’ll see this " +"pattern a lot in Rust code: `match` against an enum, bind a variable to the " +"data inside, and then execute code based on it. It’s a bit tricky at first, " +"but once you get used to it, you’ll wish you had it in all languages. It’s " +"consistently a user favorite." +msgstr "" + +#: src/ch06-02-match.md:287 +msgid "Matches Are Exhaustive" +msgstr "" + +#: src/ch06-02-match.md:289 +msgid "" +"There’s one other aspect of `match` we need to discuss: the arms’ patterns " +"must cover all possibilities. Consider this version of our `plus_one` " +"function, which has a bug and won’t compile:" +msgstr "" + +#: src/ch06-02-match.md:307 +msgid "" +"We didn’t handle the `None` case, so this code will cause a bug. Luckily, " +"it’s a bug Rust knows how to catch. If we try to compile this code, we’ll " +"get this error:" +msgstr "" + +#: src/ch06-02-match.md:311 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling enums v0.1.0 (file:///projects/enums)\n" +"error[E0004]: non-exhaustive patterns: `None` not covered\n" +" --> src/main.rs:3:15\n" +" |\n" +"3 | match x {\n" +" | ^ pattern `None` not covered\n" +" |\n" +"note: `Option` defined here\n" +" --> /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/option." +"rs:571:1\n" +" ::: /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/option." +"rs:575:5\n" +" |\n" +" = note: not covered\n" +" = note: the matched value is of type `Option`\n" +"help: ensure that all possible cases are being handled by adding a match arm " +"with a wildcard pattern or an explicit pattern as shown\n" +" |\n" +"4 ~ Some(i) => Some(i + 1),\n" +"5 ~ None => todo!(),\n" +" |\n" +"\n" +"For more information about this error, try `rustc --explain E0004`.\n" +"error: could not compile `enums` (bin \"enums\") due to 1 previous error\n" +"```" +msgstr "" + +#: src/ch06-02-match.md:336 +msgid "" +"Rust knows that we didn’t cover every possible case, and even knows which " +"pattern we forgot! Matches in Rust are _exhaustive_: we must exhaust every " +"last possibility in order for the code to be valid. Especially in the case " +"of `Option`, when Rust prevents us from forgetting to explicitly handle " +"the `None` case, it protects us from assuming that we have a value when we " +"might have null, thus making the billion-dollar mistake discussed earlier " +"impossible." +msgstr "" + +#: src/ch06-02-match.md:343 +msgid "Catch-all Patterns and the `_` Placeholder" +msgstr "" + +#: src/ch06-02-match.md:345 +msgid "" +"Using enums, we can also take special actions for a few particular values, " +"but for all other values take one default action. Imagine we’re implementing " +"a game where, if you roll a 3 on a dice roll, your player doesn’t move, but " +"instead gets a new fancy hat. If you roll a 7, your player loses a fancy " +"hat. For all other values, your player moves that number of spaces on the " +"game board. Here’s a `match` that implements that logic, with the result of " +"the dice roll hardcoded rather than a random value, and all other logic " +"represented by functions without bodies because actually implementing them " +"is out of scope for this example:" +msgstr "" + +#: src/ch06-02-match.md:370 +msgid "" +"For the first two arms, the patterns are the literal values `3` and `7`. For " +"the last arm that covers every other possible value, the pattern is the " +"variable we’ve chosen to name `other`. The code that runs for the `other` " +"arm uses the variable by passing it to the `move_player` function." +msgstr "" + +#: src/ch06-02-match.md:375 +msgid "" +"This code compiles, even though we haven’t listed all the possible values a " +"`u8` can have, because the last pattern will match all values not " +"specifically listed. This catch-all pattern meets the requirement that " +"`match` must be exhaustive. Note that we have to put the catch-all arm last " +"because the patterns are evaluated in order. If we put the catch-all arm " +"earlier, the other arms would never run, so Rust will warn us if we add arms " +"after a catch-all!" +msgstr "" + +#: src/ch06-02-match.md:382 +msgid "" +"Rust also has a pattern we can use when we want a catch-all but don’t want " +"to _use_ the value in the catch-all pattern: `_` is a special pattern that " +"matches any value and does not bind to that value. This tells Rust we aren’t " +"going to use the value, so Rust won’t warn us about an unused variable." +msgstr "" + +#: src/ch06-02-match.md:387 +msgid "" +"Let’s change the rules of the game: now, if you roll anything other than a 3 " +"or a 7, you must roll again. We no longer need to use the catch-all value, " +"so we can change our code to use `_` instead of the variable named `other`:" +msgstr "" + +#: src/ch06-02-match.md:406 +msgid "" +"This example also meets the exhaustiveness requirement because we’re " +"explicitly ignoring all other values in the last arm; we haven’t forgotten " +"anything." +msgstr "" + +#: src/ch06-02-match.md:409 +msgid "" +"Finally, we’ll change the rules of the game one more time so that nothing " +"else happens on your turn if you roll anything other than a 3 or a 7. We can " +"express that by using the unit value (the empty tuple type we mentioned in " +"[“The Tuple Type”](ch03-02-data-types.html#the-tuple-type) " +"section) as the code that goes with the `_` arm:" +msgstr "" + +#: src/ch06-02-match.md:428 +msgid "" +"Here, we’re telling Rust explicitly that we aren’t going to use any other " +"value that doesn’t match a pattern in an earlier arm, and we don’t want to " +"run any code in this case." +msgstr "" + +#: src/ch06-02-match.md:432 +msgid "" +"There’s more about patterns and matching that we’ll cover in [Chapter 18]" +"(ch18-00-patterns.html). For now, we’re going to move on to " +"the `if let` syntax, which can be useful in situations where the `match` " +"expression is a bit wordy." +msgstr "" + +#: src/ch06-03-if-let.md:3 +msgid "" +"The `if let` syntax lets you combine `if` and `let` into a less verbose way " +"to handle values that match one pattern while ignoring the rest. Consider " +"the program in Listing 6-6 that matches on an `Option` value in the " +"`config_max` variable but only wants to execute code if the value is the " +"`Some` variant." +msgstr "" + +#: src/ch06-03-if-let.md:13 src/ch06-03-if-let.md:35 +msgid "\"The maximum is configured to be {max}\"" +msgstr "" + +#: src/ch06-03-if-let.md:19 +msgid "" +"Listing 6-6: A `match` that only cares about " +"executing code when the value is `Some`" +msgstr "" + +#: src/ch06-03-if-let.md:22 +msgid "" +"If the value is `Some`, we print out the value in the `Some` variant by " +"binding the value to the variable `max` in the pattern. We don’t want to do " +"anything with the `None` value. To satisfy the `match` expression, we have " +"to add `_ => ()` after processing just one variant, which is annoying " +"boilerplate code to add." +msgstr "" + +#: src/ch06-03-if-let.md:28 +msgid "" +"Instead, we could write this in a shorter way using `if let`. The following " +"code behaves the same as the `match` in Listing 6-6:" +msgstr "" + +#: src/ch06-03-if-let.md:40 +msgid "" +"The syntax `if let` takes a pattern and an expression separated by an equal " +"sign. It works the same way as a `match`, where the expression is given to " +"the `match` and the pattern is its first arm. In this case, the pattern is " +"`Some(max)`, and the `max` binds to the value inside the `Some`. We can then " +"use `max` in the body of the `if let` block in the same way we used `max` in " +"the corresponding `match` arm. The code in the `if let` block isn’t run if " +"the value doesn’t match the pattern." +msgstr "" + +#: src/ch06-03-if-let.md:48 +msgid "" +"Using `if let` means less typing, less indentation, and less boilerplate " +"code. However, you lose the exhaustive checking that `match` enforces. " +"Choosing between `match` and `if let` depends on what you’re doing in your " +"particular situation and whether gaining conciseness is an appropriate trade-" +"off for losing exhaustive checking." +msgstr "" + +#: src/ch06-03-if-let.md:54 +msgid "" +"In other words, you can think of `if let` as syntax sugar for a `match` that " +"runs code when the value matches one pattern and then ignores all other " +"values." +msgstr "" + +#: src/ch06-03-if-let.md:57 +msgid "" +"We can include an `else` with an `if let`. The block of code that goes with " +"the `else` is the same as the block of code that would go with the `_` case " +"in the `match` expression that is equivalent to the `if let` and `else`. " +"Recall the `Coin` enum definition in Listing 6-4, where the `Quarter` " +"variant also held a `UsState` value. If we wanted to count all non-quarter " +"coins we see while also announcing the state of the quarters, we could do " +"that with a `match` expression, like this:" +msgstr "" + +#: src/ch06-03-if-let.md:90 +msgid "Or we could use an `if let` and `else` expression, like this:" +msgstr "" + +#: src/ch06-03-if-let.md:118 +msgid "" +"If you have a situation in which your program has logic that is too verbose " +"to express using a `match`, remember that `if let` is in your Rust toolbox " +"as well." +msgstr "" + +#: src/ch06-03-if-let.md:123 +msgid "" +"We’ve now covered how to use enums to create custom types that can be one of " +"a set of enumerated values. We’ve shown how the standard library’s " +"`Option` type helps you use the type system to prevent errors. When enum " +"values have data inside them, you can use `match` or `if let` to extract and " +"use those values, depending on how many cases you need to handle." +msgstr "" + +#: src/ch06-03-if-let.md:129 +msgid "" +"Your Rust programs can now express concepts in your domain using structs and " +"enums. Creating custom types to use in your API ensures type safety: the " +"compiler will make certain your functions only get values of the type each " +"function expects." +msgstr "" + +#: src/ch06-03-if-let.md:134 +msgid "" +"In order to provide a well-organized API to your users that is " +"straightforward to use and only exposes exactly what your users will need, " +"let’s now turn to Rust’s modules." +msgstr "" + +#: src/ch07-00-managing-growing-projects-with-packages-crates-and-modules.md:3 +msgid "" +"As you write large programs, organizing your code will become increasingly " +"important. By grouping related functionality and separating code with " +"distinct features, you’ll clarify where to find code that implements a " +"particular feature and where to go to change how a feature works." +msgstr "" + +#: src/ch07-00-managing-growing-projects-with-packages-crates-and-modules.md:8 +msgid "" +"The programs we’ve written so far have been in one module in one file. As a " +"project grows, you should organize code by splitting it into multiple " +"modules and then multiple files. A package can contain multiple binary " +"crates and optionally one library crate. As a package grows, you can extract " +"parts into separate crates that become external dependencies. This chapter " +"covers all these techniques. For very large projects comprising a set of " +"interrelated packages that evolve together, Cargo provides _workspaces_, " +"which we’ll cover in the [“Cargo Workspaces”](ch14-03-cargo-workspaces." +"html) section in Chapter 14." +msgstr "" + +#: src/ch07-00-managing-growing-projects-with-packages-crates-and-modules.md:17 +msgid "" +"We’ll also discuss encapsulating implementation details, which lets you " +"reuse code at a higher level: once you’ve implemented an operation, other " +"code can call your code via its public interface without having to know how " +"the implementation works. The way you write code defines which parts are " +"public for other code to use and which parts are private implementation " +"details that you reserve the right to change. This is another way to limit " +"the amount of detail you have to keep in your head." +msgstr "" + +#: src/ch07-00-managing-growing-projects-with-packages-crates-and-modules.md:25 +msgid "" +"A related concept is scope: the nested context in which code is written has " +"a set of names that are defined as “in scope.” When reading, writing, and " +"compiling code, programmers and compilers need to know whether a particular " +"name at a particular spot refers to a variable, function, struct, enum, " +"module, constant, or other item and what that item means. You can create " +"scopes and change which names are in or out of scope. You can’t have two " +"items with the same name in the same scope; tools are available to resolve " +"name conflicts." +msgstr "" + +#: src/ch07-00-managing-growing-projects-with-packages-crates-and-modules.md:33 +msgid "" +"Rust has a number of features that allow you to manage your code’s " +"organization, including which details are exposed, which details are " +"private, and what names are in each scope in your programs. These features, " +"sometimes collectively referred to as the _module system_, include:" +msgstr "" + +#: src/ch07-00-managing-growing-projects-with-packages-crates-and-modules.md:38 +msgid "" +"**Packages:** A Cargo feature that lets you build, test, and share crates" +msgstr "" + +#: src/ch07-00-managing-growing-projects-with-packages-crates-and-modules.md:39 +msgid "**Crates:** A tree of modules that produces a library or executable" +msgstr "" + +#: src/ch07-00-managing-growing-projects-with-packages-crates-and-modules.md:40 +msgid "" +"**Modules** and **use:** Let you control the organization, scope, and " +"privacy of paths" +msgstr "" + +#: src/ch07-00-managing-growing-projects-with-packages-crates-and-modules.md:42 +msgid "" +"**Paths:** A way of naming an item, such as a struct, function, or module" +msgstr "" + +#: src/ch07-00-managing-growing-projects-with-packages-crates-and-modules.md:44 +msgid "" +"In this chapter, we’ll cover all these features, discuss how they interact, " +"and explain how to use them to manage scope. By the end, you should have a " +"solid understanding of the module system and be able to work with scopes " +"like a pro!" +msgstr "" + +#: src/ch07-01-packages-and-crates.md:3 +msgid "" +"The first parts of the module system we’ll cover are packages and crates." +msgstr "" + +#: src/ch07-01-packages-and-crates.md:5 +msgid "" +"A _crate_ is the smallest amount of code that the Rust compiler considers at " +"a time. Even if you run `rustc` rather than `cargo` and pass a single source " +"code file (as we did all the way back in the “Writing and Running a Rust " +"Program” section of Chapter 1), the compiler considers that file to be a " +"crate. Crates can contain modules, and the modules may be defined in other " +"files that get compiled with the crate, as we’ll see in the coming sections." +msgstr "" + +#: src/ch07-01-packages-and-crates.md:12 +msgid "" +"A crate can come in one of two forms: a binary crate or a library crate. " +"_Binary crates_ are programs you can compile to an executable that you can " +"run, such as a command-line program or a server. Each must have a function " +"called `main` that defines what happens when the executable runs. All the " +"crates we’ve created so far have been binary crates." +msgstr "" + +#: src/ch07-01-packages-and-crates.md:18 +msgid "" +"_Library crates_ don’t have a `main` function, and they don’t compile to an " +"executable. Instead, they define functionality intended to be shared with " +"multiple projects. For example, the `rand` crate we used in [Chapter 2]" +"(ch02-00-guessing-game-tutorial.html#generating-a-random-number) provides functionality that generates random numbers. Most of the time " +"when Rustaceans say “crate”, they mean library crate, and they use “crate” " +"interchangeably with the general programming concept of a “library\"." +msgstr "" + +#: src/ch07-01-packages-and-crates.md:25 +msgid "" +"The _crate root_ is a source file that the Rust compiler starts from and " +"makes up the root module of your crate (we’ll explain modules in depth in " +"the [“Defining Modules to Control Scope and Privacy”](ch07-02-defining-" +"modules-to-control-scope-and-privacy.html) section)." +msgstr "" + +#: src/ch07-01-packages-and-crates.md:30 +msgid "" +"A _package_ is a bundle of one or more crates that provides a set of " +"functionality. A package contains a _Cargo.toml_ file that describes how to " +"build those crates. Cargo is actually a package that contains the binary " +"crate for the command-line tool you’ve been using to build your code. The " +"Cargo package also contains a library crate that the binary crate depends " +"on. Other projects can depend on the Cargo library crate to use the same " +"logic the Cargo command-line tool uses." +msgstr "" + +#: src/ch07-01-packages-and-crates.md:38 +msgid "" +"A crate can come in one of two forms: a binary crate or a library crate. A " +"package can contain as many binary crates as you like, but at most only one " +"library crate. A package must contain at least one crate, whether that’s a " +"library or binary crate." +msgstr "" + +#: src/ch07-01-packages-and-crates.md:43 +msgid "" +"Let’s walk through what happens when we create a package. First we enter the " +"command `cargo new my-project`:" +msgstr "" + +#: src/ch07-01-packages-and-crates.md:56 +msgid "" +"After we run `cargo new my-project`, we use `ls` to see what Cargo creates. " +"In the project directory, there’s a _Cargo.toml_ file, giving us a package. " +"There’s also a _src_ directory that contains _main.rs_. Open _Cargo.toml_ in " +"your text editor, and note there’s no mention of _src/main.rs_. Cargo " +"follows a convention that _src/main.rs_ is the crate root of a binary crate " +"with the same name as the package. Likewise, Cargo knows that if the package " +"directory contains _src/lib.rs_, the package contains a library crate with " +"the same name as the package, and _src/lib.rs_ is its crate root. Cargo " +"passes the crate root files to `rustc` to build the library or binary." +msgstr "" + +#: src/ch07-01-packages-and-crates.md:66 +msgid "" +"Here, we have a package that only contains _src/main.rs_, meaning it only " +"contains a binary crate named `my-project`. If a package contains _src/main." +"rs_ and _src/lib.rs_, it has two crates: a binary and a library, both with " +"the same name as the package. A package can have multiple binary crates by " +"placing files in the _src/bin_ directory: each file will be a separate " +"binary crate." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:3 +msgid "" +"In this section, we’ll talk about modules and other parts of the module " +"system, namely _paths_, which allow you to name items; the `use` keyword " +"that brings a path into scope; and the `pub` keyword to make items public. " +"We’ll also discuss the `as` keyword, external packages, and the glob " +"operator." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:8 +msgid "Modules Cheat Sheet" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:10 +msgid "" +"Before we get to the details of modules and paths, here we provide a quick " +"reference on how modules, paths, the `use` keyword, and the `pub` keyword " +"work in the compiler, and how most developers organize their code. We’ll be " +"going through examples of each of these rules throughout this chapter, but " +"this is a great place to refer to as a reminder of how modules work." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:16 +msgid "" +"**Start from the crate root**: When compiling a crate, the compiler first " +"looks in the crate root file (usually _src/lib.rs_ for a library crate or " +"_src/main.rs_ for a binary crate) for code to compile." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:19 +msgid "" +"**Declaring modules**: In the crate root file, you can declare new modules; " +"say you declare a “garden” module with `mod garden;`. The compiler will look " +"for the module’s code in these places:" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:22 +msgid "" +"Inline, within curly brackets that replace the semicolon following `mod " +"garden`" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:24 +msgid "In the file _src/garden.rs_" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:25 +msgid "In the file _src/garden/mod.rs_" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:26 +msgid "" +"**Declaring submodules**: In any file other than the crate root, you can " +"declare submodules. For example, you might declare `mod vegetables;` in _src/" +"garden.rs_. The compiler will look for the submodule’s code within the " +"directory named for the parent module in these places:" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:30 +msgid "" +"Inline, directly following `mod vegetables`, within curly brackets instead " +"of the semicolon" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:32 +msgid "In the file _src/garden/vegetables.rs_" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:33 +msgid "In the file _src/garden/vegetables/mod.rs_" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:34 +msgid "" +"**Paths to code in modules**: Once a module is part of your crate, you can " +"refer to code in that module from anywhere else in that same crate, as long " +"as the privacy rules allow, using the path to the code. For example, an " +"`Asparagus` type in the garden vegetables module would be found at `crate::" +"garden::vegetables::Asparagus`." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:39 +msgid "" +"**Private vs. public**: Code within a module is private from its parent " +"modules by default. To make a module public, declare it with `pub mod` " +"instead of `mod`. To make items within a public module public as well, use " +"`pub` before their declarations." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:43 +msgid "" +"**The `use` keyword**: Within a scope, the `use` keyword creates shortcuts " +"to items to reduce repetition of long paths. In any scope that can refer to " +"`crate::garden::vegetables::Asparagus`, you can create a shortcut with `use " +"crate::garden::vegetables::Asparagus;` and from then on you only need to " +"write `Asparagus` to make use of that type in the scope." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:49 +msgid "" +"Here, we create a binary crate named `backyard` that illustrates these " +"rules. The crate’s directory, also named `backyard`, contains these files " +"and directories:" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:64 +msgid "The crate root file in this case is _src/main.rs_, and it contains:" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:75 +msgid "\"I'm growing {plant:?}!\"" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:79 +msgid "" +"The `pub mod garden;` line tells the compiler to include the code it finds " +"in _src/garden.rs_, which is:" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:82 +msgid "Filename: src/garden.rs" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:88 +msgid "" +"Here, `pub mod vegetables;` means the code in _src/garden/vegetables.rs_ is " +"included too. That code is:" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:96 +msgid "" +"Now let’s get into the details of these rules and demonstrate them in action!" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:98 +msgid "Grouping Related Code in Modules" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:100 +msgid "" +"_Modules_ let us organize code within a crate for readability and easy " +"reuse. Modules also allow us to control the _privacy_ of items because code " +"within a module is private by default. Private items are internal " +"implementation details not available for outside use. We can choose to make " +"modules and the items within them public, which exposes them to allow " +"external code to use and depend on them." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:107 +msgid "" +"As an example, let’s write a library crate that provides the functionality " +"of a restaurant. We’ll define the signatures of functions but leave their " +"bodies empty to concentrate on the organization of the code rather than the " +"implementation of a restaurant." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:112 +msgid "" +"In the restaurant industry, some parts of a restaurant are referred to as " +"_front of house_ and others as _back of house_. Front of house is where " +"customers are; this encompasses where the hosts seat customers, servers take " +"orders and payment, and bartenders make drinks. Back of house is where the " +"chefs and cooks work in the kitchen, dishwashers clean up, and managers do " +"administrative work." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:119 +msgid "" +"To structure our crate in this way, we can organize its functions into " +"nested modules. Create a new library named `restaurant` by running `cargo " +"new restaurant --lib`. Then enter the code in Listing 7-1 into _src/lib.rs_ " +"to define some modules and function signatures; this code is the front of " +"house section." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:125 +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:32 +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:151 +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:225 +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:313 +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:353 +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:404 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:15 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:45 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:108 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:162 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:194 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:231 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:431 +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:445 +#: src/ch07-05-separating-modules-into-different-files.md:19 +#: src/ch09-03-to-panic-or-not-to-panic.md:213 src/ch10-02-traits.md:30 +#: src/ch10-02-traits.md:67 src/ch10-02-traits.md:170 src/ch10-02-traits.md:606 +#: src/ch10-03-lifetime-syntax.md:580 src/ch11-01-writing-tests.md:147 +#: src/ch11-01-writing-tests.md:386 src/ch11-01-writing-tests.md:709 +#: src/ch11-02-running-tests.md:297 src/ch11-03-test-organization.md:38 +#: src/ch12-04-testing-the-librarys-functionality.md:493 +#: src/ch12-05-working-with-environment-variables.md:275 +#: src/ch15-05-interior-mutability.md:149 +#: src/ch15-05-interior-mutability.md:213 +#: src/ch15-05-interior-mutability.md:345 +#: src/ch15-05-interior-mutability.md:466 src/ch17-01-what-is-oo.md:47 +#: src/ch17-01-what-is-oo.md:66 src/ch17-02-trait-objects.md:69 +#: src/ch17-02-trait-objects.md:85 src/ch17-02-trait-objects.md:104 +#: src/ch17-02-trait-objects.md:134 src/ch17-02-trait-objects.md:178 +#: src/ch17-03-oo-design-patterns.md:100 src/ch17-03-oo-design-patterns.md:151 +#: src/ch17-03-oo-design-patterns.md:202 src/ch17-03-oo-design-patterns.md:246 +#: src/ch17-03-oo-design-patterns.md:353 src/ch17-03-oo-design-patterns.md:454 +#: src/ch17-03-oo-design-patterns.md:564 src/ch17-03-oo-design-patterns.md:779 +#: src/ch17-03-oo-design-patterns.md:839 src/ch19-03-advanced-traits.md:50 +#: src/ch19-03-advanced-traits.md:199 src/ch19-06-macros.md:78 +#: src/ch19-06-macros.md:178 src/ch19-06-macros.md:242 +#: src/ch20-02-multithreaded.md:307 src/ch20-02-multithreaded.md:386 +#: src/ch20-02-multithreaded.md:457 src/ch20-02-multithreaded.md:513 +#: src/ch20-02-multithreaded.md:587 src/ch20-02-multithreaded.md:685 +#: src/ch20-02-multithreaded.md:792 src/ch20-02-multithreaded.md:860 +#: src/ch20-02-multithreaded.md:976 src/ch20-02-multithreaded.md:1063 +#: src/ch20-02-multithreaded.md:1151 src/ch20-02-multithreaded.md:1304 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:25 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:147 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:267 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:355 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:464 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:565 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:833 +msgid "Filename: src/lib.rs" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:145 +msgid "" +"Listing 7-1: A `front_of_house` module containing " +"other modules that then contain functions" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:148 +msgid "" +"We define a module with the `mod` keyword followed by the name of the module " +"(in this case, `front_of_house`). The body of the module then goes inside " +"curly brackets. Inside modules, we can place other modules, as in this case " +"with the modules `hosting` and `serving`. Modules can also hold definitions " +"for other items, such as structs, enums, constants, traits, and—as in " +"Listing 7-1—functions." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:155 +msgid "" +"By using modules, we can group related definitions together and name why " +"they’re related. Programmers using this code can navigate the code based on " +"the groups rather than having to read through all the definitions, making it " +"easier to find the definitions relevant to them. Programmers adding new " +"functionality to this code would know where to place the code to keep the " +"program organized." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:161 +msgid "" +"Earlier, we mentioned that _src/main.rs_ and _src/lib.rs_ are called crate " +"roots. The reason for their name is that the contents of either of these two " +"files form a module named `crate` at the root of the crate’s module " +"structure, known as the _module tree_." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:166 +msgid "Listing 7-2 shows the module tree for the structure in Listing 7-1." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:180 +msgid "" +"Listing 7-2: The module tree for the code in Listing " +"7-1" +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:183 +msgid "" +"This tree shows how some of the modules nest inside other modules; for " +"example, `hosting` nests inside `front_of_house`. The tree also shows that " +"some modules are _siblings_, meaning they’re defined in the same module; " +"`hosting` and `serving` are siblings defined within `front_of_house`. If " +"module A is contained inside module B, we say that module A is the _child_ " +"of module B and that module B is the _parent_ of module A. Notice that the " +"entire module tree is rooted under the implicit module named `crate`." +msgstr "" + +#: src/ch07-02-defining-modules-to-control-scope-and-privacy.md:191 +msgid "" +"The module tree might remind you of the filesystem’s directory tree on your " +"computer; this is a very apt comparison! Just like directories in a " +"filesystem, you use modules to organize your code. And just like files in a " +"directory, we need a way to find our modules." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:3 +msgid "" +"To show Rust where to find an item in a module tree, we use a path in the " +"same way we use a path when navigating a filesystem. To call a function, we " +"need to know its path." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:7 +msgid "A path can take two forms:" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:9 +msgid "" +"An _absolute path_ is the full path starting from a crate root; for code " +"from an external crate, the absolute path begins with the crate name, and " +"for code from the current crate, it starts with the literal `crate`." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:12 +msgid "" +"A _relative path_ starts from the current module and uses `self`, `super`, " +"or an identifier in the current module." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:15 +msgid "" +"Both absolute and relative paths are followed by one or more identifiers " +"separated by double colons (`::`)." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:18 +msgid "" +"Returning to Listing 7-1, say we want to call the `add_to_waitlist` " +"function. This is the same as asking: what’s the path of the " +"`add_to_waitlist` function? Listing 7-3 contains Listing 7-1 with some of " +"the modules and functions removed." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:23 +msgid "" +"We’ll show two ways to call the `add_to_waitlist` function from a new " +"function, `eat_at_restaurant`, defined in the crate root. These paths are " +"correct, but there’s another problem remaining that will prevent this " +"example from compiling as is. We’ll explain why in a bit." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:28 +msgid "" +"The `eat_at_restaurant` function is part of our library crate’s public API, " +"so we mark it with the `pub` keyword. In the [“Exposing Paths with the `pub` " +"Keyword”](ch07-03-paths-for-referring-to-an-item-in-the-module-tree." +"html#exposing-paths-with-the-pub-keyword) section, we’ll go " +"into more detail about `pub`." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:42 +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:161 +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:235 +msgid "// Absolute path\n" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:45 +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:164 +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:238 +msgid "// Relative path\n" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:50 +msgid "" +"Listing 7-3: Calling the `add_to_waitlist` function " +"using absolute and relative paths" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:53 +msgid "" +"The first time we call the `add_to_waitlist` function in " +"`eat_at_restaurant`, we use an absolute path. The `add_to_waitlist` function " +"is defined in the same crate as `eat_at_restaurant`, which means we can use " +"the `crate` keyword to start an absolute path. We then include each of the " +"successive modules until we make our way to `add_to_waitlist`. You can " +"imagine a filesystem with the same structure: we’d specify the path `/" +"front_of_house/hosting/add_to_waitlist` to run the `add_to_waitlist` " +"program; using the `crate` name to start from the crate root is like using `/" +"` to start from the filesystem root in your shell." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:62 +msgid "" +"The second time we call `add_to_waitlist` in `eat_at_restaurant`, we use a " +"relative path. The path starts with `front_of_house`, the name of the module " +"defined at the same level of the module tree as `eat_at_restaurant`. Here " +"the filesystem equivalent would be using the path `front_of_house/hosting/" +"add_to_waitlist`. Starting with a module name means that the path is " +"relative." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:69 +msgid "" +"Choosing whether to use a relative or absolute path is a decision you’ll " +"make based on your project, and it depends on whether you’re more likely to " +"move item definition code separately from or together with the code that " +"uses the item. For example, if we moved the `front_of_house` module and the " +"`eat_at_restaurant` function into a module named `customer_experience`, we’d " +"need to update the absolute path to `add_to_waitlist`, but the relative path " +"would still be valid. However, if we moved the `eat_at_restaurant` function " +"separately into a module named `dining`, the absolute path to the " +"`add_to_waitlist` call would stay the same, but the relative path would need " +"to be updated. Our preference in general is to specify absolute paths " +"because it’s more likely we’ll want to move code definitions and item calls " +"independently of each other." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:82 +msgid "" +"Let’s try to compile Listing 7-3 and find out why it won’t compile yet! The " +"errors we get are shown in Listing 7-4." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:85 +msgid "" +"```console\n" +"$ cargo build\n" +" Compiling restaurant v0.1.0 (file:///projects/restaurant)\n" +"error[E0603]: module `hosting` is private\n" +" --> src/lib.rs:9:28\n" +" |\n" +"9 | crate::front_of_house::hosting::add_to_waitlist();\n" +" | ^^^^^^^ --------------- function " +"`add_to_waitlist` is not publicly re-exported\n" +" | |\n" +" | private module\n" +" |\n" +"note: the module `hosting` is defined here\n" +" --> src/lib.rs:2:5\n" +" |\n" +"2 | mod hosting {\n" +" | ^^^^^^^^^^^\n" +"\n" +"error[E0603]: module `hosting` is private\n" +" --> src/lib.rs:12:21\n" +" |\n" +"12 | front_of_house::hosting::add_to_waitlist();\n" +" | ^^^^^^^ --------------- function `add_to_waitlist` " +"is not publicly re-exported\n" +" | |\n" +" | private module\n" +" |\n" +"note: the module `hosting` is defined here\n" +" --> src/lib.rs:2:5\n" +" |\n" +"2 | mod hosting {\n" +" | ^^^^^^^^^^^\n" +"\n" +"For more information about this error, try `rustc --explain E0603`.\n" +"error: could not compile `restaurant` (lib) due to 2 previous errors\n" +"```" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:120 +msgid "" +"Listing 7-4: Compiler errors from building the code " +"in Listing 7-3" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:123 +msgid "" +"The error messages say that module `hosting` is private. In other words, we " +"have the correct paths for the `hosting` module and the `add_to_waitlist` " +"function, but Rust won’t let us use them because it doesn’t have access to " +"the private sections. In Rust, all items (functions, methods, structs, " +"enums, modules, and constants) are private to parent modules by default. If " +"you want to make an item like a function or struct private, you put it in a " +"module." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:130 +msgid "" +"Items in a parent module can’t use the private items inside child modules, " +"but items in child modules can use the items in their ancestor modules. This " +"is because child modules wrap and hide their implementation details, but the " +"child modules can see the context in which they’re defined. To continue with " +"our metaphor, think of the privacy rules as being like the back office of a " +"restaurant: what goes on in there is private to restaurant customers, but " +"office managers can see and do everything in the restaurant they operate." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:138 +msgid "" +"Rust chose to have the module system function this way so that hiding inner " +"implementation details is the default. That way, you know which parts of the " +"inner code you can change without breaking outer code. However, Rust does " +"give you the option to expose inner parts of child modules’ code to outer " +"ancestor modules by using the `pub` keyword to make an item public." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:144 +msgid "Exposing Paths with the `pub` Keyword" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:146 +msgid "" +"Let’s return to the error in Listing 7-4 that told us the `hosting` module " +"is private. We want the `eat_at_restaurant` function in the parent module to " +"have access to the `add_to_waitlist` function in the child module, so we " +"mark the `hosting` module with the `pub` keyword, as shown in Listing 7-5." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:169 +msgid "" +"Listing 7-5: Declaring the `hosting` module as `pub` " +"to use it from `eat_at_restaurant`" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:172 +msgid "" +"Unfortunately, the code in Listing 7-5 still results in compiler errors, as " +"shown in Listing 7-6." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:175 +msgid "" +"```console\n" +"$ cargo build\n" +" Compiling restaurant v0.1.0 (file:///projects/restaurant)\n" +"error[E0603]: function `add_to_waitlist` is private\n" +" --> src/lib.rs:9:37\n" +" |\n" +"9 | crate::front_of_house::hosting::add_to_waitlist();\n" +" | ^^^^^^^^^^^^^^^ private function\n" +" |\n" +"note: the function `add_to_waitlist` is defined here\n" +" --> src/lib.rs:3:9\n" +" |\n" +"3 | fn add_to_waitlist() {}\n" +" | ^^^^^^^^^^^^^^^^^^^^\n" +"\n" +"error[E0603]: function `add_to_waitlist` is private\n" +" --> src/lib.rs:12:30\n" +" |\n" +"12 | front_of_house::hosting::add_to_waitlist();\n" +" | ^^^^^^^^^^^^^^^ private function\n" +" |\n" +"note: the function `add_to_waitlist` is defined here\n" +" --> src/lib.rs:3:9\n" +" |\n" +"3 | fn add_to_waitlist() {}\n" +" | ^^^^^^^^^^^^^^^^^^^^\n" +"\n" +"For more information about this error, try `rustc --explain E0603`.\n" +"error: could not compile `restaurant` (lib) due to 2 previous errors\n" +"```" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:206 +msgid "" +"Listing 7-6: Compiler errors from building the code " +"in Listing 7-5" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:209 +msgid "" +"What happened? Adding the `pub` keyword in front of `mod hosting` makes the " +"module public. With this change, if we can access `front_of_house`, we can " +"access `hosting`. But the _contents_ of `hosting` are still private; making " +"the module public doesn’t make its contents public. The `pub` keyword on a " +"module only lets code in its ancestor modules refer to it, not access its " +"inner code. Because modules are containers, there’s not much we can do by " +"only making the module public; we need to go further and choose to make one " +"or more of the items within the module public as well." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:218 +msgid "" +"The errors in Listing 7-6 say that the `add_to_waitlist` function is " +"private. The privacy rules apply to structs, enums, functions, and methods " +"as well as modules." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:222 +msgid "" +"Let’s also make the `add_to_waitlist` function public by adding the `pub` " +"keyword before its definition, as in Listing 7-7." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:243 +msgid "" +"Listing 7-7: Adding the `pub` keyword to `mod " +"hosting` and `fn add_to_waitlist` lets us call the function from " +"`eat_at_restaurant`" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:247 +msgid "" +"Now the code will compile! To see why adding the `pub` keyword lets us use " +"these paths in `eat_at_restaurant` with respect to the privacy rules, let’s " +"look at the absolute and the relative paths." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:251 +msgid "" +"In the absolute path, we start with `crate`, the root of our crate’s module " +"tree. The `front_of_house` module is defined in the crate root. While " +"`front_of_house` isn’t public, because the `eat_at_restaurant` function is " +"defined in the same module as `front_of_house` (that is, `eat_at_restaurant` " +"and `front_of_house` are siblings), we can refer to `front_of_house` from " +"`eat_at_restaurant`. Next is the `hosting` module marked with `pub`. We can " +"access the parent module of `hosting`, so we can access `hosting`. Finally, " +"the `add_to_waitlist` function is marked with `pub` and we can access its " +"parent module, so this function call works!" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:261 +msgid "" +"In the relative path, the logic is the same as the absolute path except for " +"the first step: rather than starting from the crate root, the path starts " +"from `front_of_house`. The `front_of_house` module is defined within the " +"same module as `eat_at_restaurant`, so the relative path starting from the " +"module in which `eat_at_restaurant` is defined works. Then, because " +"`hosting` and `add_to_waitlist` are marked with `pub`, the rest of the path " +"works, and this function call is valid!" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:269 +msgid "" +"If you plan on sharing your library crate so other projects can use your " +"code, your public API is your contract with users of your crate that " +"determines how they can interact with your code. There are many " +"considerations around managing changes to your public API to make it easier " +"for people to depend on your crate. These considerations are out of the " +"scope of this book; if you’re interested in this topic, see [The Rust API " +"Guidelines](https://rust-lang.github.io/api-guidelines/)." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:276 +msgid "Best Practices for Packages with a Binary and a Library" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:278 +msgid "" +"We mentioned that a package can contain both a _src/main.rs_ binary crate " +"root as well as a _src/lib.rs_ library crate root, and both crates will have " +"the package name by default. Typically, packages with this pattern of " +"containing both a library and a binary crate will have just enough code in " +"the binary crate to start an executable that calls code within the library " +"crate. This lets other projects benefit from most of the functionality that " +"the package provides because the library crate’s code can be shared." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:286 +msgid "" +"The module tree should be defined in _src/lib.rs_. Then, any public items " +"can be used in the binary crate by starting paths with the name of the " +"package. The binary crate becomes a user of the library crate just like a " +"completely external crate would use the library crate: it can only use the " +"public API. This helps you design a good API; not only are you the author, " +"you’re also a client!" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:293 +msgid "" +"In [Chapter 12](ch12-00-an-io-project.html), we’ll " +"demonstrate this organizational practice with a command-line program that " +"will contain both a binary crate and a library crate." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:297 +msgid "Starting Relative Paths with `super`" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:299 +msgid "" +"We can construct relative paths that begin in the parent module, rather than " +"the current module or the crate root, by using `super` at the start of the " +"path. This is like starting a filesystem path with the `..` syntax. Using " +"`super` allows us to reference an item that we know is in the parent module, " +"which can make rearranging the module tree easier when the module is closely " +"related to the parent but the parent might be moved elsewhere in the module " +"tree someday." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:307 +msgid "" +"Consider the code in Listing 7-8 that models the situation in which a chef " +"fixes an incorrect order and personally brings it out to the customer. The " +"function `fix_incorrect_order` defined in the `back_of_house` module calls " +"the function `deliver_order` defined in the parent module by specifying the " +"path to `deliver_order`, starting with `super`." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:328 +msgid "" +"Listing 7-8: Calling a function using a relative " +"path starting with `super`" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:331 +msgid "" +"The `fix_incorrect_order` function is in the `back_of_house` module, so we " +"can use `super` to go to the parent module of `back_of_house`, which in this " +"case is `crate`, the root. From there, we look for `deliver_order` and find " +"it. Success! We think the `back_of_house` module and the `deliver_order` " +"function are likely to stay in the same relationship to each other and get " +"moved together should we decide to reorganize the crate’s module tree. " +"Therefore, we used `super` so we’ll have fewer places to update code in the " +"future if this code gets moved to a different module." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:340 +msgid "Making Structs and Enums Public" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:342 +msgid "" +"We can also use `pub` to designate structs and enums as public, but there " +"are a few extra details to the usage of `pub` with structs and enums. If we " +"use `pub` before a struct definition, we make the struct public, but the " +"struct’s fields will still be private. We can make each field public or not " +"on a case-by-case basis. In Listing 7-9, we’ve defined a public " +"`back_of_house::Breakfast` struct with a public `toast` field but a private " +"`seasonal_fruit` field. This models the case in a restaurant where the " +"customer can pick the type of bread that comes with a meal, but the chef " +"decides which fruit accompanies the meal based on what’s in season and in " +"stock. The available fruit changes quickly, so customers can’t choose the " +"fruit or even see which fruit they’ll get." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:366 +msgid "\"peaches\"" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:373 +msgid "// Order a breakfast in the summer with Rye toast\n" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:374 +msgid "\"Rye\"" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:375 +msgid "// Change our mind about what bread we'd like\n" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:376 +msgid "\"Wheat\"" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:377 +msgid "\"I'd like {} toast please\"" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:379 +msgid "" +"// The next line won't compile if we uncomment it; we're not allowed\n" +" // to see or modify the seasonal fruit that comes with the meal\n" +" // meal.seasonal_fruit = String::from(\"blueberries\");\n" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:385 +msgid "" +"Listing 7-9: A struct with some public fields and " +"some private fields" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:388 +msgid "" +"Because the `toast` field in the `back_of_house::Breakfast` struct is " +"public, in `eat_at_restaurant` we can write and read to the `toast` field " +"using dot notation. Notice that we can’t use the `seasonal_fruit` field in " +"`eat_at_restaurant`, because `seasonal_fruit` is private. Try uncommenting " +"the line modifying the `seasonal_fruit` field value to see what error you " +"get!" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:394 +msgid "" +"Also, note that because `back_of_house::Breakfast` has a private field, the " +"struct needs to provide a public associated function that constructs an " +"instance of `Breakfast` (we’ve named it `summer` here). If `Breakfast` " +"didn’t have such a function, we couldn’t create an instance of `Breakfast` " +"in `eat_at_restaurant` because we couldn’t set the value of the private " +"`seasonal_fruit` field in `eat_at_restaurant`." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:401 +msgid "" +"In contrast, if we make an enum public, all of its variants are then public. " +"We only need the `pub` before the `enum` keyword, as shown in Listing 7-10." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:420 +msgid "" +"Listing 7-10: Designating an enum as public makes " +"all its variants public" +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:423 +msgid "" +"Because we made the `Appetizer` enum public, we can use the `Soup` and " +"`Salad` variants in `eat_at_restaurant`." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:426 +msgid "" +"Enums aren’t very useful unless their variants are public; it would be " +"annoying to have to annotate all enum variants with `pub` in every case, so " +"the default for enum variants is to be public. Structs are often useful " +"without their fields being public, so struct fields follow the general rule " +"of everything being private by default unless annotated with `pub`." +msgstr "" + +#: src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md:432 +msgid "" +"There’s one more situation involving `pub` that we haven’t covered, and that " +"is our last module system feature: the `use` keyword. We’ll cover `use` by " +"itself first, and then we’ll show how to combine `pub` and `use`." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:1 +msgid "Bringing Paths into Scope with the `use` Keyword" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:3 +msgid "" +"Having to write out the paths to call functions can feel inconvenient and " +"repetitive. In Listing 7-7, whether we chose the absolute or relative path " +"to the `add_to_waitlist` function, every time we wanted to call " +"`add_to_waitlist` we had to specify `front_of_house` and `hosting` too. " +"Fortunately, there’s a way to simplify this process: we can create a " +"shortcut to a path with the `use` keyword once, and then use the shorter " +"name everywhere else in the scope." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:10 +msgid "" +"In Listing 7-11, we bring the `crate::front_of_house::hosting` module into " +"the scope of the `eat_at_restaurant` function so we only have to specify " +"`hosting::add_to_waitlist` to call the `add_to_waitlist` function in " +"`eat_at_restaurant`." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:31 +msgid "" +"Listing 7-11: Bringing a module into scope with " +"`use`" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:34 +msgid "" +"Adding `use` and a path in a scope is similar to creating a symbolic link in " +"the filesystem. By adding `use crate::front_of_house::hosting` in the crate " +"root, `hosting` is now a valid name in that scope, just as though the " +"`hosting` module had been defined in the crate root. Paths brought into " +"scope with `use` also check privacy, like any other paths." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:40 +msgid "" +"Note that `use` only creates the shortcut for the particular scope in which " +"the `use` occurs. Listing 7-12 moves the `eat_at_restaurant` function into a " +"new child module named `customer`, which is then a different scope than the " +"`use` statement, so the function body won’t compile." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:63 +msgid "" +"Listing 7-12: A `use` statement only applies in the " +"scope it’s in" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:66 +msgid "" +"The compiler error shows that the shortcut no longer applies within the " +"`customer` module:" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:69 +msgid "" +"```console\n" +"$ cargo build\n" +" Compiling restaurant v0.1.0 (file:///projects/restaurant)\n" +"error[E0433]: failed to resolve: use of undeclared crate or module " +"`hosting`\n" +" --> src/lib.rs:11:9\n" +" |\n" +"11 | hosting::add_to_waitlist();\n" +" | ^^^^^^^ use of undeclared crate or module `hosting`\n" +" |\n" +"help: consider importing this module through its public re-export\n" +" |\n" +"10 + use crate::hosting;\n" +" |\n" +"\n" +"warning: unused import: `crate::front_of_house::hosting`\n" +" --> src/lib.rs:7:5\n" +" |\n" +"7 | use crate::front_of_house::hosting;\n" +" | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +" |\n" +" = note: `#[warn(unused_imports)]` on by default\n" +"\n" +"For more information about this error, try `rustc --explain E0433`.\n" +"warning: `restaurant` (lib) generated 1 warning\n" +"error: could not compile `restaurant` (lib) due to 1 previous error; 1 " +"warning emitted\n" +"```" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:96 +msgid "" +"Notice there’s also a warning that the `use` is no longer used in its scope! " +"To fix this problem, move the `use` within the `customer` module too, or " +"reference the shortcut in the parent module with `super::hosting` within the " +"child `customer` module." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:101 +msgid "Creating Idiomatic `use` Paths" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:103 +msgid "" +"In Listing 7-11, you might have wondered why we specified `use crate::" +"front_of_house::hosting` and then called `hosting::add_to_waitlist` in " +"`eat_at_restaurant`, rather than specifying the `use` path all the way out " +"to the `add_to_waitlist` function to achieve the same result, as in Listing " +"7-13." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:124 +msgid "" +"Listing 7-13: Bringing the `add_to_waitlist` " +"function into scope with `use`, which is unidiomatic" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:127 +msgid "" +"Although both Listing 7-11 and Listing 7-13 accomplish the same task, " +"Listing 7-11 is the idiomatic way to bring a function into scope with `use`. " +"Bringing the function’s parent module into scope with `use` means we have to " +"specify the parent module when calling the function. Specifying the parent " +"module when calling the function makes it clear that the function isn’t " +"locally defined while still minimizing repetition of the full path. The code " +"in Listing 7-13 is unclear as to where `add_to_waitlist` is defined." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:135 +msgid "" +"On the other hand, when bringing in structs, enums, and other items with " +"`use`, it’s idiomatic to specify the full path. Listing 7-14 shows the " +"idiomatic way to bring the standard library’s `HashMap` struct into the " +"scope of a binary crate." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:151 +msgid "" +"Listing 7-14: Bringing `HashMap` into scope in an " +"idiomatic way" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:154 +msgid "" +"There’s no strong reason behind this idiom: it’s just the convention that " +"has emerged, and folks have gotten used to reading and writing Rust code " +"this way." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:157 +msgid "" +"The exception to this idiom is if we’re bringing two items with the same " +"name into scope with `use` statements, because Rust doesn’t allow that. " +"Listing 7-15 shows how to bring two `Result` types into scope that have the " +"same name but different parent modules, and how to refer to them." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:179 +msgid "" +"Listing 7-15: Bringing two types with the same name " +"into the same scope requires using their parent modules." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:182 +msgid "" +"As you can see, using the parent modules distinguishes the two `Result` " +"types. If instead we specified `use std::fmt::Result` and `use std::io::" +"Result`, we’d have two `Result` types in the same scope, and Rust wouldn’t " +"know which one we meant when we used `Result`." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:187 +msgid "Providing New Names with the `as` Keyword" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:189 +msgid "" +"There’s another solution to the problem of bringing two types of the same " +"name into the same scope with `use`: after the path, we can specify `as` and " +"a new local name, or _alias_, for the type. Listing 7-16 shows another way " +"to write the code in Listing 7-15 by renaming one of the two `Result` types " +"using `as`." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:211 +msgid "" +"Listing 7-16: Renaming a type when it’s brought into " +"scope with the `as` keyword" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:214 +msgid "" +"In the second `use` statement, we chose the new name `IoResult` for the " +"`std::io::Result` type, which won’t conflict with the `Result` from `std::" +"fmt` that we’ve also brought into scope. Listing 7-15 and Listing 7-16 are " +"considered idiomatic, so the choice is up to you!" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:219 +msgid "Re-exporting Names with `pub use`" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:221 +msgid "" +"When we bring a name into scope with the `use` keyword, the name available " +"in the new scope is private. To enable the code that calls our code to refer " +"to that name as if it had been defined in that code’s scope, we can combine " +"`pub` and `use`. This technique is called _re-exporting_ because we’re " +"bringing an item into scope but also making that item available for others " +"to bring into their scope." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:228 +msgid "" +"Listing 7-17 shows the code in Listing 7-11 with `use` in the root module " +"changed to `pub use`." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:247 +msgid "" +"Listing 7-17: Making a name available for any code " +"to use from a new scope with `pub use`" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:250 +msgid "" +"Before this change, external code would have to call the `add_to_waitlist` " +"function by using the path `restaurant::front_of_house::hosting::" +"add_to_waitlist()`, which also would have required the `front_of_house` " +"module to be marked as `pub`. Now that this `pub use` has re-exported the " +"`hosting` module from the root module, external code can use the path " +"`restaurant::hosting::add_to_waitlist()` instead." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:257 +msgid "" +"Re-exporting is useful when the internal structure of your code is different " +"from how programmers calling your code would think about the domain. For " +"example, in this restaurant metaphor, the people running the restaurant " +"think about “front of house” and “back of house.” But customers visiting a " +"restaurant probably won’t think about the parts of the restaurant in those " +"terms. With `pub use`, we can write our code with one structure but expose a " +"different structure. Doing so makes our library well organized for " +"programmers working on the library and programmers calling the library. " +"We’ll look at another example of `pub use` and how it affects your crate’s " +"documentation in the [“Exporting a Convenient Public API with `pub use`”]" +"(ch14-02-publishing-to-crates-io.html#exporting-a-convenient-public-api-with-" +"pub-use) section of Chapter 14." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:269 +msgid "Using External Packages" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:271 +msgid "" +"In Chapter 2, we programmed a guessing game project that used an external " +"package called `rand` to get random numbers. To use `rand` in our project, " +"we added this line to _Cargo.toml_:" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:283 +msgid "" +"```toml\n" +"rand = \"0.8.5\"\n" +"```" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:287 +msgid "" +"Adding `rand` as a dependency in _Cargo.toml_ tells Cargo to download the " +"`rand` package and any dependencies from [crates.io](https://crates.io/) and " +"make `rand` available to our project." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:291 +msgid "" +"Then, to bring `rand` definitions into the scope of our package, we added a " +"`use` line starting with the name of the crate, `rand`, and listed the items " +"we wanted to bring into scope. Recall that in the [“Generating a Random " +"Number”](ch02-00-guessing-game-tutorial.html#generating-a-random-number) section in Chapter 2, we brought the `Rng` trait into scope and " +"called the `rand::thread_rng` function:" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:320 +msgid "" +"Members of the Rust community have made many packages available at [crates." +"io](https://crates.io/), and pulling any of them into your package involves " +"these same steps: listing them in your package’s _Cargo.toml_ file and using " +"`use` to bring items from their crates into scope." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:325 +msgid "" +"Note that the standard `std` library is also a crate that’s external to our " +"package. Because the standard library is shipped with the Rust language, we " +"don’t need to change _Cargo.toml_ to include `std`. But we do need to refer " +"to it with `use` to bring items from there into our package’s scope. For " +"example, with `HashMap` we would use this line:" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:335 +msgid "" +"This is an absolute path starting with `std`, the name of the standard " +"library crate." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:338 +msgid "Using Nested Paths to Clean Up Large `use` Lists" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:340 +msgid "" +"If we’re using multiple items defined in the same crate or same module, " +"listing each item on its own line can take up a lot of vertical space in our " +"files. For example, these two `use` statements we had in the guessing game " +"in Listing 2-4 bring items from `std` into scope:" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:379 +msgid "" +"Instead, we can use nested paths to bring the same items into scope in one " +"line. We do this by specifying the common part of the path, followed by two " +"colons, and then curly brackets around a list of the parts of the paths that " +"differ, as shown in Listing 7-18." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:419 +msgid "" +"Listing 7-18: Specifying a nested path to bring " +"multiple items with the same prefix into scope" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:422 +msgid "" +"In bigger programs, bringing many items into scope from the same crate or " +"module using nested paths can reduce the number of separate `use` statements " +"needed by a lot!" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:426 +msgid "" +"We can use a nested path at any level in a path, which is useful when " +"combining two `use` statements that share a subpath. For example, Listing " +"7-19 shows two `use` statements: one that brings `std::io` into scope and " +"one that brings `std::io::Write` into scope." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:438 +msgid "" +"Listing 7-19: Two `use` statements where one is a " +"subpath of the other" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:441 +msgid "" +"The common part of these two paths is `std::io`, and that’s the complete " +"first path. To merge these two paths into one `use` statement, we can use " +"`self` in the nested path, as shown in Listing 7-20." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:451 +msgid "" +"Listing 7-20: Combining the paths in Listing 7-19 " +"into one `use` statement" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:454 +msgid "This line brings `std::io` and `std::io::Write` into scope." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:456 +msgid "The Glob Operator" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:458 +msgid "" +"If we want to bring _all_ public items defined in a path into scope, we can " +"specify that path followed by the `*` glob operator:" +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:465 +msgid "" +"This `use` statement brings all public items defined in `std::collections` " +"into the current scope. Be careful when using the glob operator! Glob can " +"make it harder to tell what names are in scope and where a name used in your " +"program was defined." +msgstr "" + +#: src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md:470 +msgid "" +"The glob operator is often used when testing to bring everything under test " +"into the `tests` module; we’ll talk about that in the [“How to Write Tests”]" +"(ch11-01-writing-tests.html#how-to-write-tests) section in " +"Chapter 11. The glob operator is also sometimes used as part of the prelude " +"pattern: see [the standard library documentation](../std/prelude/index." +"html#other-preludes) for more information on that pattern." +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:3 +msgid "" +"So far, all the examples in this chapter defined multiple modules in one " +"file. When modules get large, you might want to move their definitions to a " +"separate file to make the code easier to navigate." +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:7 +msgid "" +"For example, let’s start from the code in Listing 7-17 that had multiple " +"restaurant modules. We’ll extract modules into files instead of having all " +"the modules defined in the crate root file. In this case, the crate root " +"file is _src/lib.rs_, but this procedure also works with binary crates whose " +"crate root file is _src/main.rs_." +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:13 +msgid "" +"First we’ll extract the `front_of_house` module to its own file. Remove the " +"code inside the curly brackets for the `front_of_house` module, leaving only " +"the `mod front_of_house;` declaration, so that _src/lib.rs_ contains the " +"code shown in Listing 7-21. Note that this won’t compile until we create the " +"_src/front_of_house.rs_ file in Listing 7-22." +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:31 +msgid "" +"Listing 7-21: Declaring the `front_of_house` module " +"whose body will be in _src/front_of_house.rs_" +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:34 +msgid "" +"Next, place the code that was in the curly brackets into a new file named " +"_src/front_of_house.rs_, as shown in Listing 7-22. The compiler knows to " +"look in this file because it came across the module declaration in the crate " +"root with the name `front_of_house`." +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:39 +#: src/ch07-05-separating-modules-into-different-files.md:67 +msgid "Filename: src/front_of_house.rs" +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:47 +msgid "" +"Listing 7-22: Definitions inside the " +"`front_of_house` module in _src/front_of_house.rs_" +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:50 +msgid "" +"Note that you only need to load a file using a `mod` declaration _once_ in " +"your module tree. Once the compiler knows the file is part of the project " +"(and knows where in the module tree the code resides because of where you’ve " +"put the `mod` statement), other files in your project should refer to the " +"loaded file’s code using a path to where it was declared, as covered in the " +"[“Paths for Referring to an Item in the Module Tree”](ch07-03-paths-for-" +"referring-to-an-item-in-the-module-tree.html) section. In " +"other words, `mod` is _not_ an “include” operation that you may have seen in " +"other programming languages." +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:59 +msgid "" +"Next, we’ll extract the `hosting` module to its own file. The process is a " +"bit different because `hosting` is a child module of `front_of_house`, not " +"of the root module. We’ll place the file for `hosting` in a new directory " +"that will be named for its ancestors in the module tree, in this case _src/" +"front_of_house_." +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:64 +msgid "" +"To start moving `hosting`, we change _src/front_of_house.rs_ to contain only " +"the declaration of the `hosting` module:" +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:73 +msgid "" +"Then we create a _src/front_of_house_ directory and a _hosting.rs_ file to " +"contain the definitions made in the `hosting` module:" +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:76 +msgid "Filename: src/front_of_house/hosting.rs" +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:82 +msgid "" +"If we instead put _hosting.rs_ in the _src_ directory, the compiler would " +"expect the _hosting.rs_ code to be in a `hosting` module declared in the " +"crate root, and not declared as a child of the `front_of_house` module. The " +"compiler’s rules for which files to check for which modules’ code mean the " +"directories and files more closely match the module tree." +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:88 +msgid "Alternate File Paths" +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:90 +msgid "" +"So far we’ve covered the most idiomatic file paths the Rust compiler uses, " +"but Rust also supports an older style of file path. For a module named " +"`front_of_house` declared in the crate root, the compiler will look for the " +"module’s code in:" +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:95 +msgid "_src/front_of_house.rs_ (what we covered)" +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:96 +msgid "_src/front_of_house/mod.rs_ (older style, still supported path)" +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:98 +msgid "" +"For a module named `hosting` that is a submodule of `front_of_house`, the " +"compiler will look for the module’s code in:" +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:101 +msgid "_src/front_of_house/hosting.rs_ (what we covered)" +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:102 +msgid "_src/front_of_house/hosting/mod.rs_ (older style, still supported path)" +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:104 +msgid "" +"If you use both styles for the same module, you’ll get a compiler error. " +"Using a mix of both styles for different modules in the same project is " +"allowed, but might be confusing for people navigating your project." +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:108 +msgid "" +"The main downside to the style that uses files named _mod.rs_ is that your " +"project can end up with many files named _mod.rs_, which can get confusing " +"when you have them open in your editor at the same time." +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:112 +msgid "" +"We’ve moved each module’s code to a separate file, and the module tree " +"remains the same. The function calls in `eat_at_restaurant` will work " +"without any modification, even though the definitions live in different " +"files. This technique lets you move modules to new files as they grow in " +"size." +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:117 +msgid "" +"Note that the `pub use crate::front_of_house::hosting` statement in _src/lib." +"rs_ also hasn’t changed, nor does `use` have any impact on what files are " +"compiled as part of the crate. The `mod` keyword declares modules, and Rust " +"looks in a file with the same name as the module for the code that goes into " +"that module." +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:125 +msgid "" +"Rust lets you split a package into multiple crates and a crate into modules " +"so you can refer to items defined in one module from another module. You can " +"do this by specifying absolute or relative paths. These paths can be brought " +"into scope with a `use` statement so you can use a shorter path for multiple " +"uses of the item in that scope. Module code is private by default, but you " +"can make definitions public by adding the `pub` keyword." +msgstr "" + +#: src/ch07-05-separating-modules-into-different-files.md:132 +msgid "" +"In the next chapter, we’ll look at some collection data structures in the " +"standard library that you can use in your neatly organized code." +msgstr "" + +#: src/ch08-00-common-collections.md:3 +msgid "" +"Rust’s standard library includes a number of very useful data structures " +"called _collections_. Most other data types represent one specific value, " +"but collections can contain multiple values. Unlike the built-in array and " +"tuple types, the data these collections point to is stored on the heap, " +"which means the amount of data does not need to be known at compile time and " +"can grow or shrink as the program runs. Each kind of collection has " +"different capabilities and costs, and choosing an appropriate one for your " +"current situation is a skill you’ll develop over time. In this chapter, " +"we’ll discuss three collections that are used very often in Rust programs:" +msgstr "" + +#: src/ch08-00-common-collections.md:13 +msgid "" +"A _vector_ allows you to store a variable number of values next to each " +"other." +msgstr "" + +#: src/ch08-00-common-collections.md:14 +msgid "" +"A _string_ is a collection of characters. We’ve mentioned the `String` type " +"previously, but in this chapter we’ll talk about it in depth." +msgstr "" + +#: src/ch08-00-common-collections.md:16 +msgid "" +"A _hash map_ allows you to associate a value with a specific key. It’s a " +"particular implementation of the more general data structure called a _map_." +msgstr "" + +#: src/ch08-00-common-collections.md:19 +msgid "" +"To learn about the other kinds of collections provided by the standard " +"library, see [the documentation](../std/collections/index.html)." +msgstr "" + +#: src/ch08-00-common-collections.md:22 +msgid "" +"We’ll discuss how to create and update vectors, strings, and hash maps, as " +"well as what makes each special." +msgstr "" + +#: src/ch08-01-vectors.md:3 +msgid "" +"The first collection type we’ll look at is `Vec`, also known as a " +"_vector_. Vectors allow you to store more than one value in a single data " +"structure that puts all the values next to each other in memory. Vectors can " +"only store values of the same type. They are useful when you have a list of " +"items, such as the lines of text in a file or the prices of items in a " +"shopping cart." +msgstr "" + +#: src/ch08-01-vectors.md:9 +msgid "Creating a New Vector" +msgstr "" + +#: src/ch08-01-vectors.md:11 +msgid "" +"To create a new empty vector, we call the `Vec::new` function, as shown in " +"Listing 8-1." +msgstr "" + +#: src/ch08-01-vectors.md:20 +msgid "" +"Listing 8-1: Creating a new, empty vector to hold " +"values of type `i32`" +msgstr "" + +#: src/ch08-01-vectors.md:23 +msgid "" +"Note that we added a type annotation here. Because we aren’t inserting any " +"values into this vector, Rust doesn’t know what kind of elements we intend " +"to store. This is an important point. Vectors are implemented using " +"generics; we’ll cover how to use generics with your own types in Chapter 10. " +"For now, know that the `Vec` type provided by the standard library can " +"hold any type. When we create a vector to hold a specific type, we can " +"specify the type within angle brackets. In Listing 8-1, we’ve told Rust that " +"the `Vec` in `v` will hold elements of the `i32` type." +msgstr "" + +#: src/ch08-01-vectors.md:32 +msgid "" +"More often, you’ll create a `Vec` with initial values and Rust will infer " +"the type of value you want to store, so you rarely need to do this type " +"annotation. Rust conveniently provides the `vec!` macro, which will create a " +"new vector that holds the values you give it. Listing 8-2 creates a new " +"`Vec` that holds the values `1`, `2`, and `3`. The integer type is " +"`i32` because that’s the default integer type, as we discussed in the [“Data " +"Types”](ch03-02-data-types.html#data-types) section of " +"Chapter 3." +msgstr "" + +#: src/ch08-01-vectors.md:46 +msgid "" +"Listing 8-2: Creating a new vector containing " +"values" +msgstr "" + +#: src/ch08-01-vectors.md:49 +msgid "" +"Because we’ve given initial `i32` values, Rust can infer that the type of " +"`v` is `Vec`, and the type annotation isn’t necessary. Next, we’ll look " +"at how to modify a vector." +msgstr "" + +#: src/ch08-01-vectors.md:53 +msgid "Updating a Vector" +msgstr "" + +#: src/ch08-01-vectors.md:55 +msgid "" +"To create a vector and then add elements to it, we can use the `push` " +"method, as shown in Listing 8-3." +msgstr "" + +#: src/ch08-01-vectors.md:69 +msgid "" +"Listing 8-3: Using the `push` method to add values " +"to a vector" +msgstr "" + +#: src/ch08-01-vectors.md:72 +msgid "" +"As with any variable, if we want to be able to change its value, we need to " +"make it mutable using the `mut` keyword, as discussed in Chapter 3. The " +"numbers we place inside are all of type `i32`, and Rust infers this from the " +"data, so we don’t need the `Vec` annotation." +msgstr "" + +#: src/ch08-01-vectors.md:77 +msgid "Reading Elements of Vectors" +msgstr "" + +#: src/ch08-01-vectors.md:79 +msgid "" +"There are two ways to reference a value stored in a vector: via indexing or " +"by using the `get` method. In the following examples, we’ve annotated the " +"types of the values that are returned from these functions for extra clarity." +msgstr "" + +#: src/ch08-01-vectors.md:83 +msgid "" +"Listing 8-4 shows both methods of accessing a value in a vector, with " +"indexing syntax and the `get` method." +msgstr "" + +#: src/ch08-01-vectors.md:91 src/ch08-01-vectors.md:95 +msgid "\"The third element is {third}\"" +msgstr "" + +#: src/ch08-01-vectors.md:96 +msgid "\"There is no third element.\"" +msgstr "" + +#: src/ch08-01-vectors.md:101 +msgid "" +"Listing 8-4: Using indexing syntax and using the " +"`get` method to access an item in a vector" +msgstr "" + +#: src/ch08-01-vectors.md:104 +msgid "" +"Note a few details here. We use the index value of `2` to get the third " +"element because vectors are indexed by number, starting at zero. Using `&` " +"and `[]` gives us a reference to the element at the index value. When we use " +"the `get` method with the index passed as an argument, we get an " +"`Option<&T>` that we can use with `match`." +msgstr "" + +#: src/ch08-01-vectors.md:110 +msgid "" +"Rust provides these two ways to reference an element so you can choose how " +"the program behaves when you try to use an index value outside the range of " +"existing elements. As an example, let’s see what happens when we have a " +"vector of five elements and then we try to access an element at index 100 " +"with each technique, as shown in Listing 8-5." +msgstr "" + +#: src/ch08-01-vectors.md:125 +msgid "" +"Listing 8-5: Attempting to access the element at " +"index 100 in a vector containing five elements" +msgstr "" + +#: src/ch08-01-vectors.md:128 +msgid "" +"When we run this code, the first `[]` method will cause the program to panic " +"because it references a nonexistent element. This method is best used when " +"you want your program to crash if there’s an attempt to access an element " +"past the end of the vector." +msgstr "" + +#: src/ch08-01-vectors.md:133 +msgid "" +"When the `get` method is passed an index that is outside the vector, it " +"returns `None` without panicking. You would use this method if accessing an " +"element beyond the range of the vector may happen occasionally under normal " +"circumstances. Your code will then have logic to handle having either " +"`Some(&element)` or `None`, as discussed in Chapter 6. For example, the " +"index could be coming from a person entering a number. If they accidentally " +"enter a number that’s too large and the program gets a `None` value, you " +"could tell the user how many items are in the current vector and give them " +"another chance to enter a valid value. That would be more user-friendly than " +"crashing the program due to a typo!" +msgstr "" + +#: src/ch08-01-vectors.md:144 +msgid "" +"When the program has a valid reference, the borrow checker enforces the " +"ownership and borrowing rules (covered in Chapter 4) to ensure this " +"reference and any other references to the contents of the vector remain " +"valid. Recall the rule that states you can’t have mutable and immutable " +"references in the same scope. That rule applies in Listing 8-6, where we " +"hold an immutable reference to the first element in a vector and try to add " +"an element to the end. This program won’t work if we also try to refer to " +"that element later in the function." +msgstr "" + +#: src/ch08-01-vectors.md:161 +msgid "\"The first element is: {first}\"" +msgstr "" + +#: src/ch08-01-vectors.md:165 +msgid "" +"Listing 8-6: Attempting to add an element to a " +"vector while holding a reference to an item" +msgstr "" + +#: src/ch08-01-vectors.md:168 +msgid "Compiling this code will result in this error:" +msgstr "" + +#: src/ch08-01-vectors.md:170 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling collections v0.1.0 (file:///projects/collections)\n" +"error[E0502]: cannot borrow `v` as mutable because it is also borrowed as " +"immutable\n" +" --> src/main.rs:6:5\n" +" |\n" +"4 | let first = &v[0];\n" +" | - immutable borrow occurs here\n" +"5 |\n" +"6 | v.push(6);\n" +" | ^^^^^^^^^ mutable borrow occurs here\n" +"7 |\n" +"8 | println!(\"The first element is: {first}\");\n" +" | ------- immutable borrow later used " +"here\n" +"\n" +"For more information about this error, try `rustc --explain E0502`.\n" +"error: could not compile `collections` (bin \"collections\") due to 1 " +"previous error\n" +"```" +msgstr "" + +#: src/ch08-01-vectors.md:189 +msgid "" +"The code in Listing 8-6 might look like it should work: why should a " +"reference to the first element care about changes at the end of the vector? " +"This error is due to the way vectors work: because vectors put the values " +"next to each other in memory, adding a new element onto the end of the " +"vector might require allocating new memory and copying the old elements to " +"the new space, if there isn’t enough room to put all the elements next to " +"each other where the vector is currently stored. In that case, the reference " +"to the first element would be pointing to deallocated memory. The borrowing " +"rules prevent programs from ending up in that situation." +msgstr "" + +#: src/ch08-01-vectors.md:199 +msgid "" +"Note: For more on the implementation details of the `Vec` type, see [“The " +"Rustonomicon”](../nomicon/vec/vec.html)." +msgstr "" + +#: src/ch08-01-vectors.md:202 +msgid "Iterating Over the Values in a Vector" +msgstr "" + +#: src/ch08-01-vectors.md:204 +msgid "" +"To access each element in a vector in turn, we would iterate through all of " +"the elements rather than use indices to access one at a time. Listing 8-7 " +"shows how to use a `for` loop to get immutable references to each element in " +"a vector of `i32` values and print them." +msgstr "" + +#: src/ch08-01-vectors.md:213 +msgid "\"{i}\"" +msgstr "" + +#: src/ch08-01-vectors.md:218 +msgid "" +"Listing 8-7: Printing each element in a vector by " +"iterating over the elements using a `for` loop" +msgstr "" + +#: src/ch08-01-vectors.md:221 +msgid "" +"We can also iterate over mutable references to each element in a mutable " +"vector in order to make changes to all the elements. The `for` loop in " +"Listing 8-8 will add `50` to each element." +msgstr "" + +#: src/ch08-01-vectors.md:234 +msgid "" +"Listing 8-8: Iterating over mutable references to " +"elements in a vector" +msgstr "" + +#: src/ch08-01-vectors.md:237 +msgid "" +"To change the value that the mutable reference refers to, we have to use the " +"`*` dereference operator to get to the value in `i` before we can use the `" +"+=` operator. We’ll talk more about the dereference operator in the " +"[“Following the Pointer to the Value with the Dereference Operator”](ch15-02-" +"deref.html#following-the-pointer-to-the-value-with-the-dereference-" +"operator) section of Chapter 15." +msgstr "" + +#: src/ch08-01-vectors.md:243 +msgid "" +"Iterating over a vector, whether immutably or mutably, is safe because of " +"the borrow checker’s rules. If we attempted to insert or remove items in the " +"`for` loop bodies in Listing 8-7 and Listing 8-8, we would get a compiler " +"error similar to the one we got with the code in Listing 8-6. The reference " +"to the vector that the `for` loop holds prevents simultaneous modification " +"of the whole vector." +msgstr "" + +#: src/ch08-01-vectors.md:250 +msgid "Using an Enum to Store Multiple Types" +msgstr "" + +#: src/ch08-01-vectors.md:252 +msgid "" +"Vectors can only store values that are of the same type. This can be " +"inconvenient; there are definitely use cases for needing to store a list of " +"items of different types. Fortunately, the variants of an enum are defined " +"under the same enum type, so when we need one type to represent elements of " +"different types, we can define and use an enum!" +msgstr "" + +#: src/ch08-01-vectors.md:258 +msgid "" +"For example, say we want to get values from a row in a spreadsheet in which " +"some of the columns in the row contain integers, some floating-point " +"numbers, and some strings. We can define an enum whose variants will hold " +"the different value types, and all the enum variants will be considered the " +"same type: that of the enum. Then we can create a vector to hold that enum " +"and so, ultimately, hold different types. We’ve demonstrated this in Listing " +"8-9." +msgstr "" + +#: src/ch08-01-vectors.md:275 +msgid "\"blue\"" +msgstr "" + +#: src/ch08-01-vectors.md:281 +msgid "" +"Listing 8-9: Defining an `enum` to store values of " +"different types in one vector" +msgstr "" + +#: src/ch08-01-vectors.md:284 +msgid "" +"Rust needs to know what types will be in the vector at compile time so it " +"knows exactly how much memory on the heap will be needed to store each " +"element. We must also be explicit about what types are allowed in this " +"vector. If Rust allowed a vector to hold any type, there would be a chance " +"that one or more of the types would cause errors with the operations " +"performed on the elements of the vector. Using an enum plus a `match` " +"expression means that Rust will ensure at compile time that every possible " +"case is handled, as discussed in Chapter 6." +msgstr "" + +#: src/ch08-01-vectors.md:292 +msgid "" +"If you don’t know the exhaustive set of types a program will get at runtime " +"to store in a vector, the enum technique won’t work. Instead, you can use a " +"trait object, which we’ll cover in Chapter 17." +msgstr "" + +#: src/ch08-01-vectors.md:296 +msgid "" +"Now that we’ve discussed some of the most common ways to use vectors, be " +"sure to review [the API documentation](../std/vec/struct.Vec.html) for all of the many useful methods defined on `Vec` by the " +"standard library. For example, in addition to `push`, a `pop` method removes " +"and returns the last element." +msgstr "" + +#: src/ch08-01-vectors.md:301 +msgid "Dropping a Vector Drops Its Elements" +msgstr "" + +#: src/ch08-01-vectors.md:303 +msgid "" +"Like any other `struct`, a vector is freed when it goes out of scope, as " +"annotated in Listing 8-10." +msgstr "" + +#: src/ch08-01-vectors.md:311 +msgid "// do stuff with v\n" +msgstr "" + +#: src/ch08-01-vectors.md:312 +msgid "// <- v goes out of scope and is freed here\n" +msgstr "" + +#: src/ch08-01-vectors.md:316 +msgid "" +"Listing 8-10: Showing where the vector and its " +"elements are dropped" +msgstr "" + +#: src/ch08-01-vectors.md:319 +msgid "" +"When the vector gets dropped, all of its contents are also dropped, meaning " +"the integers it holds will be cleaned up. The borrow checker ensures that " +"any references to contents of a vector are only used while the vector itself " +"is valid." +msgstr "" + +#: src/ch08-01-vectors.md:324 +msgid "Let’s move on to the next collection type: `String`!" +msgstr "" + +#: src/ch08-02-strings.md:3 +msgid "" +"We talked about strings in Chapter 4, but we’ll look at them in more depth " +"now. New Rustaceans commonly get stuck on strings for a combination of three " +"reasons: Rust’s propensity for exposing possible errors, strings being a " +"more complicated data structure than many programmers give them credit for, " +"and UTF-8. These factors combine in a way that can seem difficult when " +"you’re coming from other programming languages." +msgstr "" + +#: src/ch08-02-strings.md:10 +msgid "" +"We discuss strings in the context of collections because strings are " +"implemented as a collection of bytes, plus some methods to provide useful " +"functionality when those bytes are interpreted as text. In this section, " +"we’ll talk about the operations on `String` that every collection type has, " +"such as creating, updating, and reading. We’ll also discuss the ways in " +"which `String` is different from the other collections, namely how indexing " +"into a `String` is complicated by the differences between how people and " +"computers interpret `String` data." +msgstr "" + +#: src/ch08-02-strings.md:19 +msgid "What Is a String?" +msgstr "" + +#: src/ch08-02-strings.md:21 +msgid "" +"We’ll first define what we mean by the term _string_. Rust has only one " +"string type in the core language, which is the string slice `str` that is " +"usually seen in its borrowed form `&str`. In Chapter 4, we talked about " +"_string slices_, which are references to some UTF-8 encoded string data " +"stored elsewhere. String literals, for example, are stored in the program’s " +"binary and are therefore string slices." +msgstr "" + +#: src/ch08-02-strings.md:28 +msgid "" +"The `String` type, which is provided by Rust’s standard library rather than " +"coded into the core language, is a growable, mutable, owned, UTF-8 encoded " +"string type. When Rustaceans refer to “strings” in Rust, they might be " +"referring to either the `String` or the string slice `&str` types, not just " +"one of those types. Although this section is largely about `String`, both " +"types are used heavily in Rust’s standard library, and both `String` and " +"string slices are UTF-8 encoded." +msgstr "" + +#: src/ch08-02-strings.md:36 +msgid "Creating a New String" +msgstr "" + +#: src/ch08-02-strings.md:38 +msgid "" +"Many of the same operations available with `Vec` are available with " +"`String` as well because `String` is actually implemented as a wrapper " +"around a vector of bytes with some extra guarantees, restrictions, and " +"capabilities. An example of a function that works the same way with `Vec` " +"and `String` is the `new` function to create an instance, shown in Listing " +"8-11." +msgstr "" + +#: src/ch08-02-strings.md:50 +msgid "" +"Listing 8-11: Creating a new, empty `String`" +msgstr "" + +#: src/ch08-02-strings.md:52 +msgid "" +"This line creates a new, empty string called `s`, into which we can then " +"load data. Often, we’ll have some initial data with which we want to start " +"the string. For that, we use the `to_string` method, which is available on " +"any type that implements the `Display` trait, as string literals do. Listing " +"8-12 shows two examples." +msgstr "" + +#: src/ch08-02-strings.md:60 src/ch08-02-strings.md:65 +#: src/ch08-02-strings.md:80 +msgid "\"initial contents\"" +msgstr "" + +#: src/ch08-02-strings.md:64 +msgid "// the method also works on a literal directly:\n" +msgstr "" + +#: src/ch08-02-strings.md:69 +msgid "" +"Listing 8-12: Using the `to_string` method to create " +"a `String` from a string literal" +msgstr "" + +#: src/ch08-02-strings.md:72 +msgid "This code creates a string containing `initial contents`." +msgstr "" + +#: src/ch08-02-strings.md:74 +msgid "" +"We can also use the function `String::from` to create a `String` from a " +"string literal. The code in Listing 8-13 is equivalent to the code in " +"Listing 8-12 that uses `to_string`." +msgstr "" + +#: src/ch08-02-strings.md:84 +msgid "" +"Listing 8-13: Using the `String::from` function to " +"create a `String` from a string literal" +msgstr "" + +#: src/ch08-02-strings.md:87 +msgid "" +"Because strings are used for so many things, we can use many different " +"generic APIs for strings, providing us with a lot of options. Some of them " +"can seem redundant, but they all have their place! In this case, `String::" +"from` and `to_string` do the same thing, so which one you choose is a matter " +"of style and readability." +msgstr "" + +#: src/ch08-02-strings.md:93 +msgid "" +"Remember that strings are UTF-8 encoded, so we can include any properly " +"encoded data in them, as shown in Listing 8-14." +msgstr "" + +#: src/ch08-02-strings.md:98 src/ch08-02-strings.md:311 +#: src/ch08-02-strings.md:332 +msgid "\"السلام عليكم\"" +msgstr "" + +#: src/ch08-02-strings.md:99 src/ch08-02-strings.md:312 +#: src/ch08-02-strings.md:333 +msgid "\"Dobrý den\"" +msgstr "" + +#: src/ch08-02-strings.md:100 src/ch08-02-strings.md:313 +#: src/ch08-02-strings.md:334 src/ch10-01-syntax.md:413 +msgid "\"Hello\"" +msgstr "" + +#: src/ch08-02-strings.md:101 src/ch08-02-strings.md:314 +#: src/ch08-02-strings.md:335 +msgid "\"שלום\"" +msgstr "" + +#: src/ch08-02-strings.md:102 src/ch08-02-strings.md:315 +#: src/ch08-02-strings.md:336 +msgid "\"नमस्ते\"" +msgstr "" + +#: src/ch08-02-strings.md:103 src/ch08-02-strings.md:316 +#: src/ch08-02-strings.md:337 +msgid "\"こんにちは\"" +msgstr "" + +#: src/ch08-02-strings.md:104 src/ch08-02-strings.md:317 +#: src/ch08-02-strings.md:338 +msgid "\"안녕하세요\"" +msgstr "" + +#: src/ch08-02-strings.md:105 src/ch08-02-strings.md:318 +#: src/ch08-02-strings.md:339 +msgid "\"你好\"" +msgstr "" + +#: src/ch08-02-strings.md:106 src/ch08-02-strings.md:319 +#: src/ch08-02-strings.md:340 +msgid "\"Olá\"" +msgstr "" + +#: src/ch08-02-strings.md:107 src/ch08-02-strings.md:320 +#: src/ch08-02-strings.md:341 src/ch08-02-strings.md:354 +#: src/ch08-02-strings.md:423 +msgid "\"Здравствуйте\"" +msgstr "" + +#: src/ch08-02-strings.md:108 src/ch08-02-strings.md:321 +#: src/ch08-02-strings.md:342 +msgid "\"Hola\"" +msgstr "" + +#: src/ch08-02-strings.md:112 +msgid "" +"Listing 8-14: Storing greetings in different " +"languages in strings" +msgstr "" + +#: src/ch08-02-strings.md:115 +msgid "All of these are valid `String` values." +msgstr "" + +#: src/ch08-02-strings.md:117 +msgid "Updating a String" +msgstr "" + +#: src/ch08-02-strings.md:119 +msgid "" +"A `String` can grow in size and its contents can change, just like the " +"contents of a `Vec`, if you push more data into it. In addition, you can " +"conveniently use the `+` operator or the `format!` macro to concatenate " +"`String` values." +msgstr "" + +#: src/ch08-02-strings.md:123 +msgid "Appending to a String with `push_str` and `push`" +msgstr "" + +#: src/ch08-02-strings.md:125 +msgid "" +"We can grow a `String` by using the `push_str` method to append a string " +"slice, as shown in Listing 8-15." +msgstr "" + +#: src/ch08-02-strings.md:130 src/ch08-02-strings.md:145 +#: src/appendix-01-keywords.md:119 +msgid "\"foo\"" +msgstr "" + +#: src/ch08-02-strings.md:131 src/ch08-02-strings.md:146 +msgid "\"bar\"" +msgstr "" + +#: src/ch08-02-strings.md:135 +msgid "" +"Listing 8-15: Appending a string slice to a `String` " +"using the `push_str` method" +msgstr "" + +#: src/ch08-02-strings.md:138 +msgid "" +"After these two lines, `s` will contain `foobar`. The `push_str` method " +"takes a string slice because we don’t necessarily want to take ownership of " +"the parameter. For example, in the code in Listing 8-16, we want to be able " +"to use `s2` after appending its contents to `s1`." +msgstr "" + +#: src/ch08-02-strings.md:148 +msgid "\"s2 is {s2}\"" +msgstr "" + +#: src/ch08-02-strings.md:152 +msgid "" +"Listing 8-16: Using a string slice after appending " +"its contents to a `String`" +msgstr "" + +#: src/ch08-02-strings.md:155 +msgid "" +"If the `push_str` method took ownership of `s2`, we wouldn’t be able to " +"print its value on the last line. However, this code works as we’d expect!" +msgstr "" + +#: src/ch08-02-strings.md:158 +msgid "" +"The `push` method takes a single character as a parameter and adds it to the " +"`String`. Listing 8-17 adds the letter _l_ to a `String` using the `push` " +"method." +msgstr "" + +#: src/ch08-02-strings.md:164 +msgid "\"lo\"" +msgstr "" + +#: src/ch08-02-strings.md:165 +msgid "'l'" +msgstr "" + +#: src/ch08-02-strings.md:169 +msgid "" +"Listing 8-17: Adding one character to a `String` " +"value using `push`" +msgstr "" + +#: src/ch08-02-strings.md:172 +msgid "As a result, `s` will contain `lol`." +msgstr "" + +#: src/ch08-02-strings.md:174 +msgid "Concatenation with the `+` Operator or the `format!` Macro" +msgstr "" + +#: src/ch08-02-strings.md:176 +msgid "" +"Often, you’ll want to combine two existing strings. One way to do so is to " +"use the `+` operator, as shown in Listing 8-18." +msgstr "" + +#: src/ch08-02-strings.md:181 +msgid "\"Hello, \"" +msgstr "" + +#: src/ch08-02-strings.md:182 +msgid "\"world!\"" +msgstr "" + +#: src/ch08-02-strings.md:183 +msgid "// note s1 has been moved here and can no longer be used\n" +msgstr "" + +#: src/ch08-02-strings.md:187 +msgid "" +"Listing 8-18: Using the `+` operator to combine two " +"`String` values into a new `String` value" +msgstr "" + +#: src/ch08-02-strings.md:190 +msgid "" +"The string `s3` will contain `Hello, world!`. The reason `s1` is no longer " +"valid after the addition, and the reason we used a reference to `s2`, has to " +"do with the signature of the method that’s called when we use the `+` " +"operator. The `+` operator uses the `add` method, whose signature looks " +"something like this:" +msgstr "" + +#: src/ch08-02-strings.md:200 +msgid "" +"In the standard library, you’ll see `add` defined using generics and " +"associated types. Here, we’ve substituted in concrete types, which is what " +"happens when we call this method with `String` values. We’ll discuss " +"generics in Chapter 10. This signature gives us the clues we need in order " +"to understand the tricky bits of the `+` operator." +msgstr "" + +#: src/ch08-02-strings.md:206 +msgid "" +"First, `s2` has an `&`, meaning that we’re adding a _reference_ of the " +"second string to the first string. This is because of the `s` parameter in " +"the `add` function: we can only add a `&str` to a `String`; we can’t add two " +"`String` values together. But wait—the type of `&s2` is `&String`, not " +"`&str`, as specified in the second parameter to `add`. So why does Listing " +"8-18 compile?" +msgstr "" + +#: src/ch08-02-strings.md:212 +msgid "" +"The reason we’re able to use `&s2` in the call to `add` is that the compiler " +"can _coerce_ the `&String` argument into a `&str`. When we call the `add` " +"method, Rust uses a _deref coercion_, which here turns `&s2` into `&s2[..]`. " +"We’ll discuss deref coercion in more depth in Chapter 15. Because `add` does " +"not take ownership of the `s` parameter, `s2` will still be a valid `String` " +"after this operation." +msgstr "" + +#: src/ch08-02-strings.md:219 +msgid "" +"Second, we can see in the signature that `add` takes ownership of `self` " +"because `self` does _not_ have an `&`. This means `s1` in Listing 8-18 will " +"be moved into the `add` call and will no longer be valid after that. So, " +"although `let s3 = s1 + &s2;` looks like it will copy both strings and " +"create a new one, this statement actually takes ownership of `s1`, appends a " +"copy of the contents of `s2`, and then returns ownership of the result. In " +"other words, it looks like it’s making a lot of copies, but it isn’t; the " +"implementation is more efficient than copying." +msgstr "" + +#: src/ch08-02-strings.md:228 +msgid "" +"If we need to concatenate multiple strings, the behavior of the `+` operator " +"gets unwieldy:" +msgstr "" + +#: src/ch08-02-strings.md:233 src/ch08-02-strings.md:247 +msgid "\"tic\"" +msgstr "" + +#: src/ch08-02-strings.md:234 src/ch08-02-strings.md:248 +msgid "\"tac\"" +msgstr "" + +#: src/ch08-02-strings.md:235 src/ch08-02-strings.md:249 +msgid "\"toe\"" +msgstr "" + +#: src/ch08-02-strings.md:237 +msgid "\"-\"" +msgstr "" + +#: src/ch08-02-strings.md:241 +msgid "" +"At this point, `s` will be `tic-tac-toe`. With all of the `+` and `\"` " +"characters, it’s difficult to see what’s going on. For combining strings in " +"more complicated ways, we can instead use the `format!` macro:" +msgstr "" + +#: src/ch08-02-strings.md:251 +msgid "\"{s1}-{s2}-{s3}\"" +msgstr "" + +#: src/ch08-02-strings.md:255 +msgid "" +"This code also sets `s` to `tic-tac-toe`. The `format!` macro works like " +"`println!`, but instead of printing the output to the screen, it returns a " +"`String` with the contents. The version of the code using `format!` is much " +"easier to read, and the code generated by the `format!` macro uses " +"references so that this call doesn’t take ownership of any of its parameters." +msgstr "" + +#: src/ch08-02-strings.md:261 +msgid "Indexing into Strings" +msgstr "" + +#: src/ch08-02-strings.md:263 +msgid "" +"In many other programming languages, accessing individual characters in a " +"string by referencing them by index is a valid and common operation. " +"However, if you try to access parts of a `String` using indexing syntax in " +"Rust, you’ll get an error. Consider the invalid code in Listing 8-19." +msgstr "" + +#: src/ch08-02-strings.md:275 +msgid "" +"Listing 8-19: Attempting to use indexing syntax with " +"a String" +msgstr "" + +#: src/ch08-02-strings.md:278 +msgid "This code will result in the following error:" +msgstr "" + +#: src/ch08-02-strings.md:280 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling collections v0.1.0 (file:///projects/collections)\n" +"error[E0277]: the type `str` cannot be indexed by `{integer}`\n" +" --> src/main.rs:3:16\n" +" |\n" +"3 | let h = s1[0];\n" +" | ^ string indices are ranges of `usize`\n" +" |\n" +" = help: the trait `SliceIndex` is not implemented for `{integer}`, " +"which is required by `String: Index<_>`\n" +" = note: you can use `.chars().nth()` or `.bytes().nth()`\n" +" for more information, see chapter 8 in The Book: \n" +" = help: the trait `SliceIndex<[_]>` is implemented for `usize`\n" +" = help: for that trait implementation, expected `[_]`, found `str`\n" +" = note: required for `String` to implement `Index<{integer}>`\n" +"\n" +"For more information about this error, try `rustc --explain E0277`.\n" +"error: could not compile `collections` (bin \"collections\") due to 1 " +"previous error\n" +"```" +msgstr "" + +#: src/ch08-02-strings.md:300 +msgid "" +"The error and the note tell the story: Rust strings don’t support indexing. " +"But why not? To answer that question, we need to discuss how Rust stores " +"strings in memory." +msgstr "" + +#: src/ch08-02-strings.md:304 +msgid "Internal Representation" +msgstr "" + +#: src/ch08-02-strings.md:306 +msgid "" +"A `String` is a wrapper over a `Vec`. Let’s look at some of our properly " +"encoded UTF-8 example strings from Listing 8-14. First, this one:" +msgstr "" + +#: src/ch08-02-strings.md:325 +msgid "" +"In this case, `len` will be `4`, which means the vector storing the string `" +"\"Hola\"` is 4 bytes long. Each of these letters takes one byte when encoded " +"in UTF-8. The following line, however, may surprise you (note that this " +"string begins with the capital Cyrillic letter _Ze_, not the number 3):" +msgstr "" + +#: src/ch08-02-strings.md:346 +msgid "" +"If you were asked how long the string is, you might say 12. In fact, Rust’s " +"answer is 24: that’s the number of bytes it takes to encode “Здравствуйте” " +"in UTF-8, because each Unicode scalar value in that string takes 2 bytes of " +"storage. Therefore, an index into the string’s bytes will not always " +"correlate to a valid Unicode scalar value. To demonstrate, consider this " +"invalid Rust code:" +msgstr "" + +#: src/ch08-02-strings.md:358 +msgid "" +"You already know that `answer` will not be `З`, the first letter. When " +"encoded in UTF-8, the first byte of `З` is `208` and the second is `151`, so " +"it would seem that `answer` should in fact be `208`, but `208` is not a " +"valid character on its own. Returning `208` is likely not what a user would " +"want if they asked for the first letter of this string; however, that’s the " +"only data that Rust has at byte index 0. Users generally don’t want the byte " +"value returned, even if the string contains only Latin letters: if `&\"hello" +"\"[0]` were valid code that returned the byte value, it would return `104`, " +"not `h`." +msgstr "" + +#: src/ch08-02-strings.md:367 +msgid "" +"The answer, then, is that to avoid returning an unexpected value and causing " +"bugs that might not be discovered immediately, Rust doesn’t compile this " +"code at all and prevents misunderstandings early in the development process." +msgstr "" + +#: src/ch08-02-strings.md:371 +msgid "Bytes and Scalar Values and Grapheme Clusters! Oh My!" +msgstr "" + +#: src/ch08-02-strings.md:373 +msgid "" +"Another point about UTF-8 is that there are actually three relevant ways to " +"look at strings from Rust’s perspective: as bytes, scalar values, and " +"grapheme clusters (the closest thing to what we would call _letters_)." +msgstr "" + +#: src/ch08-02-strings.md:377 +msgid "" +"If we look at the Hindi word “नमस्ते” written in the Devanagari script, it is " +"stored as a vector of `u8` values that looks like this:" +msgstr "" + +#: src/ch08-02-strings.md:385 +msgid "" +"That’s 18 bytes and is how computers ultimately store this data. If we look " +"at them as Unicode scalar values, which are what Rust’s `char` type is, " +"those bytes look like this:" +msgstr "" + +#: src/ch08-02-strings.md:393 +msgid "" +"There are six `char` values here, but the fourth and sixth are not letters: " +"they’re diacritics that don’t make sense on their own. Finally, if we look " +"at them as grapheme clusters, we’d get what a person would call the four " +"letters that make up the Hindi word:" +msgstr "" + +#: src/ch08-02-strings.md:398 +msgid "" +"```text\n" +"[\"न\", \"म\", \"स्\", \"ते\"]\n" +"```" +msgstr "" + +#: src/ch08-02-strings.md:402 +msgid "" +"Rust provides different ways of interpreting the raw string data that " +"computers store so that each program can choose the interpretation it needs, " +"no matter what human language the data is in." +msgstr "" + +#: src/ch08-02-strings.md:406 +msgid "" +"A final reason Rust doesn’t allow us to index into a `String` to get a " +"character is that indexing operations are expected to always take constant " +"time (O(1)). But it isn’t possible to guarantee that performance with a " +"`String`, because Rust would have to walk through the contents from the " +"beginning to the index to determine how many valid characters there were." +msgstr "" + +#: src/ch08-02-strings.md:412 +msgid "Slicing Strings" +msgstr "" + +#: src/ch08-02-strings.md:414 +msgid "" +"Indexing into a string is often a bad idea because it’s not clear what the " +"return type of the string-indexing operation should be: a byte value, a " +"character, a grapheme cluster, or a string slice. If you really need to use " +"indices to create string slices, therefore, Rust asks you to be more " +"specific." +msgstr "" + +#: src/ch08-02-strings.md:419 +msgid "" +"Rather than indexing using `[]` with a single number, you can use `[]` with " +"a range to create a string slice containing particular bytes:" +msgstr "" + +#: src/ch08-02-strings.md:428 +msgid "" +"Here, `s` will be a `&str` that contains the first four bytes of the string. " +"Earlier, we mentioned that each of these characters was two bytes, which " +"means `s` will be `Зд`." +msgstr "" + +#: src/ch08-02-strings.md:432 +msgid "" +"If we were to try to slice only part of a character’s bytes with something " +"like `&hello[0..1]`, Rust would panic at runtime in the same way as if an " +"invalid index were accessed in a vector:" +msgstr "" + +#: src/ch08-02-strings.md:436 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling collections v0.1.0 (file:///projects/collections)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.43s\n" +" Running `target/debug/collections`\n" +"thread 'main' panicked at src/main.rs:4:19:\n" +"byte index 1 is not a char boundary; it is inside 'З' (bytes 0..2) of " +"`Здравствуйте`\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"```" +msgstr "" + +#: src/ch08-02-strings.md:446 +msgid "" +"You should use caution when creating string slices with ranges, because " +"doing so can crash your program." +msgstr "" + +#: src/ch08-02-strings.md:449 +msgid "Methods for Iterating Over Strings" +msgstr "" + +#: src/ch08-02-strings.md:451 +msgid "" +"The best way to operate on pieces of strings is to be explicit about whether " +"you want characters or bytes. For individual Unicode scalar values, use the " +"`chars` method. Calling `chars` on “Зд” separates out and returns two values " +"of type `char`, and you can iterate over the result to access each element:" +msgstr "" + +#: src/ch08-02-strings.md:457 src/ch08-02-strings.md:473 +msgid "\"Зд\"" +msgstr "" + +#: src/ch08-02-strings.md:458 +msgid "\"{c}\"" +msgstr "" + +#: src/ch08-02-strings.md:462 src/ch16-03-shared-state.md:332 +msgid "This code will print the following:" +msgstr "" + +#: src/ch08-02-strings.md:469 +msgid "" +"Alternatively, the `bytes` method returns each raw byte, which might be " +"appropriate for your domain:" +msgstr "" + +#: src/ch08-02-strings.md:474 +msgid "\"{b}\"" +msgstr "" + +#: src/ch08-02-strings.md:478 +msgid "This code will print the four bytes that make up this string:" +msgstr "" + +#: src/ch08-02-strings.md:487 +msgid "" +"But be sure to remember that valid Unicode scalar values may be made up of " +"more than one byte." +msgstr "" + +#: src/ch08-02-strings.md:490 +msgid "" +"Getting grapheme clusters from strings, as with the Devanagari script, is " +"complex, so this functionality is not provided by the standard library. " +"Crates are available on [crates.io](https://crates.io/) if " +"this is the functionality you need." +msgstr "" + +#: src/ch08-02-strings.md:495 +msgid "Strings Are Not So Simple" +msgstr "" + +#: src/ch08-02-strings.md:497 +msgid "" +"To summarize, strings are complicated. Different programming languages make " +"different choices about how to present this complexity to the programmer. " +"Rust has chosen to make the correct handling of `String` data the default " +"behavior for all Rust programs, which means programmers have to put more " +"thought into handling UTF-8 data up front. This trade-off exposes more of " +"the complexity of strings than is apparent in other programming languages, " +"but it prevents you from having to handle errors involving non-ASCII " +"characters later in your development life cycle." +msgstr "" + +#: src/ch08-02-strings.md:506 +msgid "" +"The good news is that the standard library offers a lot of functionality " +"built off the `String` and `&str` types to help handle these complex " +"situations correctly. Be sure to check out the documentation for useful " +"methods like `contains` for searching in a string and `replace` for " +"substituting parts of a string with another string." +msgstr "" + +#: src/ch08-02-strings.md:512 +msgid "Let’s switch to something a bit less complex: hash maps!" +msgstr "" + +#: src/ch08-03-hash-maps.md:3 +msgid "" +"The last of our common collections is the _hash map_. The type `HashMap` stores a mapping of keys of type `K` to values of type `V` using a " +"_hashing function_, which determines how it places these keys and values " +"into memory. Many programming languages support this kind of data structure, " +"but they often use a different name, such as _hash_, _map_, _object_, _hash " +"table_, _dictionary_, or _associative array_, just to name a few." +msgstr "" + +#: src/ch08-03-hash-maps.md:10 +msgid "" +"Hash maps are useful when you want to look up data not by using an index, as " +"you can with vectors, but by using a key that can be of any type. For " +"example, in a game, you could keep track of each team’s score in a hash map " +"in which each key is a team’s name and the values are each team’s score. " +"Given a team name, you can retrieve its score." +msgstr "" + +#: src/ch08-03-hash-maps.md:16 +msgid "" +"We’ll go over the basic API of hash maps in this section, but many more " +"goodies are hiding in the functions defined on `HashMap` by the " +"standard library. As always, check the standard library documentation for " +"more information." +msgstr "" + +#: src/ch08-03-hash-maps.md:20 +msgid "Creating a New Hash Map" +msgstr "" + +#: src/ch08-03-hash-maps.md:22 +msgid "" +"One way to create an empty hash map is to use `new` and to add elements with " +"`insert`. In Listing 8-20, we’re keeping track of the scores of two teams " +"whose names are _Blue_ and _Yellow_. The Blue team starts with 10 points, " +"and the Yellow team starts with 50." +msgstr "" + +#: src/ch08-03-hash-maps.md:33 src/ch08-03-hash-maps.md:63 +#: src/ch08-03-hash-maps.md:66 src/ch08-03-hash-maps.md:90 +#: src/ch08-03-hash-maps.md:117 src/ch08-03-hash-maps.md:167 +#: src/ch08-03-hash-maps.md:168 src/ch08-03-hash-maps.md:202 +#: src/ch08-03-hash-maps.md:205 +msgid "\"Blue\"" +msgstr "" + +#: src/ch08-03-hash-maps.md:34 src/ch08-03-hash-maps.md:64 +#: src/ch08-03-hash-maps.md:91 src/ch08-03-hash-maps.md:204 +msgid "\"Yellow\"" +msgstr "" + +#: src/ch08-03-hash-maps.md:38 +msgid "" +"Listing 8-20: Creating a new hash map and inserting " +"some keys and values" +msgstr "" + +#: src/ch08-03-hash-maps.md:41 +msgid "" +"Note that we need to first `use` the `HashMap` from the collections portion " +"of the standard library. Of our three common collections, this one is the " +"least often used, so it’s not included in the features brought into scope " +"automatically in the prelude. Hash maps also have less support from the " +"standard library; there’s no built-in macro to construct them, for example." +msgstr "" + +#: src/ch08-03-hash-maps.md:47 +msgid "" +"Just like vectors, hash maps store their data on the heap. This `HashMap` " +"has keys of type `String` and values of type `i32`. Like vectors, hash maps " +"are homogeneous: all of the keys must have the same type, and all of the " +"values must have the same type." +msgstr "" + +#: src/ch08-03-hash-maps.md:52 +msgid "Accessing Values in a Hash Map" +msgstr "" + +#: src/ch08-03-hash-maps.md:54 +msgid "" +"We can get a value out of the hash map by providing its key to the `get` " +"method, as shown in Listing 8-21." +msgstr "" + +#: src/ch08-03-hash-maps.md:71 +msgid "" +"Listing 8-21: Accessing the score for the Blue team " +"stored in the hash map" +msgstr "" + +#: src/ch08-03-hash-maps.md:74 +msgid "" +"Here, `score` will have the value that’s associated with the Blue team, and " +"the result will be `10`. The `get` method returns an `Option<&V>`; if " +"there’s no value for that key in the hash map, `get` will return `None`. " +"This program handles the `Option` by calling `copied` to get an " +"`Option` rather than an `Option<&i32>`, then `unwrap_or` to set `score` " +"to zero if `scores` doesn’t have an entry for the key." +msgstr "" + +#: src/ch08-03-hash-maps.md:81 +msgid "" +"We can iterate over each key–value pair in a hash map in a similar manner as " +"we do with vectors, using a `for` loop:" +msgstr "" + +#: src/ch08-03-hash-maps.md:94 +msgid "\"{key}: {value}\"" +msgstr "" + +#: src/ch08-03-hash-maps.md:99 +msgid "This code will print each pair in an arbitrary order:" +msgstr "" + +#: src/ch08-03-hash-maps.md:106 +msgid "Hash Maps and Ownership" +msgstr "" + +#: src/ch08-03-hash-maps.md:108 +msgid "" +"For types that implement the `Copy` trait, like `i32`, the values are copied " +"into the hash map. For owned values like `String`, the values will be moved " +"and the hash map will be the owner of those values, as demonstrated in " +"Listing 8-22." +msgstr "" + +#: src/ch08-03-hash-maps.md:116 +msgid "\"Favorite color\"" +msgstr "" + +#: src/ch08-03-hash-maps.md:121 +msgid "" +"// field_name and field_value are invalid at this point, try using them and\n" +" // see what compiler error you get!\n" +msgstr "" + +#: src/ch08-03-hash-maps.md:126 +msgid "" +"Listing 8-22: Showing that keys and values are owned " +"by the hash map once they’re inserted" +msgstr "" + +#: src/ch08-03-hash-maps.md:129 +msgid "" +"We aren’t able to use the variables `field_name` and `field_value` after " +"they’ve been moved into the hash map with the call to `insert`." +msgstr "" + +#: src/ch08-03-hash-maps.md:132 +msgid "" +"If we insert references to values into the hash map, the values won’t be " +"moved into the hash map. The values that the references point to must be " +"valid for at least as long as the hash map is valid. We’ll talk more about " +"these issues in the [“Validating References with Lifetimes”](ch10-03-" +"lifetime-syntax.html#validating-references-with-lifetimes) " +"section in Chapter 10." +msgstr "" + +#: src/ch08-03-hash-maps.md:139 +msgid "Updating a Hash Map" +msgstr "" + +#: src/ch08-03-hash-maps.md:141 +msgid "" +"Although the number of key and value pairs is growable, each unique key can " +"only have one value associated with it at a time (but not vice versa: for " +"example, both the Blue team and the Yellow team could have the value `10` " +"stored in the `scores` hash map)." +msgstr "" + +#: src/ch08-03-hash-maps.md:146 +msgid "" +"When you want to change the data in a hash map, you have to decide how to " +"handle the case when a key already has a value assigned. You could replace " +"the old value with the new value, completely disregarding the old value. You " +"could keep the old value and ignore the new value, only adding the new value " +"if the key _doesn’t_ already have a value. Or you could combine the old " +"value and the new value. Let’s look at how to do each of these!" +msgstr "" + +#: src/ch08-03-hash-maps.md:153 +msgid "Overwriting a Value" +msgstr "" + +#: src/ch08-03-hash-maps.md:155 +msgid "" +"If we insert a key and a value into a hash map and then insert that same key " +"with a different value, the value associated with that key will be replaced. " +"Even though the code in Listing 8-23 calls `insert` twice, the hash map will " +"only contain one key–value pair because we’re inserting the value for the " +"Blue team’s key both times." +msgstr "" + +#: src/ch08-03-hash-maps.md:170 src/ch08-03-hash-maps.md:207 +msgid "\"{scores:?}\"" +msgstr "" + +#: src/ch08-03-hash-maps.md:174 +msgid "" +"Listing 8-23: Replacing a value stored with a " +"particular key" +msgstr "" + +#: src/ch08-03-hash-maps.md:177 +msgid "" +"This code will print `{\"Blue\": 25}`. The original value of `10` has been " +"overwritten." +msgstr "" + +#: src/ch08-03-hash-maps.md:181 +msgid "" +msgstr "" + +#: src/ch08-03-hash-maps.md:183 +msgid "Adding a Key and Value Only If a Key Isn’t Present" +msgstr "" + +#: src/ch08-03-hash-maps.md:185 +msgid "" +"It’s common to check whether a particular key already exists in the hash map " +"with a value and then to take the following actions: if the key does exist " +"in the hash map, the existing value should remain the way it is; if the key " +"doesn’t exist, insert it and a value for it." +msgstr "" + +#: src/ch08-03-hash-maps.md:190 +msgid "" +"Hash maps have a special API for this called `entry` that takes the key you " +"want to check as a parameter. The return value of the `entry` method is an " +"enum called `Entry` that represents a value that might or might not exist. " +"Let’s say we want to check whether the key for the Yellow team has a value " +"associated with it. If it doesn’t, we want to insert the value `50`, and the " +"same for the Blue team. Using the `entry` API, the code looks like Listing " +"8-24." +msgstr "" + +#: src/ch08-03-hash-maps.md:211 +msgid "" +"Listing 8-24: Using the `entry` method to only " +"insert if the key does not already have a value" +msgstr "" + +#: src/ch08-03-hash-maps.md:214 +msgid "" +"The `or_insert` method on `Entry` is defined to return a mutable reference " +"to the value for the corresponding `Entry` key if that key exists, and if " +"not, it inserts the parameter as the new value for this key and returns a " +"mutable reference to the new value. This technique is much cleaner than " +"writing the logic ourselves and, in addition, plays more nicely with the " +"borrow checker." +msgstr "" + +#: src/ch08-03-hash-maps.md:220 +msgid "" +"Running the code in Listing 8-24 will print `{\"Yellow\": 50, \"Blue\": 10}" +"`. The first call to `entry` will insert the key for the Yellow team with " +"the value `50` because the Yellow team doesn’t have a value already. The " +"second call to `entry` will not change the hash map because the Blue team " +"already has the value `10`." +msgstr "" + +#: src/ch08-03-hash-maps.md:226 +msgid "Updating a Value Based on the Old Value" +msgstr "" + +#: src/ch08-03-hash-maps.md:228 +msgid "" +"Another common use case for hash maps is to look up a key’s value and then " +"update it based on the old value. For instance, Listing 8-25 shows code that " +"counts how many times each word appears in some text. We use a hash map with " +"the words as keys and increment the value to keep track of how many times " +"we’ve seen that word. If it’s the first time we’ve seen a word, we’ll first " +"insert the value `0`." +msgstr "" + +#: src/ch08-03-hash-maps.md:239 +msgid "\"hello world wonderful world\"" +msgstr "" + +#: src/ch08-03-hash-maps.md:248 +msgid "\"{map:?}\"" +msgstr "" + +#: src/ch08-03-hash-maps.md:252 +msgid "" +"Listing 8-25: Counting occurrences of words using a " +"hash map that stores words and counts" +msgstr "" + +#: src/ch08-03-hash-maps.md:255 +msgid "" +"This code will print `{\"world\": 2, \"hello\": 1, \"wonderful\": 1}`. You " +"might see the same key–value pairs printed in a different order: recall from " +"the [“Accessing Values in a Hash Map”](#accessing-values-in-a-hash-map) section that iterating over a hash map happens in an arbitrary " +"order." +msgstr "" + +#: src/ch08-03-hash-maps.md:260 +msgid "" +"The `split_whitespace` method returns an iterator over subslices, separated " +"by whitespace, of the value in `text`. The `or_insert` method returns a " +"mutable reference (`&mut V`) to the value for the specified key. Here, we " +"store that mutable reference in the `count` variable, so in order to assign " +"to that value, we must first dereference `count` using the asterisk (`*`). " +"The mutable reference goes out of scope at the end of the `for` loop, so all " +"of these changes are safe and allowed by the borrowing rules." +msgstr "" + +#: src/ch08-03-hash-maps.md:268 +msgid "Hashing Functions" +msgstr "" + +#: src/ch08-03-hash-maps.md:270 +msgid "" +"By default, `HashMap` uses a hashing function called _SipHash_ that can " +"provide resistance to denial-of-service (DoS) attacks involving hash " +"tables[^siphash]. This is not the fastest hashing algorithm " +"available, but the trade-off for better security that comes with the drop in " +"performance is worth it. If you profile your code and find that the default " +"hash function is too slow for your purposes, you can switch to another " +"function by specifying a different hasher. A _hasher_ is a type that " +"implements the `BuildHasher` trait. We’ll talk about traits and how to " +"implement them in [Chapter 10](ch10-02-traits.html). You " +"don’t necessarily have to implement your own hasher from scratch; [crates.io]" +"(https://crates.io/) has libraries shared by other Rust users " +"that provide hashers implementing many common hashing algorithms." +msgstr "" + +#: src/ch08-03-hash-maps.md:283 +msgid "" +"[https://en.wikipedia.org/wiki/SipHash](https://en.wikipedia.org/wiki/" +"SipHash)" +msgstr "" + +#: src/ch08-03-hash-maps.md:287 +msgid "" +"Vectors, strings, and hash maps will provide a large amount of functionality " +"necessary in programs when you need to store, access, and modify data. Here " +"are some exercises you should now be equipped to solve:" +msgstr "" + +#: src/ch08-03-hash-maps.md:291 +msgid "" +"Given a list of integers, use a vector and return the median (when sorted, " +"the value in the middle position) and mode (the value that occurs most " +"often; a hash map will be helpful here) of the list." +msgstr "" + +#: src/ch08-03-hash-maps.md:294 +msgid "" +"Convert strings to pig latin. The first consonant of each word is moved to " +"the end of the word and _ay_ is added, so _first_ becomes _irst-fay_. Words " +"that start with a vowel have _hay_ added to the end instead (_apple_ becomes " +"_apple-hay_). Keep in mind the details about UTF-8 encoding!" +msgstr "" + +#: src/ch08-03-hash-maps.md:298 +msgid "" +"Using a hash map and vectors, create a text interface to allow a user to add " +"employee names to a department in a company; for example, “Add Sally to " +"Engineering” or “Add Amir to Sales.” Then let the user retrieve a list of " +"all people in a department or all people in the company by department, " +"sorted alphabetically." +msgstr "" + +#: src/ch08-03-hash-maps.md:304 +msgid "" +"The standard library API documentation describes methods that vectors, " +"strings, and hash maps have that will be helpful for these exercises!" +msgstr "" + +#: src/ch08-03-hash-maps.md:307 +msgid "" +"We’re getting into more complex programs in which operations can fail, so " +"it’s a perfect time to discuss error handling. We’ll do that next!" +msgstr "" + +#: src/ch09-00-error-handling.md:3 +msgid "" +"Errors are a fact of life in software, so Rust has a number of features for " +"handling situations in which something goes wrong. In many cases, Rust " +"requires you to acknowledge the possibility of an error and take some action " +"before your code will compile. This requirement makes your program more " +"robust by ensuring that you’ll discover errors and handle them appropriately " +"before you’ve deployed your code to production!" +msgstr "" + +#: src/ch09-00-error-handling.md:10 +msgid "" +"Rust groups errors into two major categories: _recoverable_ and " +"_unrecoverable_ errors. For a recoverable error, such as a _file not found_ " +"error, we most likely just want to report the problem to the user and retry " +"the operation. Unrecoverable errors are always symptoms of bugs, such as " +"trying to access a location beyond the end of an array, and so we want to " +"immediately stop the program." +msgstr "" + +#: src/ch09-00-error-handling.md:17 +msgid "" +"Most languages don’t distinguish between these two kinds of errors and " +"handle both in the same way, using mechanisms such as exceptions. Rust " +"doesn’t have exceptions. Instead, it has the type `Result` for " +"recoverable errors and the `panic!` macro that stops execution when the " +"program encounters an unrecoverable error. This chapter covers calling " +"`panic!` first and then talks about returning `Result` values. " +"Additionally, we’ll explore considerations when deciding whether to try to " +"recover from an error or to stop execution." +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:3 +msgid "" +"Sometimes bad things happen in your code, and there’s nothing you can do " +"about it. In these cases, Rust has the `panic!` macro. There are two ways to " +"cause a panic in practice: by taking an action that causes our code to panic " +"(such as accessing an array past the end) or by explicitly calling the " +"`panic!` macro. In both cases, we cause a panic in our program. By default, " +"these panics will print a failure message, unwind, clean up the stack, and " +"quit. Via an environment variable, you can also have Rust display the call " +"stack when a panic occurs to make it easier to track down the source of the " +"panic." +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:12 +msgid "Unwinding the Stack or Aborting in Response to a Panic" +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:14 +msgid "" +"By default, when a panic occurs the program starts _unwinding_, which means " +"Rust walks back up the stack and cleans up the data from each function it " +"encounters. However, walking back and cleaning up is a lot of work. Rust, " +"therefore, allows you to choose the alternative of immediately _aborting_, " +"which ends the program without cleaning up." +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:20 +msgid "" +"Memory that the program was using will then need to be cleaned up by the " +"operating system. If in your project you need to make the resultant binary " +"as small as possible, you can switch from unwinding to aborting upon a panic " +"by adding `panic = 'abort'` to the appropriate `[profile]` sections in your " +"_Cargo.toml_ file. For example, if you want to abort on panic in release " +"mode, add this:" +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:32 +msgid "Let’s try calling `panic!` in a simple program:" +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:38 +msgid "\"crash and burn\"" +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:42 +msgid "When you run the program, you’ll see something like this:" +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:44 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling panic v0.1.0 (file:///projects/panic)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.25s\n" +" Running `target/debug/panic`\n" +"thread 'main' panicked at src/main.rs:2:5:\n" +"crash and burn\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"```" +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:54 +msgid "" +"The call to `panic!` causes the error message contained in the last two " +"lines. The first line shows our panic message and the place in our source " +"code where the panic occurred: _src/main.rs:2:5_ indicates that it’s the " +"second line, fifth character of our _src/main.rs_ file." +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:59 +msgid "" +"In this case, the line indicated is part of our code, and if we go to that " +"line, we see the `panic!` macro call. In other cases, the `panic!` call " +"might be in code that our code calls, and the filename and line number " +"reported by the error message will be someone else’s code where the `panic!` " +"macro is called, not the line of our code that eventually led to the `panic!" +"` call." +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:66 +msgid "" +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:68 +msgid "" +"We can use the backtrace of the functions the `panic!` call came from to " +"figure out the part of our code that is causing the problem. To understand " +"how to use a `panic!` backtrace, let’s look at another example and see what " +"it’s like when a `panic!` call comes from a library because of a bug in our " +"code instead of from our code calling the macro directly. Listing 9-1 has " +"some code that attempts to access an index in a vector beyond the range of " +"valid indexes." +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:85 +msgid "" +"Listing 9-1: Attempting to access an element beyond " +"the end of a vector, which will cause a call to `panic!`" +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:88 +msgid "" +"Here, we’re attempting to access the 100th element of our vector (which is " +"at index 99 because indexing starts at zero), but the vector has only three " +"elements. In this situation, Rust will panic. Using `[]` is supposed to " +"return an element, but if you pass an invalid index, there’s no element that " +"Rust could return here that would be correct." +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:94 +msgid "" +"In C, attempting to read beyond the end of a data structure is undefined " +"behavior. You might get whatever is at the location in memory that would " +"correspond to that element in the data structure, even though the memory " +"doesn’t belong to that structure. This is called a _buffer overread_ and can " +"lead to security vulnerabilities if an attacker is able to manipulate the " +"index in such a way as to read data they shouldn’t be allowed to that is " +"stored after the data structure." +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:102 +msgid "" +"To protect your program from this sort of vulnerability, if you try to read " +"an element at an index that doesn’t exist, Rust will stop execution and " +"refuse to continue. Let’s try it and see:" +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:106 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling panic v0.1.0 (file:///projects/panic)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.27s\n" +" Running `target/debug/panic`\n" +"thread 'main' panicked at src/main.rs:4:6:\n" +"index out of bounds: the len is 3 but the index is 99\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"```" +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:116 +msgid "" +"This error points at line 4 of our _main.rs_ where we attempt to access " +"index `99` of the vector in `v`." +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:119 +msgid "" +"The `note:` line tells us that we can set the `RUST_BACKTRACE` environment " +"variable to get a backtrace of exactly what happened to cause the error. A " +"_backtrace_ is a list of all the functions that have been called to get to " +"this point. Backtraces in Rust work as they do in other languages: the key " +"to reading the backtrace is to start from the top and read until you see " +"files you wrote. That’s the spot where the problem originated. The lines " +"above that spot are code that your code has called; the lines below are code " +"that called your code. These before-and-after lines might include core Rust " +"code, standard library code, or crates that you’re using. Let’s try getting " +"a backtrace by setting the `RUST_BACKTRACE` environment variable to any " +"value except `0`. Listing 9-2 shows output similar to what you’ll see." +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:162 +msgid "" +"Listing 9-2: The backtrace generated by a call to " +"`panic!` displayed when the environment variable `RUST_BACKTRACE` is set" +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:165 +msgid "" +"That’s a lot of output! The exact output you see might be different " +"depending on your operating system and Rust version. In order to get " +"backtraces with this information, debug symbols must be enabled. Debug " +"symbols are enabled by default when using `cargo build` or `cargo run` " +"without the `--release` flag, as we have here." +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:171 +msgid "" +"In the output in Listing 9-2, line 6 of the backtrace points to the line in " +"our project that’s causing the problem: line 4 of _src/main.rs_. If we don’t " +"want our program to panic, we should start our investigation at the location " +"pointed to by the first line mentioning a file we wrote. In Listing 9-1, " +"where we deliberately wrote code that would panic, the way to fix the panic " +"is to not request an element beyond the range of the vector indexes. When " +"your code panics in the future, you’ll need to figure out what action the " +"code is taking with what values to cause the panic and what the code should " +"do instead." +msgstr "" + +#: src/ch09-01-unrecoverable-errors-with-panic.md:180 +msgid "" +"We’ll come back to `panic!` and when we should and should not use `panic!` " +"to handle error conditions in the [“To `panic!` or Not to `panic!`”](ch09-03-" +"to-panic-or-not-to-panic.html#to-panic-or-not-to-panic) " +"section later in this chapter. Next, we’ll look at how to recover from an " +"error using `Result`." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:3 +msgid "" +"Most errors aren’t serious enough to require the program to stop entirely. " +"Sometimes when a function fails it’s for a reason that you can easily " +"interpret and respond to. For example, if you try to open a file and that " +"operation fails because the file doesn’t exist, you might want to create the " +"file instead of terminating the process." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:9 +msgid "" +"Recall from [“Handling Potential Failure with `Result`”](ch02-00-guessing-" +"game-tutorial.html#handling-potential-failure-with-result) in Chapter 2 that the `Result` enum is defined as having two " +"variants, `Ok` and `Err`, as follows:" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:20 +msgid "" +"The `T` and `E` are generic type parameters: we’ll discuss generics in more " +"detail in Chapter 10. What you need to know right now is that `T` represents " +"the type of the value that will be returned in a success case within the " +"`Ok` variant, and `E` represents the type of the error that will be returned " +"in a failure case within the `Err` variant. Because `Result` has these " +"generic type parameters, we can use the `Result` type and the functions " +"defined on it in many different situations where the success value and error " +"value we want to return may differ." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:29 +msgid "" +"Let’s call a function that returns a `Result` value because the function " +"could fail. In Listing 9-3 we try to open a file." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:38 +#: src/ch09-02-recoverable-errors-with-result.md:72 +#: src/ch09-02-recoverable-errors-with-result.md:130 +#: src/ch09-02-recoverable-errors-with-result.md:135 +#: src/ch09-02-recoverable-errors-with-result.md:184 +#: src/ch09-02-recoverable-errors-with-result.md:186 +#: src/ch09-02-recoverable-errors-with-result.md:218 +#: src/ch09-02-recoverable-errors-with-result.md:247 +#: src/ch09-02-recoverable-errors-with-result.md:297 +#: src/ch09-02-recoverable-errors-with-result.md:384 +#: src/ch09-02-recoverable-errors-with-result.md:442 +#: src/ch09-02-recoverable-errors-with-result.md:473 +#: src/ch09-02-recoverable-errors-with-result.md:507 +#: src/ch09-02-recoverable-errors-with-result.md:620 +msgid "\"hello.txt\"" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:42 +msgid "Listing 9-3: Opening a file" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:44 +msgid "" +"The return type of `File::open` is a `Result`. The generic parameter " +"`T` has been filled in by the implementation of `File::open` with the type " +"of the success value, `std::fs::File`, which is a file handle. The type of " +"`E` used in the error value is `std::io::Error`. This return type means the " +"call to `File::open` might succeed and return a file handle that we can read " +"from or write to. The function call also might fail: for example, the file " +"might not exist, or we might not have permission to access the file. The " +"`File::open` function needs to have a way to tell us whether it succeeded or " +"failed and at the same time give us either the file handle or error " +"information. This information is exactly what the `Result` enum conveys." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:55 +msgid "" +"In the case where `File::open` succeeds, the value in the variable " +"`greeting_file_result` will be an instance of `Ok` that contains a file " +"handle. In the case where it fails, the value in `greeting_file_result` will " +"be an instance of `Err` that contains more information about the kind of " +"error that occurred." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:61 +msgid "" +"We need to add to the code in Listing 9-3 to take different actions " +"depending on the value `File::open` returns. Listing 9-4 shows one way to " +"handle the `Result` using a basic tool, the `match` expression that we " +"discussed in Chapter 6." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:76 +#: src/ch09-02-recoverable-errors-with-result.md:190 +msgid "\"Problem opening the file: {error:?}\"" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:81 +msgid "" +"Listing 9-4: Using a `match` expression to handle " +"the `Result` variants that might be returned" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:84 +msgid "" +"Note that, like the `Option` enum, the `Result` enum and its variants have " +"been brought into scope by the prelude, so we don’t need to specify `Result::" +"` before the `Ok` and `Err` variants in the `match` arms." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:88 +msgid "" +"When the result is `Ok`, this code will return the inner `file` value out of " +"the `Ok` variant, and we then assign that file handle value to the variable " +"`greeting_file`. After the `match`, we can use the file handle for reading " +"or writing." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:93 +msgid "" +"The other arm of the `match` handles the case where we get an `Err` value " +"from `File::open`. In this example, we’ve chosen to call the `panic!` macro. " +"If there’s no file named _hello.txt_ in our current directory and we run " +"this code, we’ll see the following output from the `panic!` macro:" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:98 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling error-handling v0.1.0 (file:///projects/error-handling)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.73s\n" +" Running `target/debug/error-handling`\n" +"thread 'main' panicked at src/main.rs:8:23:\n" +"Problem opening the file: Os { code: 2, kind: NotFound, message: \"No such " +"file or directory\" }\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"```" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:108 +msgid "As usual, this output tells us exactly what has gone wrong." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:110 +msgid "Matching on Different Errors" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:112 +msgid "" +"The code in Listing 9-4 will `panic!` no matter why `File::open` failed. " +"However, we want to take different actions for different failure reasons. If " +"`File::open` failed because the file doesn’t exist, we want to create the " +"file and return the handle to the new file. If `File::open` failed for any " +"other reason—for example, because we didn’t have permission to open the file—" +"we still want the code to `panic!` in the same way it did in Listing 9-4. " +"For this, we add an inner `match` expression, shown in Listing 9-5." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:137 +msgid "\"Problem creating the file: {e:?}\"" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:140 +msgid "\"Problem opening the file: {other_error:?}\"" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:147 +msgid "" +"Listing 9-5: Handling different kinds of errors in " +"different ways" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:150 +msgid "" +"The type of the value that `File::open` returns inside the `Err` variant is " +"`io::Error`, which is a struct provided by the standard library. This struct " +"has a method `kind` that we can call to get an `io::ErrorKind` value. The " +"enum `io::ErrorKind` is provided by the standard library and has variants " +"representing the different kinds of errors that might result from an `io` " +"operation. The variant we want to use is `ErrorKind::NotFound`, which " +"indicates the file we’re trying to open doesn’t exist yet. So we match on " +"`greeting_file_result`, but we also have an inner match on `error.kind()`." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:159 +msgid "" +"The condition we want to check in the inner match is whether the value " +"returned by `error.kind()` is the `NotFound` variant of the `ErrorKind` " +"enum. If it is, we try to create the file with `File::create`. However, " +"because `File::create` could also fail, we need a second arm in the inner " +"`match` expression. When the file can’t be created, a different error " +"message is printed. The second arm of the outer `match` stays the same, so " +"the program panics on any error besides the missing file error." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:167 +msgid "Alternatives to Using `match` with `Result`" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:169 +msgid "" +"That’s a lot of `match`! The `match` expression is very useful but also very " +"much a primitive. In Chapter 13, you’ll learn about closures, which are used " +"with many of the methods defined on `Result`. These methods can be " +"more concise than using `match` when handling `Result` values in your " +"code." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:174 +msgid "" +"For example, here’s another way to write the same logic as shown in Listing " +"9-5, this time using closures and the `unwrap_or_else` method:" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:187 +msgid "\"Problem creating the file: {error:?}\"" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:196 +msgid "" +"Although this code has the same behavior as Listing 9-5, it doesn’t contain " +"any `match` expressions and is cleaner to read. Come back to this example " +"after you’ve read Chapter 13, and look up the `unwrap_or_else` method in the " +"standard library documentation. Many more of these methods can clean up huge " +"nested `match` expressions when you’re dealing with errors." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:202 +msgid "Shortcuts for Panic on Error: `unwrap` and `expect`" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:204 +msgid "" +"Using `match` works well enough, but it can be a bit verbose and doesn’t " +"always communicate intent well. The `Result` type has many helper " +"methods defined on it to do various, more specific tasks. The `unwrap` " +"method is a shortcut method implemented just like the `match` expression we " +"wrote in Listing 9-4. If the `Result` value is the `Ok` variant, `unwrap` " +"will return the value inside the `Ok`. If the `Result` is the `Err` variant, " +"`unwrap` will call the `panic!` macro for us. Here is an example of `unwrap` " +"in action:" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:222 +msgid "" +"If we run this code without a _hello.txt_ file, we’ll see an error message " +"from the `panic!` call that the `unwrap` method makes:" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:231 +msgid "" +"```text\n" +"thread 'main' panicked at src/main.rs:4:49:\n" +"called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, " +"message: \"No such file or directory\" }\n" +"```" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:236 +msgid "" +"Similarly, the `expect` method lets us also choose the `panic!` error " +"message. Using `expect` instead of `unwrap` and providing good error " +"messages can convey your intent and make tracking down the source of a panic " +"easier. The syntax of `expect` looks like this:" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:248 +msgid "\"hello.txt should be included in this project\"" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:252 +msgid "" +"We use `expect` in the same way as `unwrap`: to return the file handle or " +"call the `panic!` macro. The error message used by `expect` in its call to " +"`panic!` will be the parameter that we pass to `expect`, rather than the " +"default `panic!` message that `unwrap` uses. Here’s what it looks like:" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:263 +msgid "" +"```text\n" +"thread 'main' panicked at src/main.rs:5:10:\n" +"hello.txt should be included in this project: Os { code: 2, kind: NotFound, " +"message: \"No such file or directory\" }\n" +"```" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:268 +msgid "" +"In production-quality code, most Rustaceans choose `expect` rather than " +"`unwrap` and give more context about why the operation is expected to always " +"succeed. That way, if your assumptions are ever proven wrong, you have more " +"information to use in debugging." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:273 +msgid "Propagating Errors" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:275 +msgid "" +"When a function’s implementation calls something that might fail, instead of " +"handling the error within the function itself you can return the error to " +"the calling code so that it can decide what to do. This is known as " +"_propagating_ the error and gives more control to the calling code, where " +"there might be more information or logic that dictates how the error should " +"be handled than what you have available in the context of your code." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:282 +msgid "" +"For example, Listing 9-6 shows a function that reads a username from a file. " +"If the file doesn’t exist or can’t be read, this function will return those " +"errors to the code that called the function." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:313 +msgid "" +"Listing 9-6: A function that returns errors to the " +"calling code using `match`" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:316 +msgid "" +"This function can be written in a much shorter way, but we’re going to start " +"by doing a lot of it manually in order to explore error handling; at the " +"end, we’ll show the shorter way. Let’s look at the return type of the " +"function first: `Result`. This means the function is " +"returning a value of the type `Result`, where the generic parameter " +"`T` has been filled in with the concrete type `String` and the generic type " +"`E` has been filled in with the concrete type `io::Error`." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:324 +msgid "" +"If this function succeeds without any problems, the code that calls this " +"function will receive an `Ok` value that holds a `String`—the `username` " +"that this function read from the file. If this function encounters any " +"problems, the calling code will receive an `Err` value that holds an " +"instance of `io::Error` that contains more information about what the " +"problems were. We chose `io::Error` as the return type of this function " +"because that happens to be the type of the error value returned from both of " +"the operations we’re calling in this function’s body that might fail: the " +"`File::open` function and the `read_to_string` method." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:334 +msgid "" +"The body of the function starts by calling the `File::open` function. Then " +"we handle the `Result` value with a `match` similar to the `match` in " +"Listing 9-4. If `File::open` succeeds, the file handle in the pattern " +"variable `file` becomes the value in the mutable variable `username_file` " +"and the function continues. In the `Err` case, instead of calling `panic!`, " +"we use the `return` keyword to return early out of the function entirely and " +"pass the error value from `File::open`, now in the pattern variable `e`, " +"back to the calling code as this function’s error value." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:343 +msgid "" +"So, if we have a file handle in `username_file`, the function then creates a " +"new `String` in variable `username` and calls the `read_to_string` method on " +"the file handle in `username_file` to read the contents of the file into " +"`username`. The `read_to_string` method also returns a `Result` because it " +"might fail, even though `File::open` succeeded. So we need another `match` " +"to handle that `Result`: if `read_to_string` succeeds, then our function has " +"succeeded, and we return the username from the file that’s now in `username` " +"wrapped in an `Ok`. If `read_to_string` fails, we return the error value in " +"the same way that we returned the error value in the `match` that handled " +"the return value of `File::open`. However, we don’t need to explicitly say " +"`return`, because this is the last expression in the function." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:355 +msgid "" +"The code that calls this code will then handle getting either an `Ok` value " +"that contains a username or an `Err` value that contains an `io::Error`. " +"It’s up to the calling code to decide what to do with those values. If the " +"calling code gets an `Err` value, it could call `panic!` and crash the " +"program, use a default username, or look up the username from somewhere " +"other than a file, for example. We don’t have enough information on what the " +"calling code is actually trying to do, so we propagate all the success or " +"error information upward for it to handle appropriately." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:364 +msgid "" +"This pattern of propagating errors is so common in Rust that Rust provides " +"the question mark operator `?` to make this easier." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:367 +msgid "A Shortcut for Propagating Errors: the `?` Operator" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:369 +msgid "" +"Listing 9-7 shows an implementation of `read_username_from_file` that has " +"the same functionality as in Listing 9-6, but this implementation uses the `?" +"` operator." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:391 +msgid "" +"Listing 9-7: A function that returns errors to the " +"calling code using the `?` operator" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:394 +msgid "" +"The `?` placed after a `Result` value is defined to work in almost the same " +"way as the `match` expressions we defined to handle the `Result` values in " +"Listing 9-6. If the value of the `Result` is an `Ok`, the value inside the " +"`Ok` will get returned from this expression, and the program will continue. " +"If the value is an `Err`, the `Err` will be returned from the whole function " +"as if we had used the `return` keyword so the error value gets propagated to " +"the calling code." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:402 +msgid "" +"There is a difference between what the `match` expression from Listing 9-6 " +"does and what the `?` operator does: error values that have the `?` operator " +"called on them go through the `from` function, defined in the `From` trait " +"in the standard library, which is used to convert values from one type into " +"another. When the `?` operator calls the `from` function, the error type " +"received is converted into the error type defined in the return type of the " +"current function. This is useful when a function returns one error type to " +"represent all the ways a function might fail, even if parts might fail for " +"many different reasons." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:412 +msgid "" +"For example, we could change the `read_username_from_file` function in " +"Listing 9-7 to return a custom error type named `OurError` that we define. " +"If we also define `impl From for OurError` to construct an " +"instance of `OurError` from an `io::Error`, then the `?` operator calls in " +"the body of `read_username_from_file` will call `from` and convert the error " +"types without needing to add any more code to the function." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:419 +msgid "" +"In the context of Listing 9-7, the `?` at the end of the `File::open` call " +"will return the value inside an `Ok` to the variable `username_file`. If an " +"error occurs, the `?` operator will return early out of the whole function " +"and give any `Err` value to the calling code. The same thing applies to the " +"`?` at the end of the `read_to_string` call." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:425 +msgid "" +"The `?` operator eliminates a lot of boilerplate and makes this function’s " +"implementation simpler. We could even shorten this code further by chaining " +"method calls immediately after the `?`, as shown in Listing 9-8." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:448 +msgid "" +"Listing 9-8: Chaining method calls after the `?` " +"operator" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:451 +msgid "" +"We’ve moved the creation of the new `String` in `username` to the beginning " +"of the function; that part hasn’t changed. Instead of creating a variable " +"`username_file`, we’ve chained the call to `read_to_string` directly onto " +"the result of `File::open(\"hello.txt\")?`. We still have a `?` at the end " +"of the `read_to_string` call, and we still return an `Ok` value containing " +"`username` when both `File::open` and `read_to_string` succeed rather than " +"returning errors. The functionality is again the same as in Listing 9-6 and " +"Listing 9-7; this is just a different, more ergonomic way to write it." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:460 +msgid "" +"Listing 9-9 shows a way to make this even shorter using `fs::read_to_string`." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:477 +msgid "" +"Listing 9-9: Using `fs::read_to_string` instead of " +"opening and then reading the file" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:480 +msgid "" +"Reading a file into a string is a fairly common operation, so the standard " +"library provides the convenient `fs::read_to_string` function that opens the " +"file, creates a new `String`, reads the contents of the file, puts the " +"contents into that `String`, and returns it. Of course, using `fs::" +"read_to_string` doesn’t give us the opportunity to explain all the error " +"handling, so we did it the longer way first." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:487 +msgid "Where The `?` Operator Can Be Used" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:489 +msgid "" +"The `?` operator can only be used in functions whose return type is " +"compatible with the value the `?` is used on. This is because the `?` " +"operator is defined to perform an early return of a value out of the " +"function, in the same manner as the `match` expression we defined in Listing " +"9-6. In Listing 9-6, the `match` was using a `Result` value, and the early " +"return arm returned an `Err(e)` value. The return type of the function has " +"to be a `Result` so that it’s compatible with this `return`." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:497 +msgid "" +"In Listing 9-10, let’s look at the error we’ll get if we use the `?` " +"operator in a `main` function with a return type that is incompatible with " +"the type of the value we use `?` on." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:511 +msgid "" +"Listing 9-10: Attempting to use the `?` in the " +"`main` function that returns `()` won’t compile." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:514 +msgid "" +"This code opens a file, which might fail. The `?` operator follows the " +"`Result` value returned by `File::open`, but this `main` function has the " +"return type of `()`, not `Result`. When we compile this code, we get the " +"following error message:" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:519 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling error-handling v0.1.0 (file:///projects/error-handling)\n" +"error[E0277]: the `?` operator can only be used in a function that returns " +"`Result` or `Option` (or another type that implements `FromResidual`)\n" +" --> src/main.rs:4:48\n" +" |\n" +"3 | fn main() {\n" +" | --------- this function should return `Result` or `Option` to accept `?" +"`\n" +"4 | let greeting_file = File::open(\"hello.txt\")?;\n" +" | ^ cannot use the `?` " +"operator in a function that returns `()`\n" +" |\n" +" = help: the trait `FromResidual>` is " +"not implemented for `()`\n" +"\n" +"For more information about this error, try `rustc --explain E0277`.\n" +"error: could not compile `error-handling` (bin \"error-handling\") due to 1 " +"previous error\n" +"```" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:536 +msgid "" +"This error points out that we’re only allowed to use the `?` operator in a " +"function that returns `Result`, `Option`, or another type that implements " +"`FromResidual`." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:540 +msgid "" +"To fix the error, you have two choices. One choice is to change the return " +"type of your function to be compatible with the value you’re using the `?` " +"operator on as long as you have no restrictions preventing that. The other " +"choice is to use a `match` or one of the `Result` methods to handle " +"the `Result` in whatever way is appropriate." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:546 +msgid "" +"The error message also mentioned that `?` can be used with `Option` " +"values as well. As with using `?` on `Result`, you can only use `?` on " +"`Option` in a function that returns an `Option`. The behavior of the `?` " +"operator when called on an `Option` is similar to its behavior when " +"called on a `Result`: if the value is `None`, the `None` will be " +"returned early from the function at that point. If the value is `Some`, the " +"value inside the `Some` is the resultant value of the expression, and the " +"function continues. Listing 9-11 has an example of a function that finds the " +"last character of the first line in the given text." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:563 +msgid "\"Hello, world\\nHow are you today?\"" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:564 +msgid "'d'" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:567 +#: src/ch17-03-oo-design-patterns.md:52 src/ch17-03-oo-design-patterns.md:55 +#: src/ch17-03-oo-design-patterns.md:224 src/ch17-03-oo-design-patterns.md:268 +#: src/ch17-03-oo-design-patterns.md:375 src/ch17-03-oo-design-patterns.md:607 +#: src/ch17-03-oo-design-patterns.md:759 src/ch17-03-oo-design-patterns.md:762 +msgid "\"\"" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:568 +msgid "\"\\nhi\"" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:572 +msgid "" +"Listing 9-11: Using the `?` operator on an " +"`Option` value" +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:575 +msgid "" +"This function returns `Option` because it’s possible that there is a " +"character there, but it’s also possible that there isn’t. This code takes " +"the `text` string slice argument and calls the `lines` method on it, which " +"returns an iterator over the lines in the string. Because this function " +"wants to examine the first line, it calls `next` on the iterator to get the " +"first value from the iterator. If `text` is the empty string, this call to " +"`next` will return `None`, in which case we use `?` to stop and return " +"`None` from `last_char_of_first_line`. If `text` is not the empty string, " +"`next` will return a `Some` value containing a string slice of the first " +"line in `text`." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:585 +msgid "" +"The `?` extracts the string slice, and we can call `chars` on that string " +"slice to get an iterator of its characters. We’re interested in the last " +"character in this first line, so we call `last` to return the last item in " +"the iterator. This is an `Option` because it’s possible that the first line " +"is the empty string; for example, if `text` starts with a blank line but has " +"characters on other lines, as in `\"\\nhi\"`. However, if there is a last " +"character on the first line, it will be returned in the `Some` variant. The " +"`?` operator in the middle gives us a concise way to express this logic, " +"allowing us to implement the function in one line. If we couldn’t use the `?" +"` operator on `Option`, we’d have to implement this logic using more method " +"calls or a `match` expression." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:596 +msgid "" +"Note that you can use the `?` operator on a `Result` in a function that " +"returns `Result`, and you can use the `?` operator on an `Option` in a " +"function that returns `Option`, but you can’t mix and match. The `?` " +"operator won’t automatically convert a `Result` to an `Option` or vice " +"versa; in those cases, you can use methods like the `ok` method on `Result` " +"or the `ok_or` method on `Option` to do the conversion explicitly." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:603 +msgid "" +"So far, all the `main` functions we’ve used return `()`. The `main` function " +"is special because it’s the entry point and exit point of an executable " +"program, and there are restrictions on what its return type can be for the " +"program to behave as expected." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:608 +msgid "" +"Luckily, `main` can also return a `Result<(), E>`. Listing 9-12 has the code " +"from Listing 9-10, but we’ve changed the return type of `main` to be " +"`Result<(), Box>` and added a return value `Ok(())` to the end. " +"This code will now compile." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:626 +msgid "" +"Listing 9-12: Changing `main` to return `Result<(), " +"E>` allows the use of the `?` operator on `Result` values." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:629 +msgid "" +"The `Box` type is a _trait object_, which we’ll talk about in the " +"[“Using Trait Objects that Allow for Values of Different Types”](ch17-02-" +"trait-objects.html#using-trait-objects-that-allow-for-values-of-different-" +"types) section in Chapter 17. For now, you can read `Box` to mean “any kind of error.” Using `?` on a `Result` value in a " +"`main` function with the error type `Box` is allowed because it " +"allows any `Err` value to be returned early. Even though the body of this " +"`main` function will only ever return errors of type `std::io::Error`, by " +"specifying `Box`, this signature will continue to be correct even " +"if more code that returns other errors is added to the body of `main`." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:639 +msgid "" +"When a `main` function returns a `Result<(), E>`, the executable will exit " +"with a value of `0` if `main` returns `Ok(())` and will exit with a nonzero " +"value if `main` returns an `Err` value. Executables written in C return " +"integers when they exit: programs that exit successfully return the integer " +"`0`, and programs that error return some integer other than `0`. Rust also " +"returns integers from executables to be compatible with this convention." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:646 +msgid "" +"The `main` function may return any types that implement [the `std::process::" +"Termination` trait](../std/process/trait.Termination.html), " +"which contains a function `report` that returns an `ExitCode`. Consult the " +"standard library documentation for more information on implementing the " +"`Termination` trait for your own types." +msgstr "" + +#: src/ch09-02-recoverable-errors-with-result.md:652 +msgid "" +"Now that we’ve discussed the details of calling `panic!` or returning " +"`Result`, let’s return to the topic of how to decide which is appropriate to " +"use in which cases." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:3 +msgid "" +"So how do you decide when you should call `panic!` and when you should " +"return `Result`? When code panics, there’s no way to recover. You could call " +"`panic!` for any error situation, whether there’s a possible way to recover " +"or not, but then you’re making the decision that a situation is " +"unrecoverable on behalf of the calling code. When you choose to return a " +"`Result` value, you give the calling code options. The calling code could " +"choose to attempt to recover in a way that’s appropriate for its situation, " +"or it could decide that an `Err` value in this case is unrecoverable, so it " +"can call `panic!` and turn your recoverable error into an unrecoverable one. " +"Therefore, returning `Result` is a good default choice when you’re defining " +"a function that might fail." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:14 +msgid "" +"In situations such as examples, prototype code, and tests, it’s more " +"appropriate to write code that panics instead of returning a `Result`. Let’s " +"explore why, then discuss situations in which the compiler can’t tell that " +"failure is impossible, but you as a human can. The chapter will conclude " +"with some general guidelines on how to decide whether to panic in library " +"code." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:20 +msgid "Examples, Prototype Code, and Tests" +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:22 +msgid "" +"When you’re writing an example to illustrate some concept, also including " +"robust error-handling code can make the example less clear. In examples, " +"it’s understood that a call to a method like `unwrap` that could panic is " +"meant as a placeholder for the way you’d want your application to handle " +"errors, which can differ based on what the rest of your code is doing." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:28 +msgid "" +"Similarly, the `unwrap` and `expect` methods are very handy when " +"prototyping, before you’re ready to decide how to handle errors. They leave " +"clear markers in your code for when you’re ready to make your program more " +"robust." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:32 +msgid "" +"If a method call fails in a test, you’d want the whole test to fail, even if " +"that method isn’t the functionality under test. Because `panic!` is how a " +"test is marked as a failure, calling `unwrap` or `expect` is exactly what " +"should happen." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:37 +msgid "Cases in Which You Have More Information Than the Compiler" +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:39 +msgid "" +"It would also be appropriate to call `unwrap` or `expect` when you have some " +"other logic that ensures the `Result` will have an `Ok` value, but the logic " +"isn’t something the compiler understands. You’ll still have a `Result` value " +"that you need to handle: whatever operation you’re calling still has the " +"possibility of failing in general, even though it’s logically impossible in " +"your particular situation. If you can ensure by manually inspecting the code " +"that you’ll never have an `Err` variant, it’s perfectly acceptable to call " +"`unwrap`, and even better to document the reason you think you’ll never have " +"an `Err` variant in the `expect` text. Here’s an example:" +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:55 +msgid "\"Hardcoded IP address should be valid\"" +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:59 +msgid "" +"We’re creating an `IpAddr` instance by parsing a hardcoded string. We can " +"see that `127.0.0.1` is a valid IP address, so it’s acceptable to use " +"`expect` here. However, having a hardcoded, valid string doesn’t change the " +"return type of the `parse` method: we still get a `Result` value, and the " +"compiler will still make us handle the `Result` as if the `Err` variant is a " +"possibility because the compiler isn’t smart enough to see that this string " +"is always a valid IP address. If the IP address string came from a user " +"rather than being hardcoded into the program and therefore _did_ have a " +"possibility of failure, we’d definitely want to handle the `Result` in a " +"more robust way instead. Mentioning the assumption that this IP address is " +"hardcoded will prompt us to change `expect` to better error-handling code " +"if, in the future, we need to get the IP address from some other source " +"instead." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:72 +msgid "Guidelines for Error Handling" +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:74 +msgid "" +"It’s advisable to have your code panic when it’s possible that your code " +"could end up in a bad state. In this context, a _bad state_ is when some " +"assumption, guarantee, contract, or invariant has been broken, such as when " +"invalid values, contradictory values, or missing values are passed to your " +"code—plus one or more of the following:" +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:80 +msgid "" +"The bad state is something that is unexpected, as opposed to something that " +"will likely happen occasionally, like a user entering data in the wrong " +"format." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:83 +msgid "" +"Your code after this point needs to rely on not being in this bad state, " +"rather than checking for the problem at every step." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:85 +msgid "" +"There’s not a good way to encode this information in the types you use. " +"We’ll work through an example of what we mean in the [“Encoding States and " +"Behavior as Types”](ch17-03-oo-design-patterns.html#encoding-states-and-" +"behavior-as-types) section of Chapter 17." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:89 +msgid "" +"If someone calls your code and passes in values that don’t make sense, it’s " +"best to return an error if you can so the user of the library can decide " +"what they want to do in that case. However, in cases where continuing could " +"be insecure or harmful, the best choice might be to call `panic!` and alert " +"the person using your library to the bug in their code so they can fix it " +"during development. Similarly, `panic!` is often appropriate if you’re " +"calling external code that is out of your control and it returns an invalid " +"state that you have no way of fixing." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:98 +msgid "" +"However, when failure is expected, it’s more appropriate to return a " +"`Result` than to make a `panic!` call. Examples include a parser being given " +"malformed data or an HTTP request returning a status that indicates you have " +"hit a rate limit. In these cases, returning a `Result` indicates that " +"failure is an expected possibility that the calling code must decide how to " +"handle." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:104 +msgid "" +"When your code performs an operation that could put a user at risk if it’s " +"called using invalid values, your code should verify the values are valid " +"first and panic if the values aren’t valid. This is mostly for safety " +"reasons: attempting to operate on invalid data can expose your code to " +"vulnerabilities. This is the main reason the standard library will call " +"`panic!` if you attempt an out-of-bounds memory access: trying to access " +"memory that doesn’t belong to the current data structure is a common " +"security problem. Functions often have _contracts_: their behavior is only " +"guaranteed if the inputs meet particular requirements. Panicking when the " +"contract is violated makes sense because a contract violation always " +"indicates a caller-side bug, and it’s not a kind of error you want the " +"calling code to have to explicitly handle. In fact, there’s no reasonable " +"way for calling code to recover; the calling _programmers_ need to fix the " +"code. Contracts for a function, especially when a violation will cause a " +"panic, should be explained in the API documentation for the function." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:119 +msgid "" +"However, having lots of error checks in all of your functions would be " +"verbose and annoying. Fortunately, you can use Rust’s type system (and thus " +"the type checking done by the compiler) to do many of the checks for you. If " +"your function has a particular type as a parameter, you can proceed with " +"your code’s logic knowing that the compiler has already ensured you have a " +"valid value. For example, if you have a type rather than an `Option`, your " +"program expects to have _something_ rather than _nothing_. Your code then " +"doesn’t have to handle two cases for the `Some` and `None` variants: it will " +"only have one case for definitely having a value. Code trying to pass " +"nothing to your function won’t even compile, so your function doesn’t have " +"to check for that case at runtime. Another example is using an unsigned " +"integer type such as `u32`, which ensures the parameter is never negative." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:132 +msgid "Creating Custom Types for Validation" +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:134 +msgid "" +"Let’s take the idea of using Rust’s type system to ensure we have a valid " +"value one step further and look at creating a custom type for validation. " +"Recall the guessing game in Chapter 2 in which our code asked the user to " +"guess a number between 1 and 100. We never validated that the user’s guess " +"was between those numbers before checking it against our secret number; we " +"only validated that the guess was positive. In this case, the consequences " +"were not very dire: our output of “Too high” or “Too low” would still be " +"correct. But it would be a useful enhancement to guide the user toward valid " +"guesses and have different behavior when the user guesses a number that’s " +"out of range versus when the user types, for example, letters instead." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:145 +msgid "" +"One way to do this would be to parse the guess as an `i32` instead of only a " +"`u32` to allow potentially negative numbers, and then add a check for the " +"number being in range, like so:" +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:178 +msgid "\"The secret number will be between 1 and 100.\"" +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:195 +msgid "" +"The `if` expression checks whether our value is out of range, tells the user " +"about the problem, and calls `continue` to start the next iteration of the " +"loop and ask for another guess. After the `if` expression, we can proceed " +"with the comparisons between `guess` and the secret number knowing that " +"`guess` is between 1 and 100." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:201 +msgid "" +"However, this is not an ideal solution: if it were absolutely critical that " +"the program only operated on values between 1 and 100, and it had many " +"functions with this requirement, having a check like this in every function " +"would be tedious (and might impact performance)." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:206 +msgid "" +"Instead, we can make a new type and put the validations in a function to " +"create an instance of the type rather than repeating the validations " +"everywhere. That way, it’s safe for functions to use the new type in their " +"signatures and confidently use the values they receive. Listing 9-13 shows " +"one way to define a `Guess` type that will only create an instance of " +"`Guess` if the `new` function receives a value between 1 and 100." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:223 src/ch11-01-writing-tests.md:863 +#: src/ch11-01-writing-tests.md:919 +msgid "\"Guess value must be between 1 and 100, got {value}.\"" +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:235 +msgid "" +"Listing 9-13: A `Guess` type that will only continue " +"with values between 1 and 100" +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:238 +msgid "" +"First we define a struct named `Guess` that has a field named `value` that " +"holds an `i32`. This is where the number will be stored." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:241 +msgid "" +"Then we implement an associated function named `new` on `Guess` that creates " +"instances of `Guess` values. The `new` function is defined to have one " +"parameter named `value` of type `i32` and to return a `Guess`. The code in " +"the body of the `new` function tests `value` to make sure it’s between 1 and " +"100. If `value` doesn’t pass this test, we make a `panic!` call, which will " +"alert the programmer who is writing the calling code that they have a bug " +"they need to fix, because creating a `Guess` with a `value` outside this " +"range would violate the contract that `Guess::new` is relying on. The " +"conditions in which `Guess::new` might panic should be discussed in its " +"public-facing API documentation; we’ll cover documentation conventions " +"indicating the possibility of a `panic!` in the API documentation that you " +"create in Chapter 14. If `value` does pass the test, we create a new `Guess` " +"with its `value` field set to the `value` parameter and return the `Guess`." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:255 +msgid "" +"Next, we implement a method named `value` that borrows `self`, doesn’t have " +"any other parameters, and returns an `i32`. This kind of method is sometimes " +"called a _getter_ because its purpose is to get some data from its fields " +"and return it. This public method is necessary because the `value` field of " +"the `Guess` struct is private. It’s important that the `value` field be " +"private so code using the `Guess` struct is not allowed to set `value` " +"directly: code outside the module _must_ use the `Guess::new` function to " +"create an instance of `Guess`, thereby ensuring there’s no way for a `Guess` " +"to have a `value` that hasn’t been checked by the conditions in the `Guess::" +"new` function." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:265 +msgid "" +"A function that has a parameter or returns only numbers between 1 and 100 " +"could then declare in its signature that it takes or returns a `Guess` " +"rather than an `i32` and wouldn’t need to do any additional checks in its " +"body." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:271 +msgid "" +"Rust’s error-handling features are designed to help you write more robust " +"code. The `panic!` macro signals that your program is in a state it can’t " +"handle and lets you tell the process to stop instead of trying to proceed " +"with invalid or incorrect values. The `Result` enum uses Rust’s type system " +"to indicate that operations might fail in a way that your code could recover " +"from. You can use `Result` to tell code that calls your code that it needs " +"to handle potential success or failure as well. Using `panic!` and `Result` " +"in the appropriate situations will make your code more reliable in the face " +"of inevitable problems." +msgstr "" + +#: src/ch09-03-to-panic-or-not-to-panic.md:280 +msgid "" +"Now that you’ve seen useful ways that the standard library uses generics " +"with the `Option` and `Result` enums, we’ll talk about how generics work and " +"how you can use them in your code." +msgstr "" + +#: src/ch10-00-generics.md:3 +msgid "" +"Every programming language has tools for effectively handling the " +"duplication of concepts. In Rust, one such tool is _generics_: abstract " +"stand-ins for concrete types or other properties. We can express the " +"behavior of generics or how they relate to other generics without knowing " +"what will be in their place when compiling and running the code." +msgstr "" + +#: src/ch10-00-generics.md:9 +msgid "" +"Functions can take parameters of some generic type, instead of a concrete " +"type like `i32` or `String`, in the same way they take parameters with " +"unknown values to run the same code on multiple concrete values. In fact, " +"we’ve already used generics in Chapter 6 with `Option`, in Chapter 8 with " +"`Vec` and `HashMap`, and in Chapter 9 with `Result`. In this " +"chapter, you’ll explore how to define your own types, functions, and methods " +"with generics!" +msgstr "" + +#: src/ch10-00-generics.md:16 +msgid "" +"First we’ll review how to extract a function to reduce code duplication. " +"We’ll then use the same technique to make a generic function from two " +"functions that differ only in the types of their parameters. We’ll also " +"explain how to use generic types in struct and enum definitions." +msgstr "" + +#: src/ch10-00-generics.md:21 +msgid "" +"Then you’ll learn how to use _traits_ to define behavior in a generic way. " +"You can combine traits with generic types to constrain a generic type to " +"accept only those types that have a particular behavior, as opposed to just " +"any type." +msgstr "" + +#: src/ch10-00-generics.md:25 +msgid "" +"Finally, we’ll discuss _lifetimes_: a variety of generics that give the " +"compiler information about how references relate to each other. Lifetimes " +"allow us to give the compiler enough information about borrowed values so " +"that it can ensure references will be valid in more situations than it could " +"without our help." +msgstr "" + +#: src/ch10-00-generics.md:31 +msgid "Removing Duplication by Extracting a Function" +msgstr "" + +#: src/ch10-00-generics.md:33 +msgid "" +"Generics allow us to replace specific types with a placeholder that " +"represents multiple types to remove code duplication. Before diving into " +"generics syntax, let’s first look at how to remove duplication in a way that " +"doesn’t involve generic types by extracting a function that replaces " +"specific values with a placeholder that represents multiple values. Then " +"we’ll apply the same technique to extract a generic function! By looking at " +"how to recognize duplicated code you can extract into a function, you’ll " +"start to recognize duplicated code that can use generics." +msgstr "" + +#: src/ch10-00-generics.md:42 +msgid "" +"We’ll begin with the short program in Listing 10-1 that finds the largest " +"number in a list." +msgstr "" + +#: src/ch10-00-generics.md:59 src/ch10-00-generics.md:94 +#: src/ch10-00-generics.md:106 +msgid "\"The largest number is {largest}\"" +msgstr "" + +#: src/ch10-00-generics.md:64 +msgid "" +"Listing 10-1: Finding the largest number in a list " +"of numbers" +msgstr "" + +#: src/ch10-00-generics.md:67 +msgid "" +"We store a list of integers in the variable `number_list` and place a " +"reference to the first number in the list in a variable named `largest`. We " +"then iterate through all the numbers in the list, and if the current number " +"is greater than the number stored in `largest`, we replace the reference in " +"that variable. However, if the current number is less than or equal to the " +"largest number seen so far, the variable doesn’t change, and the code moves " +"on to the next number in the list. After considering all the numbers in the " +"list, `largest` should refer to the largest number, which in this case is " +"100." +msgstr "" + +#: src/ch10-00-generics.md:76 +msgid "" +"We’ve now been tasked with finding the largest number in two different lists " +"of numbers. To do so, we can choose to duplicate the code in Listing 10-1 " +"and use the same logic at two different places in the program, as shown in " +"Listing 10-2." +msgstr "" + +#: src/ch10-00-generics.md:110 +msgid "" +"Listing 10-2: Code to find the largest number in " +"_two_ lists of numbers" +msgstr "" + +#: src/ch10-00-generics.md:113 +msgid "" +"Although this code works, duplicating code is tedious and error prone. We " +"also have to remember to update the code in multiple places when we want to " +"change it." +msgstr "" + +#: src/ch10-00-generics.md:117 +msgid "" +"To eliminate this duplication, we’ll create an abstraction by defining a " +"function that operates on any list of integers passed in as a parameter. " +"This solution makes our code clearer and lets us express the concept of " +"finding the largest number in a list abstractly." +msgstr "" + +#: src/ch10-00-generics.md:122 +msgid "" +"In Listing 10-3, we extract the code that finds the largest number into a " +"function named `largest`. Then we call the function to find the largest " +"number in the two lists from Listing 10-2. We could also use the function on " +"any other list of `i32` values we might have in the future." +msgstr "" + +#: src/ch10-00-generics.md:146 src/ch10-00-generics.md:152 +#: src/ch10-01-syntax.md:50 src/ch10-01-syntax.md:116 +msgid "\"The largest number is {result}\"" +msgstr "" + +#: src/ch10-00-generics.md:157 +msgid "" +"Listing 10-3: Abstracted code to find the largest " +"number in two lists" +msgstr "" + +#: src/ch10-00-generics.md:160 +msgid "" +"The `largest` function has a parameter called `list`, which represents any " +"concrete slice of `i32` values we might pass into the function. As a result, " +"when we call the function, the code runs on the specific values that we pass " +"in." +msgstr "" + +#: src/ch10-00-generics.md:165 +msgid "" +"In summary, here are the steps we took to change the code from Listing 10-2 " +"to Listing 10-3:" +msgstr "" + +#: src/ch10-00-generics.md:168 +msgid "Identify duplicate code." +msgstr "" + +#: src/ch10-00-generics.md:169 +msgid "" +"Extract the duplicate code into the body of the function, and specify the " +"inputs and return values of that code in the function signature." +msgstr "" + +#: src/ch10-00-generics.md:171 +msgid "" +"Update the two instances of duplicated code to call the function instead." +msgstr "" + +#: src/ch10-00-generics.md:173 +msgid "" +"Next, we’ll use these same steps with generics to reduce code duplication. " +"In the same way that the function body can operate on an abstract `list` " +"instead of specific values, generics allow code to operate on abstract types." +msgstr "" + +#: src/ch10-00-generics.md:177 +msgid "" +"For example, say we had two functions: one that finds the largest item in a " +"slice of `i32` values and one that finds the largest item in a slice of " +"`char` values. How would we eliminate that duplication? Let’s find out!" +msgstr "" + +#: src/ch10-01-syntax.md:3 +msgid "" +"We use generics to create definitions for items like function signatures or " +"structs, which we can then use with many different concrete data types. " +"Let’s first look at how to define functions, structs, enums, and methods " +"using generics. Then we’ll discuss how generics affect code performance." +msgstr "" + +#: src/ch10-01-syntax.md:8 +msgid "In Function Definitions" +msgstr "" + +#: src/ch10-01-syntax.md:10 +msgid "" +"When defining a function that uses generics, we place the generics in the " +"signature of the function where we would usually specify the data types of " +"the parameters and return value. Doing so makes our code more flexible and " +"provides more functionality to callers of our function while preventing code " +"duplication." +msgstr "" + +#: src/ch10-01-syntax.md:15 +msgid "" +"Continuing with our `largest` function, Listing 10-4 shows two functions " +"that both find the largest value in a slice. We’ll then combine these into a " +"single function that uses generics." +msgstr "" + +#: src/ch10-01-syntax.md:53 src/ch10-01-syntax.md:57 src/ch10-01-syntax.md:118 +msgid "'y'" +msgstr "" + +#: src/ch10-01-syntax.md:53 src/ch10-01-syntax.md:118 +msgid "'m'" +msgstr "" + +#: src/ch10-01-syntax.md:53 src/ch10-01-syntax.md:118 +#: src/ch18-01-all-the-places-for-patterns.md:156 +#: src/ch18-03-pattern-syntax.md:145 +msgid "'a'" +msgstr "" + +#: src/ch10-01-syntax.md:53 src/ch10-01-syntax.md:118 +msgid "'q'" +msgstr "" + +#: src/ch10-01-syntax.md:56 src/ch10-01-syntax.md:121 +msgid "\"The largest char is {result}\"" +msgstr "" + +#: src/ch10-01-syntax.md:61 +msgid "" +"Listing 10-4: Two functions that differ only in " +"their names and in the types in their signatures" +msgstr "" + +#: src/ch10-01-syntax.md:64 +msgid "" +"The `largest_i32` function is the one we extracted in Listing 10-3 that " +"finds the largest `i32` in a slice. The `largest_char` function finds the " +"largest `char` in a slice. The function bodies have the same code, so let’s " +"eliminate the duplication by introducing a generic type parameter in a " +"single function." +msgstr "" + +#: src/ch10-01-syntax.md:69 +msgid "" +"To parameterize the types in a new single function, we need to name the type " +"parameter, just as we do for the value parameters to a function. You can use " +"any identifier as a type parameter name. But we’ll use `T` because, by " +"convention, type parameter names in Rust are short, often just one letter, " +"and Rust’s type-naming convention is UpperCamelCase. Short for _type_, `T` " +"is the default choice of most Rust programmers." +msgstr "" + +#: src/ch10-01-syntax.md:76 +msgid "" +"When we use a parameter in the body of the function, we have to declare the " +"parameter name in the signature so the compiler knows what that name means. " +"Similarly, when we use a type parameter name in a function signature, we " +"have to declare the type parameter name before we use it. To define the " +"generic `largest` function, we place type name declarations inside angle " +"brackets, `<>`, between the name of the function and the parameter list, " +"like this:" +msgstr "" + +#: src/ch10-01-syntax.md:87 +msgid "" +"We read this definition as: the function `largest` is generic over some type " +"`T`. This function has one parameter named `list`, which is a slice of " +"values of type `T`. The `largest` function will return a reference to a " +"value of the same type `T`." +msgstr "" + +#: src/ch10-01-syntax.md:92 +msgid "" +"Listing 10-5 shows the combined `largest` function definition using the " +"generic data type in its signature. The listing also shows how we can call " +"the function with either a slice of `i32` values or `char` values. Note that " +"this code won’t compile yet, but we’ll fix it later in this chapter." +msgstr "" + +#: src/ch10-01-syntax.md:125 +msgid "" +"Listing 10-5: The `largest` function using generic " +"type parameters; this doesn’t compile yet" +msgstr "" + +#: src/ch10-01-syntax.md:128 +msgid "If we compile this code right now, we’ll get this error:" +msgstr "" + +#: src/ch10-01-syntax.md:130 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling chapter10 v0.1.0 (file:///projects/chapter10)\n" +"error[E0369]: binary operation `>` cannot be applied to type `&T`\n" +" --> src/main.rs:5:17\n" +" |\n" +"5 | if item > largest {\n" +" | ---- ^ ------- &T\n" +" | |\n" +" | &T\n" +" |\n" +"help: consider restricting type parameter `T`\n" +" |\n" +"1 | fn largest(list: &[T]) -> &T {\n" +" | ++++++++++++++++++++++\n" +"\n" +"For more information about this error, try `rustc --explain E0369`.\n" +"error: could not compile `chapter10` (bin \"chapter10\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch10-01-syntax.md:150 +msgid "" +"The help text mentions `std::cmp::PartialOrd`, which is a _trait_, and we’re " +"going to talk about traits in the next section. For now, know that this " +"error states that the body of `largest` won’t work for all possible types " +"that `T` could be. Because we want to compare values of type `T` in the " +"body, we can only use types whose values can be ordered. To enable " +"comparisons, the standard library has the `std::cmp::PartialOrd` trait that " +"you can implement on types (see Appendix C for more on this trait). By " +"following the help text’s suggestion, we restrict the types valid for `T` to " +"only those that implement `PartialOrd` and this example will compile, " +"because the standard library implements `PartialOrd` on both `i32` and " +"`char`." +msgstr "" + +#: src/ch10-01-syntax.md:161 +msgid "In Struct Definitions" +msgstr "" + +#: src/ch10-01-syntax.md:163 +msgid "" +"We can also define structs to use a generic type parameter in one or more " +"fields using the `<>` syntax. Listing 10-6 defines a `Point` struct to " +"hold `x` and `y` coordinate values of any type." +msgstr "" + +#: src/ch10-01-syntax.md:181 +msgid "" +"Listing 10-6: A `Point` struct that holds `x` and " +"`y` values of type `T`" +msgstr "" + +#: src/ch10-01-syntax.md:184 +msgid "" +"The syntax for using generics in struct definitions is similar to that used " +"in function definitions. First we declare the name of the type parameter " +"inside angle brackets just after the name of the struct. Then we use the " +"generic type in the struct definition where we would otherwise specify " +"concrete data types." +msgstr "" + +#: src/ch10-01-syntax.md:190 +msgid "" +"Note that because we’ve used only one generic type to define `Point`, " +"this definition says that the `Point` struct is generic over some type " +"`T`, and the fields `x` and `y` are _both_ that same type, whatever that " +"type may be. If we create an instance of a `Point` that has values of " +"different types, as in Listing 10-7, our code won’t compile." +msgstr "" + +#: src/ch10-01-syntax.md:209 +msgid "" +"Listing 10-7: The fields `x` and `y` must be the " +"same type because both have the same generic data type `T`." +msgstr "" + +#: src/ch10-01-syntax.md:212 +msgid "" +"In this example, when we assign the integer value `5` to `x`, we let the " +"compiler know that the generic type `T` will be an integer for this instance " +"of `Point`. Then when we specify `4.0` for `y`, which we’ve defined to " +"have the same type as `x`, we’ll get a type mismatch error like this:" +msgstr "" + +#: src/ch10-01-syntax.md:217 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling chapter10 v0.1.0 (file:///projects/chapter10)\n" +"error[E0308]: mismatched types\n" +" --> src/main.rs:7:38\n" +" |\n" +"7 | let wont_work = Point { x: 5, y: 4.0 };\n" +" | ^^^ expected integer, found " +"floating-point number\n" +"\n" +"For more information about this error, try `rustc --explain E0308`.\n" +"error: could not compile `chapter10` (bin \"chapter10\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch10-01-syntax.md:230 +msgid "" +"To define a `Point` struct where `x` and `y` are both generics but could " +"have different types, we can use multiple generic type parameters. For " +"example, in Listing 10-8, we change the definition of `Point` to be generic " +"over types `T` and `U` where `x` is of type `T` and `y` is of type `U`." +msgstr "" + +#: src/ch10-01-syntax.md:250 +msgid "" +"Listing 10-8: A `Point` generic over two types " +"so that `x` and `y` can be values of different types" +msgstr "" + +#: src/ch10-01-syntax.md:253 +msgid "" +"Now all the instances of `Point` shown are allowed! You can use as many " +"generic type parameters in a definition as you want, but using more than a " +"few makes your code hard to read. If you’re finding you need lots of generic " +"types in your code, it could indicate that your code needs restructuring " +"into smaller pieces." +msgstr "" + +#: src/ch10-01-syntax.md:259 +msgid "In Enum Definitions" +msgstr "" + +#: src/ch10-01-syntax.md:261 +msgid "" +"As we did with structs, we can define enums to hold generic data types in " +"their variants. Let’s take another look at the `Option` enum that the " +"standard library provides, which we used in Chapter 6:" +msgstr "" + +#: src/ch10-01-syntax.md:272 +msgid "" +"This definition should now make more sense to you. As you can see, the " +"`Option` enum is generic over type `T` and has two variants: `Some`, " +"which holds one value of type `T`, and a `None` variant that doesn’t hold " +"any value. By using the `Option` enum, we can express the abstract " +"concept of an optional value, and because `Option` is generic, we can use " +"this abstraction no matter what the type of the optional value is." +msgstr "" + +#: src/ch10-01-syntax.md:279 +msgid "" +"Enums can use multiple generic types as well. The definition of the `Result` " +"enum that we used in Chapter 9 is one example:" +msgstr "" + +#: src/ch10-01-syntax.md:289 +msgid "" +"The `Result` enum is generic over two types, `T` and `E`, and has two " +"variants: `Ok`, which holds a value of type `T`, and `Err`, which holds a " +"value of type `E`. This definition makes it convenient to use the `Result` " +"enum anywhere we have an operation that might succeed (return a value of " +"some type `T`) or fail (return an error of some type `E`). In fact, this is " +"what we used to open a file in Listing 9-3, where `T` was filled in with the " +"type `std::fs::File` when the file was opened successfully and `E` was " +"filled in with the type `std::io::Error` when there were problems opening " +"the file." +msgstr "" + +#: src/ch10-01-syntax.md:298 +msgid "" +"When you recognize situations in your code with multiple struct or enum " +"definitions that differ only in the types of the values they hold, you can " +"avoid duplication by using generic types instead." +msgstr "" + +#: src/ch10-01-syntax.md:302 +msgid "In Method Definitions" +msgstr "" + +#: src/ch10-01-syntax.md:304 +msgid "" +"We can implement methods on structs and enums (as we did in Chapter 5) and " +"use generic types in their definitions too. Listing 10-9 shows the " +"`Point` struct we defined in Listing 10-6 with a method named `x` " +"implemented on it." +msgstr "" + +#: src/ch10-01-syntax.md:325 src/ch10-01-syntax.md:374 +msgid "\"p.x = {}\"" +msgstr "" + +#: src/ch10-01-syntax.md:329 +msgid "" +"Listing 10-9: Implementing a method named `x` on the " +"`Point` struct that will return a reference to the `x` field of type `T`" +msgstr "" + +#: src/ch10-01-syntax.md:333 +msgid "" +"Here, we’ve defined a method named `x` on `Point` that returns a " +"reference to the data in the field `x`." +msgstr "" + +#: src/ch10-01-syntax.md:336 +msgid "" +"Note that we have to declare `T` just after `impl` so we can use `T` to " +"specify that we’re implementing methods on the type `Point`. By declaring " +"`T` as a generic type after `impl`, Rust can identify that the type in the " +"angle brackets in `Point` is a generic type rather than a concrete type. We " +"could have chosen a different name for this generic parameter than the " +"generic parameter declared in the struct definition, but using the same name " +"is conventional. Methods written within an `impl` that declares the generic " +"type will be defined on any instance of the type, no matter what concrete " +"type ends up substituting for the generic type." +msgstr "" + +#: src/ch10-01-syntax.md:346 +msgid "" +"We can also specify constraints on generic types when defining methods on " +"the type. We could, for example, implement methods only on `Point` " +"instances rather than on `Point` instances with any generic type. In " +"Listing 10-10 we use the concrete type `f32`, meaning we don’t declare any " +"types after `impl`." +msgstr "" + +#: src/ch10-01-syntax.md:378 +msgid "" +"Listing 10-10: An `impl` block that only applies to " +"a struct with a particular concrete type for the generic type parameter `T`" +msgstr "" + +#: src/ch10-01-syntax.md:381 +msgid "" +"This code means the type `Point` will have a `distance_from_origin` " +"method; other instances of `Point` where `T` is not of type `f32` will " +"not have this method defined. The method measures how far our point is from " +"the point at coordinates (0.0, 0.0) and uses mathematical operations that " +"are available only for floating-point types." +msgstr "" + +#: src/ch10-01-syntax.md:387 +msgid "" +"Generic type parameters in a struct definition aren’t always the same as " +"those you use in that same struct’s method signatures. Listing 10-11 uses " +"the generic types `X1` and `Y1` for the `Point` struct and `X2` `Y2` for the " +"`mixup` method signature to make the example clearer. The method creates a " +"new `Point` instance with the `x` value from the `self` `Point` (of type " +"`X1`) and the `y` value from the passed-in `Point` (of type `Y2`)." +msgstr "" + +#: src/ch10-01-syntax.md:413 src/ch18-01-all-the-places-for-patterns.md:156 +#: src/ch18-03-pattern-syntax.md:142 +msgid "'c'" +msgstr "" + +#: src/ch10-01-syntax.md:417 +msgid "\"p3.x = {}, p3.y = {}\"" +msgstr "" + +#: src/ch10-01-syntax.md:421 +msgid "" +"Listing 10-11: A method that uses generic types " +"different from its struct’s definition" +msgstr "" + +#: src/ch10-01-syntax.md:424 +msgid "" +"In `main`, we’ve defined a `Point` that has an `i32` for `x` (with value " +"`5`) and an `f64` for `y` (with value `10.4`). The `p2` variable is a " +"`Point` struct that has a string slice for `x` (with value `\"Hello\"`) and " +"a `char` for `y` (with value `c`). Calling `mixup` on `p1` with the argument " +"`p2` gives us `p3`, which will have an `i32` for `x` because `x` came from " +"`p1`. The `p3` variable will have a `char` for `y` because `y` came from " +"`p2`. The `println!` macro call will print `p3.x = 5, p3.y = c`." +msgstr "" + +#: src/ch10-01-syntax.md:432 +msgid "" +"The purpose of this example is to demonstrate a situation in which some " +"generic parameters are declared with `impl` and some are declared with the " +"method definition. Here, the generic parameters `X1` and `Y1` are declared " +"after `impl` because they go with the struct definition. The generic " +"parameters `X2` and `Y2` are declared after `fn mixup` because they’re only " +"relevant to the method." +msgstr "" + +#: src/ch10-01-syntax.md:439 +msgid "Performance of Code Using Generics" +msgstr "" + +#: src/ch10-01-syntax.md:441 +msgid "" +"You might be wondering whether there is a runtime cost when using generic " +"type parameters. The good news is that using generic types won’t make your " +"program run any slower than it would with concrete types." +msgstr "" + +#: src/ch10-01-syntax.md:445 +msgid "" +"Rust accomplishes this by performing monomorphization of the code using " +"generics at compile time. _Monomorphization_ is the process of turning " +"generic code into specific code by filling in the concrete types that are " +"used when compiled. In this process, the compiler does the opposite of the " +"steps we used to create the generic function in Listing 10-5: the compiler " +"looks at all the places where generic code is called and generates code for " +"the concrete types the generic code is called with." +msgstr "" + +#: src/ch10-01-syntax.md:453 +msgid "" +"Let’s look at how this works by using the standard library’s generic " +"`Option` enum:" +msgstr "" + +#: src/ch10-01-syntax.md:461 +msgid "" +"When Rust compiles this code, it performs monomorphization. During that " +"process, the compiler reads the values that have been used in `Option` " +"instances and identifies two kinds of `Option`: one is `i32` and the " +"other is `f64`. As such, it expands the generic definition of `Option` " +"into two definitions specialized to `i32` and `f64`, thereby replacing the " +"generic definition with the specific ones." +msgstr "" + +#: src/ch10-01-syntax.md:468 +msgid "" +"The monomorphized version of the code looks similar to the following (the " +"compiler uses different names than what we’re using here for illustration):" +msgstr "" + +#: src/ch10-01-syntax.md:490 +msgid "" +"The generic `Option` is replaced with the specific definitions created by " +"the compiler. Because Rust compiles generic code into code that specifies " +"the type in each instance, we pay no runtime cost for using generics. When " +"the code runs, it performs just as it would if we had duplicated each " +"definition by hand. The process of monomorphization makes Rust’s generics " +"extremely efficient at runtime." +msgstr "" + +#: src/ch10-02-traits.md:3 +msgid "" +"A _trait_ defines the functionality a particular type has and can share with " +"other types. We can use traits to define shared behavior in an abstract way. " +"We can use _trait bounds_ to specify that a generic type can be any type " +"that has certain behavior." +msgstr "" + +#: src/ch10-02-traits.md:8 +msgid "" +"Note: Traits are similar to a feature often called _interfaces_ in other " +"languages, although with some differences." +msgstr "" + +#: src/ch10-02-traits.md:11 +msgid "Defining a Trait" +msgstr "" + +#: src/ch10-02-traits.md:13 +msgid "" +"A type’s behavior consists of the methods we can call on that type. " +"Different types share the same behavior if we can call the same methods on " +"all of those types. Trait definitions are a way to group method signatures " +"together to define a set of behaviors necessary to accomplish some purpose." +msgstr "" + +#: src/ch10-02-traits.md:18 +msgid "" +"For example, let’s say we have multiple structs that hold various kinds and " +"amounts of text: a `NewsArticle` struct that holds a news story filed in a " +"particular location and a `Tweet` that can have, at most, 280 characters " +"along with metadata that indicates whether it was a new tweet, a retweet, or " +"a reply to another tweet." +msgstr "" + +#: src/ch10-02-traits.md:24 +msgid "" +"We want to make a media aggregator library crate named `aggregator` that can " +"display summaries of data that might be stored in a `NewsArticle` or `Tweet` " +"instance. To do this, we need a summary from each type, and we’ll request " +"that summary by calling a `summarize` method on an instance. Listing 10-12 " +"shows the definition of a public `Summary` trait that expresses this " +"behavior." +msgstr "" + +#: src/ch10-02-traits.md:38 +msgid "" +"Listing 10-12: A `Summary` trait that consists of " +"the behavior provided by a `summarize` method" +msgstr "" + +#: src/ch10-02-traits.md:41 +msgid "" +"Here, we declare a trait using the `trait` keyword and then the trait’s " +"name, which is `Summary` in this case. We also declare the trait as `pub` so " +"that crates depending on this crate can make use of this trait too, as we’ll " +"see in a few examples. Inside the curly brackets, we declare the method " +"signatures that describe the behaviors of the types that implement this " +"trait, which in this case is `fn summarize(&self) -> String`." +msgstr "" + +#: src/ch10-02-traits.md:48 +msgid "" +"After the method signature, instead of providing an implementation within " +"curly brackets, we use a semicolon. Each type implementing this trait must " +"provide its own custom behavior for the body of the method. The compiler " +"will enforce that any type that has the `Summary` trait will have the method " +"`summarize` defined with this signature exactly." +msgstr "" + +#: src/ch10-02-traits.md:54 +msgid "" +"A trait can have multiple methods in its body: the method signatures are " +"listed one per line, and each line ends in a semicolon." +msgstr "" + +#: src/ch10-02-traits.md:57 +msgid "Implementing a Trait on a Type" +msgstr "" + +#: src/ch10-02-traits.md:59 +msgid "" +"Now that we’ve defined the desired signatures of the `Summary` trait’s " +"methods, we can implement it on the types in our media aggregator. Listing " +"10-13 shows an implementation of the `Summary` trait on the `NewsArticle` " +"struct that uses the headline, the author, and the location to create the " +"return value of `summarize`. For the `Tweet` struct, we define `summarize` " +"as the username followed by the entire text of the tweet, assuming that the " +"tweet content is already limited to 280 characters." +msgstr "" + +#: src/ch10-02-traits.md:83 src/ch10-02-traits.md:347 src/ch10-02-traits.md:485 +#: src/ch10-02-traits.md:544 +msgid "\"{}, by {} ({})\"" +msgstr "" + +#: src/ch10-02-traits.md:96 src/ch10-02-traits.md:197 src/ch10-02-traits.md:360 +#: src/ch10-02-traits.md:498 src/ch10-02-traits.md:557 +msgid "\"{}: {}\"" +msgstr "" + +#: src/ch10-02-traits.md:101 +msgid "" +"Listing 10-13: Implementing the `Summary` trait on " +"the `NewsArticle` and `Tweet` types" +msgstr "" + +#: src/ch10-02-traits.md:104 +msgid "" +"Implementing a trait on a type is similar to implementing regular methods. " +"The difference is that after `impl`, we put the trait name we want to " +"implement, then use the `for` keyword, and then specify the name of the type " +"we want to implement the trait for. Within the `impl` block, we put the " +"method signatures that the trait definition has defined. Instead of adding a " +"semicolon after each signature, we use curly brackets and fill in the method " +"body with the specific behavior that we want the methods of the trait to " +"have for the particular type." +msgstr "" + +#: src/ch10-02-traits.md:112 +msgid "" +"Now that the library has implemented the `Summary` trait on `NewsArticle` " +"and `Tweet`, users of the crate can call the trait methods on instances of " +"`NewsArticle` and `Tweet` in the same way we call regular methods. The only " +"difference is that the user must bring the trait into scope as well as the " +"types. Here’s an example of how a binary crate could use our `aggregator` " +"library crate:" +msgstr "" + +#: src/ch10-02-traits.md:124 src/ch10-02-traits.md:307 +#: src/ch10-02-traits.md:504 src/ch10-02-traits.md:576 +msgid "\"horse_ebooks\"" +msgstr "" + +#: src/ch10-02-traits.md:126 src/ch10-02-traits.md:309 +#: src/ch10-02-traits.md:506 src/ch10-02-traits.md:578 +msgid "\"of course, as you probably already know, people\"" +msgstr "" + +#: src/ch10-02-traits.md:132 src/ch10-02-traits.md:315 +msgid "\"1 new tweet: {}\"" +msgstr "" + +#: src/ch10-02-traits.md:136 +msgid "" +"This code prints `1 new tweet: horse_ebooks: of course, as you probably " +"already know, people`." +msgstr "" + +#: src/ch10-02-traits.md:139 +msgid "" +"Other crates that depend on the `aggregator` crate can also bring the " +"`Summary` trait into scope to implement `Summary` on their own types. One " +"restriction to note is that we can implement a trait on a type only if " +"either the trait or the type, or both, are local to our crate. For example, " +"we can implement standard library traits like `Display` on a custom type " +"like `Tweet` as part of our `aggregator` crate functionality because the " +"type `Tweet` is local to our `aggregator` crate. We can also implement " +"`Summary` on `Vec` in our `aggregator` crate because the trait `Summary` " +"is local to our `aggregator` crate." +msgstr "" + +#: src/ch10-02-traits.md:149 +msgid "" +"But we can’t implement external traits on external types. For example, we " +"can’t implement the `Display` trait on `Vec` within our `aggregator` " +"crate because `Display` and `Vec` are both defined in the standard " +"library and aren’t local to our `aggregator` crate. This restriction is part " +"of a property called _coherence_, and more specifically the _orphan rule_, " +"so named because the parent type is not present. This rule ensures that " +"other people’s code can’t break your code and vice versa. Without the rule, " +"two crates could implement the same trait for the same type, and Rust " +"wouldn’t know which implementation to use." +msgstr "" + +#: src/ch10-02-traits.md:159 +msgid "Default Implementations" +msgstr "" + +#: src/ch10-02-traits.md:161 +msgid "" +"Sometimes it’s useful to have default behavior for some or all of the " +"methods in a trait instead of requiring implementations for all methods on " +"every type. Then, as we implement the trait on a particular type, we can " +"keep or override each method’s default behavior." +msgstr "" + +#: src/ch10-02-traits.md:166 +msgid "" +"In Listing 10-14, we specify a default string for the `summarize` method of " +"the `Summary` trait instead of only defining the method signature, as we did " +"in Listing 10-12." +msgstr "" + +#: src/ch10-02-traits.md:175 +msgid "\"(Read more...)\"" +msgstr "" + +#: src/ch10-02-traits.md:202 +msgid "" +"Listing 10-14: Defining a `Summary` trait with a " +"default implementation of the `summarize` method" +msgstr "" + +#: src/ch10-02-traits.md:205 +msgid "" +"To use a default implementation to summarize instances of `NewsArticle`, we " +"specify an empty `impl` block with `impl Summary for NewsArticle {}`." +msgstr "" + +#: src/ch10-02-traits.md:208 +msgid "" +"Even though we’re no longer defining the `summarize` method on `NewsArticle` " +"directly, we’ve provided a default implementation and specified that " +"`NewsArticle` implements the `Summary` trait. As a result, we can still call " +"the `summarize` method on an instance of `NewsArticle`, like this:" +msgstr "" + +#: src/ch10-02-traits.md:218 src/ch10-02-traits.md:565 +msgid "\"Penguins win the Stanley Cup Championship!\"" +msgstr "" + +#: src/ch10-02-traits.md:219 src/ch10-02-traits.md:567 +msgid "\"Pittsburgh, PA, USA\"" +msgstr "" + +#: src/ch10-02-traits.md:220 src/ch10-02-traits.md:568 +msgid "\"Iceburgh\"" +msgstr "" + +#: src/ch10-02-traits.md:222 +msgid "" +"\"The Pittsburgh Penguins once again are the best \\\n" +" hockey team in the NHL.\"" +msgstr "" + +#: src/ch10-02-traits.md:227 +msgid "\"New article available! {}\"" +msgstr "" + +#: src/ch10-02-traits.md:231 +msgid "This code prints `New article available! (Read more...)`." +msgstr "" + +#: src/ch10-02-traits.md:233 +msgid "" +"Creating a default implementation doesn’t require us to change anything " +"about the implementation of `Summary` on `Tweet` in Listing 10-13. The " +"reason is that the syntax for overriding a default implementation is the " +"same as the syntax for implementing a trait method that doesn’t have a " +"default implementation." +msgstr "" + +#: src/ch10-02-traits.md:238 +msgid "" +"Default implementations can call other methods in the same trait, even if " +"those other methods don’t have a default implementation. In this way, a " +"trait can provide a lot of useful functionality and only require " +"implementors to specify a small part of it. For example, we could define the " +"`Summary` trait to have a `summarize_author` method whose implementation is " +"required, and then define a `summarize` method that has a default " +"implementation that calls the `summarize_author` method:" +msgstr "" + +#: src/ch10-02-traits.md:251 src/ch10-02-traits.md:277 +msgid "\"(Read more from {}...)\"" +msgstr "" + +#: src/ch10-02-traits.md:264 src/ch10-02-traits.md:290 +msgid "\"@{}\"" +msgstr "" + +#: src/ch10-02-traits.md:269 +msgid "" +"To use this version of `Summary`, we only need to define `summarize_author` " +"when we implement the trait on a type:" +msgstr "" + +#: src/ch10-02-traits.md:295 +msgid "" +"After we define `summarize_author`, we can call `summarize` on instances of " +"the `Tweet` struct, and the default implementation of `summarize` will call " +"the definition of `summarize_author` that we’ve provided. Because we’ve " +"implemented `summarize_author`, the `Summary` trait has given us the " +"behavior of the `summarize` method without requiring us to write any more " +"code. Here’s what that looks like:" +msgstr "" + +#: src/ch10-02-traits.md:319 +msgid "This code prints `1 new tweet: (Read more from @horse_ebooks...)`." +msgstr "" + +#: src/ch10-02-traits.md:321 +msgid "" +"Note that it isn’t possible to call the default implementation from an " +"overriding implementation of that same method." +msgstr "" + +#: src/ch10-02-traits.md:324 +msgid "Traits as Parameters" +msgstr "" + +#: src/ch10-02-traits.md:326 +msgid "" +"Now that you know how to define and implement traits, we can explore how to " +"use traits to define functions that accept many different types. We’ll use " +"the `Summary` trait we implemented on the `NewsArticle` and `Tweet` types in " +"Listing 10-13 to define a `notify` function that calls the `summarize` " +"method on its `item` parameter, which is of some type that implements the " +"`Summary` trait. To do this, we use the `impl Trait` syntax, like this:" +msgstr "" + +#: src/ch10-02-traits.md:365 src/ch10-02-traits.md:387 +msgid "\"Breaking news! {}\"" +msgstr "" + +#: src/ch10-02-traits.md:369 +msgid "" +"Instead of a concrete type for the `item` parameter, we specify the `impl` " +"keyword and the trait name. This parameter accepts any type that implements " +"the specified trait. In the body of `notify`, we can call any methods on " +"`item` that come from the `Summary` trait, such as `summarize`. We can call " +"`notify` and pass in any instance of `NewsArticle` or `Tweet`. Code that " +"calls the function with any other type, such as a `String` or an `i32`, " +"won’t compile because those types don’t implement `Summary`." +msgstr "" + +#: src/ch10-02-traits.md:378 +msgid "" +msgstr "" + +#: src/ch10-02-traits.md:380 +msgid "Trait Bound Syntax" +msgstr "" + +#: src/ch10-02-traits.md:382 +msgid "" +"The `impl Trait` syntax works for straightforward cases but is actually " +"syntax sugar for a longer form known as a _trait bound_; it looks like this:" +msgstr "" + +#: src/ch10-02-traits.md:391 +msgid "" +"This longer form is equivalent to the example in the previous section but is " +"more verbose. We place trait bounds with the declaration of the generic type " +"parameter after a colon and inside angle brackets." +msgstr "" + +#: src/ch10-02-traits.md:395 +msgid "" +"The `impl Trait` syntax is convenient and makes for more concise code in " +"simple cases, while the fuller trait bound syntax can express more " +"complexity in other cases. For example, we can have two parameters that " +"implement `Summary`. Doing so with the `impl Trait` syntax looks like this:" +msgstr "" + +#: src/ch10-02-traits.md:404 +msgid "" +"Using `impl Trait` is appropriate if we want this function to allow `item1` " +"and `item2` to have different types (as long as both types implement " +"`Summary`). If we want to force both parameters to have the same type, " +"however, we must use a trait bound, like this:" +msgstr "" + +#: src/ch10-02-traits.md:413 +msgid "" +"The generic type `T` specified as the type of the `item1` and `item2` " +"parameters constrains the function such that the concrete type of the value " +"passed as an argument for `item1` and `item2` must be the same." +msgstr "" + +#: src/ch10-02-traits.md:417 +msgid "Specifying Multiple Trait Bounds with the `+` Syntax" +msgstr "" + +#: src/ch10-02-traits.md:419 +msgid "" +"We can also specify more than one trait bound. Say we wanted `notify` to use " +"display formatting as well as `summarize` on `item`: we specify in the " +"`notify` definition that `item` must implement both `Display` and `Summary`. " +"We can do so using the `+` syntax:" +msgstr "" + +#: src/ch10-02-traits.md:428 +msgid "The `+` syntax is also valid with trait bounds on generic types:" +msgstr "" + +#: src/ch10-02-traits.md:434 +msgid "" +"With the two trait bounds specified, the body of `notify` can call " +"`summarize` and use `{}` to format `item`." +msgstr "" + +#: src/ch10-02-traits.md:437 +msgid "Clearer Trait Bounds with `where` Clauses" +msgstr "" + +#: src/ch10-02-traits.md:439 +msgid "" +"Using too many trait bounds has its downsides. Each generic has its own " +"trait bounds, so functions with multiple generic type parameters can contain " +"lots of trait bound information between the function’s name and its " +"parameter list, making the function signature hard to read. For this reason, " +"Rust has alternate syntax for specifying trait bounds inside a `where` " +"clause after the function signature. So, instead of writing this:" +msgstr "" + +#: src/ch10-02-traits.md:450 +msgid "we can use a `where` clause, like this:" +msgstr "" + +#: src/ch10-02-traits.md:462 +msgid "" +"This function’s signature is less cluttered: the function name, parameter " +"list, and return type are close together, similar to a function without lots " +"of trait bounds." +msgstr "" + +#: src/ch10-02-traits.md:466 +msgid "Returning Types That Implement Traits" +msgstr "" + +#: src/ch10-02-traits.md:468 +msgid "" +"We can also use the `impl Trait` syntax in the return position to return a " +"value of some type that implements a trait, as shown here:" +msgstr "" + +#: src/ch10-02-traits.md:514 +msgid "" +"By using `impl Summary` for the return type, we specify that the " +"`returns_summarizable` function returns some type that implements the " +"`Summary` trait without naming the concrete type. In this case, " +"`returns_summarizable` returns a `Tweet`, but the code calling this function " +"doesn’t need to know that." +msgstr "" + +#: src/ch10-02-traits.md:519 +msgid "" +"The ability to specify a return type only by the trait it implements is " +"especially useful in the context of closures and iterators, which we cover " +"in Chapter 13. Closures and iterators create types that only the compiler " +"knows or types that are very long to specify. The `impl Trait` syntax lets " +"you concisely specify that a function returns some type that implements the " +"`Iterator` trait without needing to write out a very long type." +msgstr "" + +#: src/ch10-02-traits.md:526 +msgid "" +"However, you can only use `impl Trait` if you’re returning a single type. " +"For example, this code that returns either a `NewsArticle` or a `Tweet` with " +"the return type specified as `impl Summary` wouldn’t work:" +msgstr "" + +#: src/ch10-02-traits.md:570 +msgid "" +"\"The Pittsburgh Penguins once again are the best \\\n" +" hockey team in the NHL.\"" +msgstr "" + +#: src/ch10-02-traits.md:587 +msgid "" +"Returning either a `NewsArticle` or a `Tweet` isn’t allowed due to " +"restrictions around how the `impl Trait` syntax is implemented in the " +"compiler. We’ll cover how to write a function with this behavior in the " +"[“Using Trait Objects That Allow for Values of Different Types”](ch17-02-" +"trait-objects.html#using-trait-objects-that-allow-for-values-of-different-" +"types) section of Chapter 17." +msgstr "" + +#: src/ch10-02-traits.md:594 +msgid "Using Trait Bounds to Conditionally Implement Methods" +msgstr "" + +#: src/ch10-02-traits.md:596 +msgid "" +"By using a trait bound with an `impl` block that uses generic type " +"parameters, we can implement methods conditionally for types that implement " +"the specified traits. For example, the type `Pair` in Listing 10-15 " +"always implements the `new` function to return a new instance of `Pair` " +"(recall from the [“Defining Methods”](ch05-03-method-syntax.html#defining-" +"methods) section of Chapter 5 that `Self` is a type alias for " +"the type of the `impl` block, which in this case is `Pair`). But in the " +"next `impl` block, `Pair` only implements the `cmp_display` method if its " +"inner type `T` implements the `PartialOrd` trait that enables comparison " +"_and_ the `Display` trait that enables printing." +msgstr "" + +#: src/ch10-02-traits.md:625 +msgid "\"The largest member is x = {}\"" +msgstr "" + +#: src/ch10-02-traits.md:627 +msgid "\"The largest member is y = {}\"" +msgstr "" + +#: src/ch10-02-traits.md:633 +msgid "" +"Listing 10-15: Conditionally implementing methods on " +"a generic type depending on trait bounds" +msgstr "" + +#: src/ch10-02-traits.md:636 +msgid "" +"We can also conditionally implement a trait for any type that implements " +"another trait. Implementations of a trait on any type that satisfies the " +"trait bounds are called _blanket implementations_ and are used extensively " +"in the Rust standard library. For example, the standard library implements " +"the `ToString` trait on any type that implements the `Display` trait. The " +"`impl` block in the standard library looks similar to this code:" +msgstr "" + +#: src/ch10-02-traits.md:649 +msgid "" +"Because the standard library has this blanket implementation, we can call " +"the `to_string` method defined by the `ToString` trait on any type that " +"implements the `Display` trait. For example, we can turn integers into their " +"corresponding `String` values like this because integers implement `Display`:" +msgstr "" + +#: src/ch10-02-traits.md:658 +msgid "" +"Blanket implementations appear in the documentation for the trait in the " +"“Implementors” section." +msgstr "" + +#: src/ch10-02-traits.md:661 +msgid "" +"Traits and trait bounds let us write code that uses generic type parameters " +"to reduce duplication but also specify to the compiler that we want the " +"generic type to have particular behavior. The compiler can then use the " +"trait bound information to check that all the concrete types used with our " +"code provide the correct behavior. In dynamically typed languages, we would " +"get an error at runtime if we called a method on a type which didn’t define " +"the method. But Rust moves these errors to compile time so we’re forced to " +"fix the problems before our code is even able to run. Additionally, we don’t " +"have to write code that checks for behavior at runtime because we’ve already " +"checked at compile time. Doing so improves performance without having to " +"give up the flexibility of generics." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:3 +msgid "" +"Lifetimes are another kind of generic that we’ve already been using. Rather " +"than ensuring that a type has the behavior we want, lifetimes ensure that " +"references are valid as long as we need them to be." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:7 +msgid "" +"One detail we didn’t discuss in the [“References and Borrowing”](ch04-02-" +"references-and-borrowing.html#references-and-borrowing) " +"section in Chapter 4 is that every reference in Rust has a _lifetime_, which " +"is the scope for which that reference is valid. Most of the time, lifetimes " +"are implicit and inferred, just like most of the time, types are inferred. " +"We must annotate types only when multiple types are possible. In a similar " +"way, we must annotate lifetimes when the lifetimes of references could be " +"related in a few different ways. Rust requires us to annotate the " +"relationships using generic lifetime parameters to ensure the actual " +"references used at runtime will definitely be valid." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:17 +msgid "" +"Annotating lifetimes is not a concept most other programming languages have, " +"so this is going to feel unfamiliar. Although we won’t cover lifetimes in " +"their entirety in this chapter, we’ll discuss common ways you might " +"encounter lifetime syntax so you can get comfortable with the concept." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:22 +msgid "Preventing Dangling References with Lifetimes" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:24 +msgid "" +"The main aim of lifetimes is to prevent _dangling references_, which cause a " +"program to reference data other than the data it’s intended to reference. " +"Consider the program in Listing 10-16, which has an outer scope and an inner " +"scope." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:38 src/ch10-03-lifetime-syntax.md:102 +#: src/ch10-03-lifetime-syntax.md:125 +msgid "\"r: {r}\"" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:42 +msgid "" +"Listing 10-16: An attempt to use a reference whose " +"value has gone out of scope" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:45 +msgid "" +"Note: The examples in Listing 10-16, 10-17, and 10-23 declare variables " +"without giving them an initial value, so the variable name exists in the " +"outer scope. At first glance, this might appear to be in conflict with " +"Rust’s having no null values. However, if we try to use a variable before " +"giving it a value, we’ll get a compile-time error, which shows that Rust " +"indeed does not allow null values." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:52 +msgid "" +"The outer scope declares a variable named `r` with no initial value, and the " +"inner scope declares a variable named `x` with the initial value of `5`. " +"Inside the inner scope, we attempt to set the value of `r` as a reference to " +"`x`. Then the inner scope ends, and we attempt to print the value in `r`. " +"This code won’t compile because the value that `r` is referring to has gone " +"out of scope before we try to use it. Here is the error message:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:59 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling chapter10 v0.1.0 (file:///projects/chapter10)\n" +"error[E0597]: `x` does not live long enough\n" +" --> src/main.rs:6:13\n" +" |\n" +"5 | let x = 5;\n" +" | - binding `x` declared here\n" +"6 | r = &x;\n" +" | ^^ borrowed value does not live long enough\n" +"7 | }\n" +" | - `x` dropped here while still borrowed\n" +"8 |\n" +"9 | println!(\"r: {r}\");\n" +" | --- borrow later used here\n" +"\n" +"For more information about this error, try `rustc --explain E0597`.\n" +"error: could not compile `chapter10` (bin \"chapter10\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:79 +msgid "" +"The error message says that the variable `x` “does not live long enough.” " +"The reason is that `x` will be out of scope when the inner scope ends on " +"line 7. But `r` is still valid for the outer scope; because its scope is " +"larger, we say that it “lives longer.” If Rust allowed this code to work, " +"`r` would be referencing memory that was deallocated when `x` went out of " +"scope, and anything we tried to do with `r` wouldn’t work correctly. So how " +"does Rust determine that this code is invalid? It uses a borrow checker." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:87 +msgid "The Borrow Checker" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:89 +msgid "" +"The Rust compiler has a _borrow checker_ that compares scopes to determine " +"whether all borrows are valid. Listing 10-17 shows the same code as Listing " +"10-16 but with annotations showing the lifetimes of the variables." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:95 +msgid "" +"// ---------+-- 'a\n" +" // |\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:97 src/ch10-03-lifetime-syntax.md:102 +msgid "// |\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:98 +msgid "// -+-- 'b |\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:99 +msgid "// | |\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:100 +msgid "" +"// -+ |\n" +" // |\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:103 +msgid "// ---------+\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:106 +msgid "" +"Listing 10-17: Annotations of the lifetimes of `r` " +"and `x`, named `'a` and `'b`, respectively" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:109 +msgid "" +"Here, we’ve annotated the lifetime of `r` with `'a` and the lifetime of `x` " +"with `'b`. As you can see, the inner `'b` block is much smaller than the " +"outer `'a` lifetime block. At compile time, Rust compares the size of the " +"two lifetimes and sees that `r` has a lifetime of `'a` but that it refers to " +"memory with a lifetime of `'b`. The program is rejected because `'b` is " +"shorter than `'a`: the subject of the reference doesn’t live as long as the " +"reference." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:116 +msgid "" +"Listing 10-18 fixes the code so it doesn’t have a dangling reference and it " +"compiles without any errors." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:121 +msgid "" +"// ----------+-- 'b\n" +" // |\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:123 +msgid "" +"// --+-- 'a |\n" +" // | |\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:125 +msgid "" +"// | |\n" +" // --+ |\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:127 +msgid "// ----------+\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:130 +msgid "" +"Listing 10-18: A valid reference because the data " +"has a longer lifetime than the reference" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:133 +msgid "" +"Here, `x` has the lifetime `'b`, which in this case is larger than `'a`. " +"This means `r` can reference `x` because Rust knows that the reference in " +"`r` will always be valid while `x` is valid." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:137 +msgid "" +"Now that you know what the lifetimes of references are and how Rust analyzes " +"lifetimes to ensure references will always be valid, let’s explore generic " +"lifetimes of parameters and return values in the context of functions." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:141 +msgid "Generic Lifetimes in Functions" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:143 +msgid "" +"We’ll write a function that returns the longer of two string slices. This " +"function will take two string slices and return a single string slice. After " +"we’ve implemented the `longest` function, the code in Listing 10-19 should " +"print `The longest string is abcd`." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:152 src/ch10-03-lifetime-syntax.md:177 +#: src/ch10-03-lifetime-syntax.md:280 src/ch10-03-lifetime-syntax.md:458 +#: src/ch10-03-lifetime-syntax.md:486 src/ch10-03-lifetime-syntax.md:840 +msgid "\"abcd\"" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:153 src/ch10-03-lifetime-syntax.md:178 +#: src/ch10-03-lifetime-syntax.md:281 src/ch10-03-lifetime-syntax.md:349 +#: src/ch10-03-lifetime-syntax.md:388 src/ch10-03-lifetime-syntax.md:487 +#: src/ch10-03-lifetime-syntax.md:841 +msgid "\"xyz\"" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:156 src/ch10-03-lifetime-syntax.md:181 +#: src/ch10-03-lifetime-syntax.md:284 src/ch10-03-lifetime-syntax.md:351 +#: src/ch10-03-lifetime-syntax.md:391 src/ch10-03-lifetime-syntax.md:462 +#: src/ch10-03-lifetime-syntax.md:490 src/ch10-03-lifetime-syntax.md:848 +msgid "\"The longest string is {result}\"" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:160 +msgid "" +"Listing 10-19: A `main` function that calls the " +"`longest` function to find the longer of two string slices" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:163 +msgid "" +"Note that we want the function to take string slices, which are references, " +"rather than strings, because we don’t want the `longest` function to take " +"ownership of its parameters. Refer to the [“String Slices as Parameters”]" +"(ch04-03-slices.html#string-slices-as-parameters) section in " +"Chapter 4 for more discussion about why the parameters we use in Listing " +"10-19 are the ones we want." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:170 +msgid "" +"If we try to implement the `longest` function as shown in Listing 10-20, it " +"won’t compile." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:193 +msgid "" +"Listing 10-20: An implementation of the `longest` " +"function that returns the longer of two string slices but does not yet " +"compile" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:197 +msgid "Instead, we get the following error that talks about lifetimes:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:199 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling chapter10 v0.1.0 (file:///projects/chapter10)\n" +"error[E0106]: missing lifetime specifier\n" +" --> src/main.rs:9:33\n" +" |\n" +"9 | fn longest(x: &str, y: &str) -> &str {\n" +" | ---- ---- ^ expected named lifetime parameter\n" +" |\n" +" = help: this function's return type contains a borrowed value, but the " +"signature does not say whether it is borrowed from `x` or `y`\n" +"help: consider introducing a named lifetime parameter\n" +" |\n" +"9 | fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {\n" +" | ++++ ++ ++ ++\n" +"\n" +"For more information about this error, try `rustc --explain E0106`.\n" +"error: could not compile `chapter10` (bin \"chapter10\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:218 +msgid "" +"The help text reveals that the return type needs a generic lifetime " +"parameter on it because Rust can’t tell whether the reference being returned " +"refers to `x` or `y`. Actually, we don’t know either, because the `if` block " +"in the body of this function returns a reference to `x` and the `else` block " +"returns a reference to `y`!" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:224 +msgid "" +"When we’re defining this function, we don’t know the concrete values that " +"will be passed into this function, so we don’t know whether the `if` case or " +"the `else` case will execute. We also don’t know the concrete lifetimes of " +"the references that will be passed in, so we can’t look at the scopes as we " +"did in Listings 10-17 and 10-18 to determine whether the reference we return " +"will always be valid. The borrow checker can’t determine this either, " +"because it doesn’t know how the lifetimes of `x` and `y` relate to the " +"lifetime of the return value. To fix this error, we’ll add generic lifetime " +"parameters that define the relationship between the references so the borrow " +"checker can perform its analysis." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:235 +msgid "Lifetime Annotation Syntax" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:237 +msgid "" +"Lifetime annotations don’t change how long any of the references live. " +"Rather, they describe the relationships of the lifetimes of multiple " +"references to each other without affecting the lifetimes. Just as functions " +"can accept any type when the signature specifies a generic type parameter, " +"functions can accept references with any lifetime by specifying a generic " +"lifetime parameter." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:243 +msgid "" +"Lifetime annotations have a slightly unusual syntax: the names of lifetime " +"parameters must start with an apostrophe (`'`) and are usually all lowercase " +"and very short, like generic types. Most people use the name `'a` for the " +"first lifetime annotation. We place lifetime parameter annotations after the " +"`&` of a reference, using a space to separate the annotation from the " +"reference’s type." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:249 +msgid "" +"Here are some examples: a reference to an `i32` without a lifetime " +"parameter, a reference to an `i32` that has a lifetime parameter named `'a`, " +"and a mutable reference to an `i32` that also has the lifetime `'a`." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:254 +msgid "// a reference\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:255 +msgid "// a reference with an explicit lifetime\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:256 +msgid "// a mutable reference with an explicit lifetime\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:259 +msgid "" +"One lifetime annotation by itself doesn’t have much meaning because the " +"annotations are meant to tell Rust how generic lifetime parameters of " +"multiple references relate to each other. Let’s examine how the lifetime " +"annotations relate to each other in the context of the `longest` function." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:264 +msgid "Lifetime Annotations in Function Signatures" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:266 +msgid "" +"To use lifetime annotations in function signatures, we need to declare the " +"generic _lifetime_ parameters inside angle brackets between the function " +"name and the parameter list, just as we did with generic _type_ parameters." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:270 +msgid "" +"We want the signature to express the following constraint: the returned " +"reference will be valid as long as both the parameters are valid. This is " +"the relationship between lifetimes of the parameters and the return value. " +"We’ll name the lifetime `'a` and then add it to each reference, as shown in " +"Listing 10-21." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:296 +msgid "" +"Listing 10-21: The `longest` function definition " +"specifying that all the references in the signature must have the same " +"lifetime `'a`" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:300 +msgid "" +"This code should compile and produce the result we want when we use it with " +"the `main` function in Listing 10-19." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:303 +msgid "" +"The function signature now tells Rust that for some lifetime `'a`, the " +"function takes two parameters, both of which are string slices that live at " +"least as long as lifetime `'a`. The function signature also tells Rust that " +"the string slice returned from the function will live at least as long as " +"lifetime `'a`. In practice, it means that the lifetime of the reference " +"returned by the `longest` function is the same as the smaller of the " +"lifetimes of the values referred to by the function arguments. These " +"relationships are what we want Rust to use when analyzing this code." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:312 +msgid "" +"Remember, when we specify the lifetime parameters in this function " +"signature, we’re not changing the lifetimes of any values passed in or " +"returned. Rather, we’re specifying that the borrow checker should reject any " +"values that don’t adhere to these constraints. Note that the `longest` " +"function doesn’t need to know exactly how long `x` and `y` will live, only " +"that some scope can be substituted for `'a` that will satisfy this signature." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:319 +msgid "" +"When annotating lifetimes in functions, the annotations go in the function " +"signature, not in the function body. The lifetime annotations become part of " +"the contract of the function, much like the types in the signature. Having " +"function signatures contain the lifetime contract means the analysis the " +"Rust compiler does can be simpler. If there’s a problem with the way a " +"function is annotated or the way it is called, the compiler errors can point " +"to the part of our code and the constraints more precisely. If, instead, the " +"Rust compiler made more inferences about what we intended the relationships " +"of the lifetimes to be, the compiler might only be able to point to a use of " +"our code many steps away from the cause of the problem." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:330 +msgid "" +"When we pass concrete references to `longest`, the concrete lifetime that is " +"substituted for `'a` is the part of the scope of `x` that overlaps with the " +"scope of `y`. In other words, the generic lifetime `'a` will get the " +"concrete lifetime that is equal to the smaller of the lifetimes of `x` and " +"`y`. Because we’ve annotated the returned reference with the same lifetime " +"parameter `'a`, the returned reference will also be valid for the length of " +"the smaller of the lifetimes of `x` and `y`." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:338 +msgid "" +"Let’s look at how the lifetime annotations restrict the `longest` function " +"by passing in references that have different concrete lifetimes. Listing " +"10-22 is a straightforward example." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:346 src/ch10-03-lifetime-syntax.md:385 +msgid "\"long string is long\"" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:364 +msgid "" +"Listing 10-22: Using the `longest` function with " +"references to `String` values that have different concrete lifetimes" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:367 +msgid "" +"In this example, `string1` is valid until the end of the outer scope, " +"`string2` is valid until the end of the inner scope, and `result` references " +"something that is valid until the end of the inner scope. Run this code and " +"you’ll see that the borrow checker approves; it will compile and print `The " +"longest string is long string is long`." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:373 +msgid "" +"Next, let’s try an example that shows that the lifetime of the reference in " +"`result` must be the smaller lifetime of the two arguments. We’ll move the " +"declaration of the `result` variable outside the inner scope but leave the " +"assignment of the value to the `result` variable inside the scope with " +"`string2`. Then we’ll move the `println!` that uses `result` to outside the " +"inner scope, after the inner scope has ended. The code in Listing 10-23 will " +"not compile." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:403 +msgid "" +"Listing 10-23: Attempting to use `result` after " +"`string2` has gone out of scope" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:406 +msgid "When we try to compile this code, we get this error:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:408 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling chapter10 v0.1.0 (file:///projects/chapter10)\n" +"error[E0597]: `string2` does not live long enough\n" +" --> src/main.rs:6:44\n" +" |\n" +"5 | let string2 = String::from(\"xyz\");\n" +" | ------- binding `string2` declared here\n" +"6 | result = longest(string1.as_str(), string2.as_str());\n" +" | ^^^^^^^ borrowed value does " +"not live long enough\n" +"7 | }\n" +" | - `string2` dropped here while still borrowed\n" +"8 | println!(\"The longest string is {result}\");\n" +" | -------- borrow later used here\n" +"\n" +"For more information about this error, try `rustc --explain E0597`.\n" +"error: could not compile `chapter10` (bin \"chapter10\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:427 +msgid "" +"The error shows that for `result` to be valid for the `println!` statement, " +"`string2` would need to be valid until the end of the outer scope. Rust " +"knows this because we annotated the lifetimes of the function parameters and " +"return values using the same lifetime parameter `'a`." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:432 +msgid "" +"As humans, we can look at this code and see that `string1` is longer than " +"`string2`, and therefore, `result` will contain a reference to `string1`. " +"Because `string1` has not gone out of scope yet, a reference to `string1` " +"will still be valid for the `println!` statement. However, the compiler " +"can’t see that the reference is valid in this case. We’ve told Rust that the " +"lifetime of the reference returned by the `longest` function is the same as " +"the smaller of the lifetimes of the references passed in. Therefore, the " +"borrow checker disallows the code in Listing 10-23 as possibly having an " +"invalid reference." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:441 +msgid "" +"Try designing more experiments that vary the values and lifetimes of the " +"references passed in to the `longest` function and how the returned " +"reference is used. Make hypotheses about whether or not your experiments " +"will pass the borrow checker before you compile; then check to see if you’re " +"right!" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:446 +msgid "Thinking in Terms of Lifetimes" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:448 +msgid "" +"The way in which you need to specify lifetime parameters depends on what " +"your function is doing. For example, if we changed the implementation of the " +"`longest` function to always return the first parameter rather than the " +"longest string slice, we wouldn’t need to specify a lifetime on the `y` " +"parameter. The following code will compile:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:459 +msgid "\"efghijklmnopqrstuvwxyz\"" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:470 +msgid "" +"We’ve specified a lifetime parameter `'a` for the parameter `x` and the " +"return type, but not for the parameter `y`, because the lifetime of `y` does " +"not have any relationship with the lifetime of `x` or the return value." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:474 +msgid "" +"When returning a reference from a function, the lifetime parameter for the " +"return type needs to match the lifetime parameter for one of the parameters. " +"If the reference returned does _not_ refer to one of the parameters, it must " +"refer to a value created within this function. However, this would be a " +"dangling reference because the value will go out of scope at the end of the " +"function. Consider this attempted implementation of the `longest` function " +"that won’t compile:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:494 +msgid "\"really long string\"" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:499 +msgid "" +"Here, even though we’ve specified a lifetime parameter `'a` for the return " +"type, this implementation will fail to compile because the return value " +"lifetime is not related to the lifetime of the parameters at all. Here is " +"the error message we get:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:504 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling chapter10 v0.1.0 (file:///projects/chapter10)\n" +"error[E0515]: cannot return value referencing local variable `result`\n" +" --> src/main.rs:11:5\n" +" |\n" +"11 | result.as_str()\n" +" | ------^^^^^^^^^\n" +" | |\n" +" | returns a value referencing data owned by the current function\n" +" | `result` is borrowed here\n" +"\n" +"For more information about this error, try `rustc --explain E0515`.\n" +"error: could not compile `chapter10` (bin \"chapter10\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:520 +msgid "" +"The problem is that `result` goes out of scope and gets cleaned up at the " +"end of the `longest` function. We’re also trying to return a reference to " +"`result` from the function. There is no way we can specify lifetime " +"parameters that would change the dangling reference, and Rust won’t let us " +"create a dangling reference. In this case, the best fix would be to return " +"an owned data type rather than a reference so the calling function is then " +"responsible for cleaning up the value." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:528 +msgid "" +"Ultimately, lifetime syntax is about connecting the lifetimes of various " +"parameters and return values of functions. Once they’re connected, Rust has " +"enough information to allow memory-safe operations and disallow operations " +"that would create dangling pointers or otherwise violate memory safety." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:533 +msgid "Lifetime Annotations in Struct Definitions" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:535 +msgid "" +"So far, the structs we’ve defined all hold owned types. We can define " +"structs to hold references, but in that case we would need to add a lifetime " +"annotation on every reference in the struct’s definition. Listing 10-24 has " +"a struct named `ImportantExcerpt` that holds a string slice." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:548 src/ch10-03-lifetime-syntax.md:766 +#: src/ch10-03-lifetime-syntax.md:799 +msgid "\"Call me Ishmael. Some years ago...\"" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:549 src/ch10-03-lifetime-syntax.md:767 +#: src/ch10-03-lifetime-syntax.md:800 +msgid "'.'" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:556 +msgid "" +"Listing 10-24: A struct that holds a reference, " +"requiring a lifetime annotation" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:559 +msgid "" +"This struct has the single field `part` that holds a string slice, which is " +"a reference. As with generic data types, we declare the name of the generic " +"lifetime parameter inside angle brackets after the name of the struct so we " +"can use the lifetime parameter in the body of the struct definition. This " +"annotation means an instance of `ImportantExcerpt` can’t outlive the " +"reference it holds in its `part` field." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:566 +msgid "" +"The `main` function here creates an instance of the `ImportantExcerpt` " +"struct that holds a reference to the first sentence of the `String` owned by " +"the variable `novel`. The data in `novel` exists before the " +"`ImportantExcerpt` instance is created. In addition, `novel` doesn’t go out " +"of scope until after the `ImportantExcerpt` goes out of scope, so the " +"reference in the `ImportantExcerpt` instance is valid." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:573 +msgid "Lifetime Elision" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:575 +msgid "" +"You’ve learned that every reference has a lifetime and that you need to " +"specify lifetime parameters for functions or structs that use references. " +"However, we had a function in Listing 4-9, shown again in Listing 10-25, " +"that compiled without lifetime annotations." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:598 +msgid "// first_word works on slices of `String`s\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:603 +msgid "// first_word works on slices of string literals\n" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:612 +msgid "" +"Listing 10-25: A function we defined in Listing 4-9 " +"that compiled without lifetime annotations, even though the parameter and " +"return type are references" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:616 +msgid "" +"The reason this function compiles without lifetime annotations is " +"historical: in early versions (pre-1.0) of Rust, this code wouldn’t have " +"compiled because every reference needed an explicit lifetime. At that time, " +"the function signature would have been written like this:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:625 +msgid "" +"After writing a lot of Rust code, the Rust team found that Rust programmers " +"were entering the same lifetime annotations over and over in particular " +"situations. These situations were predictable and followed a few " +"deterministic patterns. The developers programmed these patterns into the " +"compiler’s code so the borrow checker could infer the lifetimes in these " +"situations and wouldn’t need explicit annotations." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:632 +msgid "" +"This piece of Rust history is relevant because it’s possible that more " +"deterministic patterns will emerge and be added to the compiler. In the " +"future, even fewer lifetime annotations might be required." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:636 +msgid "" +"The patterns programmed into Rust’s analysis of references are called the " +"_lifetime elision rules_. These aren’t rules for programmers to follow; " +"they’re a set of particular cases that the compiler will consider, and if " +"your code fits these cases, you don’t need to write the lifetimes explicitly." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:641 +msgid "" +"The elision rules don’t provide full inference. If there is still ambiguity " +"as to what lifetimes the references have after Rust applies the rules, the " +"compiler won’t guess what the lifetime of the remaining references should " +"be. Instead of guessing, the compiler will give you an error that you can " +"resolve by adding the lifetime annotations." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:647 +msgid "" +"Lifetimes on function or method parameters are called _input lifetimes_, and " +"lifetimes on return values are called _output lifetimes_." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:650 +msgid "" +"The compiler uses three rules to figure out the lifetimes of the references " +"when there aren’t explicit annotations. The first rule applies to input " +"lifetimes, and the second and third rules apply to output lifetimes. If the " +"compiler gets to the end of the three rules and there are still references " +"for which it can’t figure out lifetimes, the compiler will stop with an " +"error. These rules apply to `fn` definitions as well as `impl` blocks." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:657 +msgid "" +"The first rule is that the compiler assigns a lifetime parameter to each " +"parameter that’s a reference. In other words, a function with one parameter " +"gets one lifetime parameter: `fn foo<'a>(x: &'a i32)`; a function with two " +"parameters gets two separate lifetime parameters: `fn foo<'a, 'b>(x: &'a " +"i32, y: &'b i32)`; and so on." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:663 +msgid "" +"The second rule is that, if there is exactly one input lifetime parameter, " +"that lifetime is assigned to all output lifetime parameters: `fn foo<'a>(x: " +"&'a i32) -> &'a i32`." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:667 +msgid "" +"The third rule is that, if there are multiple input lifetime parameters, but " +"one of them is `&self` or `&mut self` because this is a method, the lifetime " +"of `self` is assigned to all output lifetime parameters. This third rule " +"makes methods much nicer to read and write because fewer symbols are " +"necessary." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:672 +msgid "" +"Let’s pretend we’re the compiler. We’ll apply these rules to figure out the " +"lifetimes of the references in the signature of the `first_word` function in " +"Listing 10-25. The signature starts without any lifetimes associated with " +"the references:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:681 +msgid "" +"Then the compiler applies the first rule, which specifies that each " +"parameter gets its own lifetime. We’ll call it `'a` as usual, so now the " +"signature is this:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:689 +msgid "" +"The second rule applies because there is exactly one input lifetime. The " +"second rule specifies that the lifetime of the one input parameter gets " +"assigned to the output lifetime, so the signature is now this:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:697 +msgid "" +"Now all the references in this function signature have lifetimes, and the " +"compiler can continue its analysis without needing the programmer to " +"annotate the lifetimes in this function signature." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:701 +msgid "" +"Let’s look at another example, this time using the `longest` function that " +"had no lifetime parameters when we started working with it in Listing 10-20:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:708 +msgid "" +"Let’s apply the first rule: each parameter gets its own lifetime. This time " +"we have two parameters instead of one, so we have two lifetimes:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:715 +msgid "" +"You can see that the second rule doesn’t apply because there is more than " +"one input lifetime. The third rule doesn’t apply either, because `longest` " +"is a function rather than a method, so none of the parameters are `self`. " +"After working through all three rules, we still haven’t figured out what the " +"return type’s lifetime is. This is why we got an error trying to compile the " +"code in Listing 10-20: the compiler worked through the lifetime elision " +"rules but still couldn’t figure out all the lifetimes of the references in " +"the signature." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:723 +msgid "" +"Because the third rule really only applies in method signatures, we’ll look " +"at lifetimes in that context next to see why the third rule means we don’t " +"have to annotate lifetimes in method signatures very often." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:727 +msgid "Lifetime Annotations in Method Definitions" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:729 +msgid "" +"When we implement methods on a struct with lifetimes, we use the same syntax " +"as that of generic type parameters shown in Listing 10-11. Where we declare " +"and use the lifetime parameters depends on whether they’re related to the " +"struct fields or the method parameters and return values." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:734 +msgid "" +"Lifetime names for struct fields always need to be declared after the `impl` " +"keyword and then used after the struct’s name because those lifetimes are " +"part of the struct’s type." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:738 +msgid "" +"In method signatures inside the `impl` block, references might be tied to " +"the lifetime of references in the struct’s fields, or they might be " +"independent. In addition, the lifetime elision rules often make it so that " +"lifetime annotations aren’t necessary in method signatures. Let’s look at " +"some examples using the struct named `ImportantExcerpt` that we defined in " +"Listing 10-24." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:744 +msgid "" +"First we’ll use a method named `level` whose only parameter is a reference " +"to `self` and whose return value is an `i32`, which is not a reference to " +"anything:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:760 src/ch10-03-lifetime-syntax.md:793 +msgid "\"Attention please: {announcement}\"" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:774 +msgid "" +"The lifetime parameter declaration after `impl` and its use after the type " +"name are required, but we’re not required to annotate the lifetime of the " +"reference to `self` because of the first elision rule." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:778 +msgid "Here is an example where the third lifetime elision rule applies:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:807 +msgid "" +"There are two input lifetimes, so Rust applies the first lifetime elision " +"rule and gives both `&self` and `announcement` their own lifetimes. Then, " +"because one of the parameters is `&self`, the return type gets the lifetime " +"of `&self`, and all lifetimes have been accounted for." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:812 +msgid "The Static Lifetime" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:814 +msgid "" +"One special lifetime we need to discuss is `'static`, which denotes that the " +"affected reference _can_ live for the entire duration of the program. All " +"string literals have the `'static` lifetime, which we can annotate as " +"follows:" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:819 +msgid "\"I have a static lifetime.\"" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:822 +msgid "" +"The text of this string is stored directly in the program’s binary, which is " +"always available. Therefore, the lifetime of all string literals is " +"`'static`." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:825 +msgid "" +"You might see suggestions to use the `'static` lifetime in error messages. " +"But before specifying `'static` as the lifetime for a reference, think about " +"whether the reference you have actually lives the entire lifetime of your " +"program or not, and whether you want it to. Most of the time, an error " +"message suggesting the `'static` lifetime results from attempting to create " +"a dangling reference or a mismatch of the available lifetimes. In such " +"cases, the solution is to fix those problems, not to specify the `'static` " +"lifetime." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:833 +msgid "Generic Type Parameters, Trait Bounds, and Lifetimes Together" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:835 +msgid "" +"Let’s briefly look at the syntax of specifying generic type parameters, " +"trait bounds, and lifetimes all in one function!" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:846 +msgid "\"Today is someone's birthday!\"" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:861 +msgid "\"Announcement! {ann}\"" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:870 +msgid "" +"This is the `longest` function from Listing 10-21 that returns the longer of " +"two string slices. But now it has an extra parameter named `ann` of the " +"generic type `T`, which can be filled in by any type that implements the " +"`Display` trait as specified by the `where` clause. This extra parameter " +"will be printed using `{}`, which is why the `Display` trait bound is " +"necessary. Because lifetimes are a type of generic, the declarations of the " +"lifetime parameter `'a` and the generic type parameter `T` go in the same " +"list inside the angle brackets after the function name." +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:881 +msgid "" +"We covered a lot in this chapter! Now that you know about generic type " +"parameters, traits and trait bounds, and generic lifetime parameters, you’re " +"ready to write code without repetition that works in many different " +"situations. Generic type parameters let you apply the code to different " +"types. Traits and trait bounds ensure that even though the types are " +"generic, they’ll have the behavior the code needs. You learned how to use " +"lifetime annotations to ensure that this flexible code won’t have any " +"dangling references. And all of this analysis happens at compile time, which " +"doesn’t affect runtime performance!" +msgstr "" + +#: src/ch10-03-lifetime-syntax.md:890 +msgid "" +"Believe it or not, there is much more to learn on the topics we discussed in " +"this chapter: Chapter 17 discusses trait objects, which are another way to " +"use traits. There are also more complex scenarios involving lifetime " +"annotations that you will only need in very advanced scenarios; for those, " +"you should read the [Rust Reference](../reference/index.html). But next, " +"you’ll learn how to write tests in Rust so you can make sure your code is " +"working the way it should." +msgstr "" + +#: src/ch11-00-testing.md:3 +msgid "" +"In his 1972 essay “The Humble Programmer,” Edsger W. Dijkstra said that " +"“Program testing can be a very effective way to show the presence of bugs, " +"but it is hopelessly inadequate for showing their absence.” That doesn’t " +"mean we shouldn’t try to test as much as we can!" +msgstr "" + +#: src/ch11-00-testing.md:8 +msgid "" +"Correctness in our programs is the extent to which our code does what we " +"intend it to do. Rust is designed with a high degree of concern about the " +"correctness of programs, but correctness is complex and not easy to prove. " +"Rust’s type system shoulders a huge part of this burden, but the type system " +"cannot catch everything. As such, Rust includes support for writing " +"automated software tests." +msgstr "" + +#: src/ch11-00-testing.md:14 +msgid "" +"Say we write a function `add_two` that adds 2 to whatever number is passed " +"to it. This function’s signature accepts an integer as a parameter and " +"returns an integer as a result. When we implement and compile that function, " +"Rust does all the type checking and borrow checking that you’ve learned so " +"far to ensure that, for instance, we aren’t passing a `String` value or an " +"invalid reference to this function. But Rust _can’t_ check that this " +"function will do precisely what we intend, which is return the parameter " +"plus 2 rather than, say, the parameter plus 10 or the parameter minus 50! " +"That’s where tests come in." +msgstr "" + +#: src/ch11-00-testing.md:23 +msgid "" +"We can write tests that assert, for example, that when we pass `3` to the " +"`add_two` function, the returned value is `5`. We can run these tests " +"whenever we make changes to our code to make sure any existing correct " +"behavior has not changed." +msgstr "" + +#: src/ch11-00-testing.md:28 +msgid "" +"Testing is a complex skill: although we can’t cover in one chapter every " +"detail about how to write good tests, in this chapter we will discuss the " +"mechanics of Rust’s testing facilities. We’ll talk about the annotations and " +"macros available to you when writing your tests, the default behavior and " +"options provided for running your tests, and how to organize tests into unit " +"tests and integration tests." +msgstr "" + +#: src/ch11-01-writing-tests.md:3 +msgid "" +"Tests are Rust functions that verify that the non-test code is functioning " +"in the expected manner. The bodies of test functions typically perform these " +"three actions:" +msgstr "" + +#: src/ch11-01-writing-tests.md:7 +msgid "Set up any needed data or state." +msgstr "" + +#: src/ch11-01-writing-tests.md:8 +msgid "Run the code you want to test." +msgstr "" + +#: src/ch11-01-writing-tests.md:9 +msgid "Assert that the results are what you expect." +msgstr "" + +#: src/ch11-01-writing-tests.md:11 +msgid "" +"Let’s look at the features Rust provides specifically for writing tests that " +"take these actions, which include the `test` attribute, a few macros, and " +"the `should_panic` attribute." +msgstr "" + +#: src/ch11-01-writing-tests.md:15 +msgid "The Anatomy of a Test Function" +msgstr "" + +#: src/ch11-01-writing-tests.md:17 +msgid "" +"At its simplest, a test in Rust is a function that’s annotated with the " +"`test` attribute. Attributes are metadata about pieces of Rust code; one " +"example is the `derive` attribute we used with structs in Chapter 5. To " +"change a function into a test function, add `#[test]` on the line before " +"`fn`. When you run your tests with the `cargo test` command, Rust builds a " +"test runner binary that runs the annotated functions and reports on whether " +"each test function passes or fails." +msgstr "" + +#: src/ch11-01-writing-tests.md:25 +msgid "" +"Whenever we make a new library project with Cargo, a test module with a test " +"function in it is automatically generated for us. This module gives you a " +"template for writing your tests so you don’t have to look up the exact " +"structure and syntax every time you start a new project. You can add as many " +"additional test functions and as many test modules as you want!" +msgstr "" + +#: src/ch11-01-writing-tests.md:31 +msgid "" +"We’ll explore some aspects of how tests work by experimenting with the " +"template test before we actually test any code. Then we’ll write some real-" +"world tests that call some code that we’ve written and assert that its " +"behavior is correct." +msgstr "" + +#: src/ch11-01-writing-tests.md:35 +msgid "" +"Let’s create a new library project called `adder` that will add two numbers:" +msgstr "" + +#: src/ch11-01-writing-tests.md:43 +msgid "" +"The contents of the _src/lib.rs_ file in your `adder` library should look " +"like Listing 11-1." +msgstr "" + +#: src/ch11-01-writing-tests.md:78 +msgid "" +"For now, let’s focus solely on the `it_works` function. Note the `#[test]` " +"annotation: this attribute indicates this is a test function, so the test " +"runner knows to treat this function as a test. We might also have non-test " +"functions in the `tests` module to help set up common scenarios or perform " +"common operations, so we always need to indicate which functions are tests." +msgstr "" + +#: src/ch11-01-writing-tests.md:84 +msgid "" +"The example function body uses the `assert_eq!` macro to assert that " +"`result`, which contains the result of adding 2 and 2, equals 4. This " +"assertion serves as an example of the format for a typical test. Let’s run " +"it to see that this test passes." +msgstr "" + +#: src/ch11-01-writing-tests.md:89 +msgid "" +"The `cargo test` command runs all tests in our project, as shown in Listing " +"11-2." +msgstr "" + +#: src/ch11-01-writing-tests.md:94 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling adder v0.1.0 (file:///projects/adder)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.57s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"adder-92948b65e88960b4)\n" +"\n" +"running 1 test\n" +"test tests::it_works ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests adder\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-01-writing-tests.md:115 +msgid "" +"Cargo compiled and ran the test. We see the line `running 1 test`. The next " +"line shows the name of the generated test function, called `tests::" +"it_works`, and that the result of running that test is `ok`. The overall " +"summary `test result: ok.` means that all the tests passed, and the portion " +"that reads `1 passed; 0 failed` totals the number of tests that passed or " +"failed." +msgstr "" + +#: src/ch11-01-writing-tests.md:121 +msgid "" +"It’s possible to mark a test as ignored so it doesn’t run in a particular " +"instance; we’ll cover that in the [“Ignoring Some Tests Unless Specifically " +"Requested”](ch11-02-running-tests.html#ignoring-some-tests-unless-" +"specifically-requested) section later in this chapter. " +"Because we haven’t done that here, the summary shows `0 ignored`." +msgstr "" + +#: src/ch11-01-writing-tests.md:126 +msgid "" +"The `0 measured` statistic is for benchmark tests that measure performance. " +"Benchmark tests are, as of this writing, only available in nightly Rust. See " +"[the documentation about benchmark tests](../unstable-book/library-features/" +"test.html) to learn more." +msgstr "" + +#: src/ch11-01-writing-tests.md:130 +msgid "" +"We can pass an argument to the `cargo test` command to run only tests whose " +"name matches a string; this is called _filtering_ and we’ll cover that in " +"the [“Running a Subset of Tests by Name”](ch11-02-running-tests.html#running-" +"a-subset-of-tests-by-name) section. Here we haven’t filtered " +"the tests being run, so the end of the summary shows `0 filtered out`." +msgstr "" + +#: src/ch11-01-writing-tests.md:136 +msgid "" +"The next part of the test output starting at `Doc-tests adder` is for the " +"results of any documentation tests. We don’t have any documentation tests " +"yet, but Rust can compile any code examples that appear in our API " +"documentation. This feature helps keep your docs and your code in sync! " +"We’ll discuss how to write documentation tests in the [“Documentation " +"Comments as Tests”](ch14-02-publishing-to-crates-io.html#documentation-" +"comments-as-tests) section of Chapter 14. For now, we’ll " +"ignore the `Doc-tests` output." +msgstr "" + +#: src/ch11-01-writing-tests.md:144 +msgid "" +"Let’s start to customize the test to our own needs. First, change the name " +"of the `it_works` function to a different name, such as `exploration`, like " +"so:" +msgstr "" + +#: src/ch11-01-writing-tests.md:166 +msgid "" +"Then run `cargo test` again. The output now shows `exploration` instead of " +"`it_works`:" +msgstr "" + +#: src/ch11-01-writing-tests.md:169 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling adder v0.1.0 (file:///projects/adder)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.59s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"adder-92948b65e88960b4)\n" +"\n" +"running 1 test\n" +"test tests::exploration ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests adder\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-01-writing-tests.md:188 +msgid "" +"Now we’ll add another test, but this time we’ll make a test that fails! " +"Tests fail when something in the test function panics. Each test is run in a " +"new thread, and when the main thread sees that a test thread has died, the " +"test is marked as failed. In Chapter 9, we talked about how the simplest way " +"to panic is to call the `panic!` macro. Enter the new test as a function " +"named `another`, so your _src/lib.rs_ file looks like Listing 11-3." +msgstr "" + +#: src/ch11-01-writing-tests.md:214 +msgid "\"Make this test fail\"" +msgstr "" + +#: src/ch11-01-writing-tests.md:221 +msgid "" +"Run the tests again using `cargo test`. The output should look like Listing " +"11-4, which shows that our `exploration` test passed and `another` failed." +msgstr "" + +#: src/ch11-01-writing-tests.md:226 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling adder v0.1.0 (file:///projects/adder)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.72s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"adder-92948b65e88960b4)\n" +"\n" +"running 2 tests\n" +"test tests::another ... FAILED\n" +"test tests::exploration ... ok\n" +"\n" +"failures:\n" +"\n" +"---- tests::another stdout ----\n" +"thread 'tests::another' panicked at src/lib.rs:17:9:\n" +"Make this test fail\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"\n" +"\n" +"failures:\n" +" tests::another\n" +"\n" +"test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered " +"out; finished in 0.00s\n" +"\n" +"error: test failed, to rerun pass `--lib`\n" +"```" +msgstr "" + +#: src/ch11-01-writing-tests.md:259 +msgid "" +"Instead of `ok`, the line `test tests::another` shows `FAILED`. Two new " +"sections appear between the individual results and the summary: the first " +"displays the detailed reason for each test failure. In this case, we get the " +"details that `another` failed because it `panicked at 'Make this test fail'` " +"on line 17 in the _src/lib.rs_ file. The next section lists just the names " +"of all the failing tests, which is useful when there are lots of tests and " +"lots of detailed failing test output. We can use the name of a failing test " +"to run just that test to more easily debug it; we’ll talk more about ways to " +"run tests in the [“Controlling How Tests Are Run”](ch11-02-running-tests." +"html#controlling-how-tests-are-run) section." +msgstr "" + +#: src/ch11-01-writing-tests.md:270 +msgid "" +"The summary line displays at the end: overall, our test result is `FAILED`. " +"We had one test pass and one test fail." +msgstr "" + +#: src/ch11-01-writing-tests.md:273 +msgid "" +"Now that you’ve seen what the test results look like in different scenarios, " +"let’s look at some macros other than `panic!` that are useful in tests." +msgstr "" + +#: src/ch11-01-writing-tests.md:276 +msgid "Checking Results with the `assert!` Macro" +msgstr "" + +#: src/ch11-01-writing-tests.md:278 +msgid "" +"The `assert!` macro, provided by the standard library, is useful when you " +"want to ensure that some condition in a test evaluates to `true`. We give " +"the `assert!` macro an argument that evaluates to a Boolean. If the value is " +"`true`, nothing happens and the test passes. If the value is `false`, the " +"`assert!` macro calls `panic!` to cause the test to fail. Using the `assert!" +"` macro helps us check that our code is functioning in the way we intend." +msgstr "" + +#: src/ch11-01-writing-tests.md:285 +msgid "" +"In Chapter 5, Listing 5-15, we used a `Rectangle` struct and a `can_hold` " +"method, which are repeated here in Listing 11-5. Let’s put this code in the " +"_src/lib.rs_ file, then write some tests for it using the `assert!` macro." +msgstr "" + +#: src/ch11-01-writing-tests.md:307 +msgid "" +"The `can_hold` method returns a Boolean, which means it’s a perfect use case " +"for the `assert!` macro. In Listing 11-6, we write a test that exercises the " +"`can_hold` method by creating a `Rectangle` instance that has a width of 8 " +"and a height of 7 and asserting that it can hold another `Rectangle` " +"instance that has a width of 5 and a height of 1." +msgstr "" + +#: src/ch11-01-writing-tests.md:350 +msgid "" +"Note the `use super::*;` line inside the `tests` module. The `tests` module " +"is a regular module that follows the usual visibility rules we covered in " +"Chapter 7 in the [“Paths for Referring to an Item in the Module Tree”]" +"(ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html) section. Because the `tests` module is an inner module, we need to bring " +"the code under test in the outer module into the scope of the inner module. " +"We use a glob here, so anything we define in the outer module is available " +"to this `tests` module." +msgstr "" + +#: src/ch11-01-writing-tests.md:359 +msgid "" +"We’ve named our test `larger_can_hold_smaller`, and we’ve created the two " +"`Rectangle` instances that we need. Then we called the `assert!` macro and " +"passed it the result of calling `larger.can_hold(&smaller)`. This expression " +"is supposed to return `true`, so our test should pass. Let’s find out!" +msgstr "" + +#: src/ch11-01-writing-tests.md:364 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling rectangle v0.1.0 (file:///projects/rectangle)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.66s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"rectangle-6584c4561e48942e)\n" +"\n" +"running 1 test\n" +"test tests::larger_can_hold_smaller ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests rectangle\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-01-writing-tests.md:383 +msgid "" +"It does pass! Let’s add another test, this time asserting that a smaller " +"rectangle cannot hold a larger rectangle:" +msgstr "" + +#: src/ch11-01-writing-tests.md:436 +msgid "" +"Because the correct result of the `can_hold` function in this case is " +"`false`, we need to negate that result before we pass it to the `assert!` " +"macro. As a result, our test will pass if `can_hold` returns `false`:" +msgstr "" + +#: src/ch11-01-writing-tests.md:440 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling rectangle v0.1.0 (file:///projects/rectangle)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.66s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"rectangle-6584c4561e48942e)\n" +"\n" +"running 2 tests\n" +"test tests::larger_can_hold_smaller ... ok\n" +"test tests::smaller_cannot_hold_larger ... ok\n" +"\n" +"test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests rectangle\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-01-writing-tests.md:460 +msgid "" +"Two tests that pass! Now let’s see what happens to our test results when we " +"introduce a bug in our code. We’ll change the implementation of the " +"`can_hold` method by replacing the greater-than sign with a less-than sign " +"when it compares the widths:" +msgstr "" + +#: src/ch11-01-writing-tests.md:513 +msgid "Running the tests now produces the following:" +msgstr "" + +#: src/ch11-01-writing-tests.md:515 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling rectangle v0.1.0 (file:///projects/rectangle)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.66s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"rectangle-6584c4561e48942e)\n" +"\n" +"running 2 tests\n" +"test tests::larger_can_hold_smaller ... FAILED\n" +"test tests::smaller_cannot_hold_larger ... ok\n" +"\n" +"failures:\n" +"\n" +"---- tests::larger_can_hold_smaller stdout ----\n" +"thread 'tests::larger_can_hold_smaller' panicked at src/lib.rs:28:9:\n" +"assertion failed: larger.can_hold(&smaller)\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"\n" +"\n" +"failures:\n" +" tests::larger_can_hold_smaller\n" +"\n" +"test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered " +"out; finished in 0.00s\n" +"\n" +"error: test failed, to rerun pass `--lib`\n" +"```" +msgstr "" + +#: src/ch11-01-writing-tests.md:541 +msgid "" +"Our tests caught the bug! Because `larger.width` is `8` and `smaller.width` " +"is `5`, the comparison of the widths in `can_hold` now returns `false`: 8 is " +"not less than 5." +msgstr "" + +#: src/ch11-01-writing-tests.md:545 +msgid "Testing Equality with the `assert_eq!` and `assert_ne!` Macros" +msgstr "" + +#: src/ch11-01-writing-tests.md:547 +msgid "" +"A common way to verify functionality is to test for equality between the " +"result of the code under test and the value you expect the code to return. " +"You could do this by using the `assert!` macro and passing it an expression " +"using the `==` operator. However, this is such a common test that the " +"standard library provides a pair of macros—`assert_eq!` and `assert_ne!`—to " +"perform this test more conveniently. These macros compare two arguments for " +"equality or inequality, respectively. They’ll also print the two values if " +"the assertion fails, which makes it easier to see _why_ the test failed; " +"conversely, the `assert!` macro only indicates that it got a `false` value " +"for the `==` expression, without printing the values that led to the `false` " +"value." +msgstr "" + +#: src/ch11-01-writing-tests.md:558 +msgid "" +"In Listing 11-7, we write a function named `add_two` that adds `2` to its " +"parameter, then we test this function using the `assert_eq!` macro." +msgstr "" + +#: src/ch11-01-writing-tests.md:582 +msgid "Let’s check that it passes!" +msgstr "" + +#: src/ch11-01-writing-tests.md:584 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling adder v0.1.0 (file:///projects/adder)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.58s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"adder-92948b65e88960b4)\n" +"\n" +"running 1 test\n" +"test tests::it_adds_two ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests adder\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-01-writing-tests.md:603 +msgid "" +"We create a variable named `result` that holds the result of calling " +"`add_two(2)`. Then we pass `result` and `4` as the arguments to `assert_eq!" +"`. The output line for this test is `test tests::it_adds_two ... ok`, and " +"the `ok` text indicates that our test passed!" +msgstr "" + +#: src/ch11-01-writing-tests.md:608 +msgid "" +"Let’s introduce a bug into our code to see what `assert_eq!` looks like when " +"it fails. Change the implementation of the `add_two` function to instead add " +"`3`:" +msgstr "" + +#: src/ch11-01-writing-tests.md:628 +msgid "Run the tests again:" +msgstr "" + +#: src/ch11-01-writing-tests.md:630 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling adder v0.1.0 (file:///projects/adder)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.61s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"adder-92948b65e88960b4)\n" +"\n" +"running 1 test\n" +"test tests::it_adds_two ... FAILED\n" +"\n" +"failures:\n" +"\n" +"---- tests::it_adds_two stdout ----\n" +"thread 'tests::it_adds_two' panicked at src/lib.rs:12:9:\n" +"assertion `left == right` failed\n" +" left: 5\n" +" right: 4\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"\n" +"\n" +"failures:\n" +" tests::it_adds_two\n" +"\n" +"test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered " +"out; finished in 0.00s\n" +"\n" +"error: test failed, to rerun pass `--lib`\n" +"```" +msgstr "" + +#: src/ch11-01-writing-tests.md:657 +msgid "" +"Our test caught the bug! The `it_adds_two` test failed, and the message " +"tells us ``assertion `left == right` failed`` and what the `left` and " +"`right` values are. This message helps us start debugging: the `left` " +"argument, where we had the result of calling `add_two(2)`, was `5` but the " +"`right` argument was `4`. You can imagine that this would be especially " +"helpful when we have a lot of tests going on." +msgstr "" + +#: src/ch11-01-writing-tests.md:664 +msgid "" +"Note that in some languages and test frameworks, the parameters to equality " +"assertion functions are called `expected` and `actual`, and the order in " +"which we specify the arguments matters. However, in Rust, they’re called " +"`left` and `right`, and the order in which we specify the value we expect " +"and the value the code produces doesn’t matter. We could write the assertion " +"in this test as `assert_eq!(4, result)`, which would produce the same " +"failure message that displays `` assertion failed: `(left == right)` ``." +msgstr "" + +#: src/ch11-01-writing-tests.md:672 +msgid "" +"The `assert_ne!` macro will pass if the two values we give it are not equal " +"and fail if they’re equal. This macro is most useful for cases when we’re " +"not sure what a value _will_ be, but we know what the value definitely " +"_shouldn’t_ be. For example, if we’re testing a function that is guaranteed " +"to change its input in some way, but the way in which the input is changed " +"depends on the day of the week that we run our tests, the best thing to " +"assert might be that the output of the function is not equal to the input." +msgstr "" + +#: src/ch11-01-writing-tests.md:680 +msgid "" +"Under the surface, the `assert_eq!` and `assert_ne!` macros use the " +"operators `==` and `!=`, respectively. When the assertions fail, these " +"macros print their arguments using debug formatting, which means the values " +"being compared must implement the `PartialEq` and `Debug` traits. All " +"primitive types and most of the standard library types implement these " +"traits. For structs and enums that you define yourself, you’ll need to " +"implement `PartialEq` to assert equality of those types. You’ll also need to " +"implement `Debug` to print the values when the assertion fails. Because both " +"traits are derivable traits, as mentioned in Listing 5-12 in Chapter 5, this " +"is usually as straightforward as adding the `#[derive(PartialEq, Debug)]` " +"annotation to your struct or enum definition. See Appendix C, [“Derivable " +"Traits,”](appendix-03-derivable-traits.html) for more details " +"about these and other derivable traits." +msgstr "" + +#: src/ch11-01-writing-tests.md:693 +msgid "Adding Custom Failure Messages" +msgstr "" + +#: src/ch11-01-writing-tests.md:695 +msgid "" +"You can also add a custom message to be printed with the failure message as " +"optional arguments to the `assert!`, `assert_eq!`, and `assert_ne!` macros. " +"Any arguments specified after the required arguments are passed along to the " +"`format!` macro (discussed in Chapter 8 in the [“Concatenation with the `+` " +"Operator or the `format!` Macro”](ch08-02-strings.html#concatenation-with-" +"the--operator-or-the-format-macro) section), so you can pass " +"a format string that contains `{}` placeholders and values to go in those " +"placeholders. Custom messages are useful for documenting what an assertion " +"means; when a test fails, you’ll have a better idea of what the problem is " +"with the code." +msgstr "" + +#: src/ch11-01-writing-tests.md:706 +msgid "" +"For example, let’s say we have a function that greets people by name and we " +"want to test that the name we pass into the function appears in the output:" +msgstr "" + +#: src/ch11-01-writing-tests.md:712 +msgid "\"Hello {name}!\"" +msgstr "" + +#: src/ch11-01-writing-tests.md:721 src/ch11-01-writing-tests.md:722 +#: src/ch11-01-writing-tests.md:748 src/ch11-01-writing-tests.md:749 +#: src/ch11-01-writing-tests.md:798 src/ch11-01-writing-tests.md:800 +msgid "\"Carol\"" +msgstr "" + +#: src/ch11-01-writing-tests.md:727 +msgid "" +"The requirements for this program haven’t been agreed upon yet, and we’re " +"pretty sure the `Hello` text at the beginning of the greeting will change. " +"We decided we don’t want to have to update the test when the requirements " +"change, so instead of checking for exact equality to the value returned from " +"the `greeting` function, we’ll just assert that the output contains the text " +"of the input parameter." +msgstr "" + +#: src/ch11-01-writing-tests.md:734 +msgid "" +"Now let’s introduce a bug into this code by changing `greeting` to exclude " +"`name` to see what the default test failure looks like:" +msgstr "" + +#: src/ch11-01-writing-tests.md:739 src/ch11-01-writing-tests.md:789 +#: src/ch18-03-pattern-syntax.md:534 src/ch18-03-pattern-syntax.md:554 +msgid "\"Hello!\"" +msgstr "" + +#: src/ch11-01-writing-tests.md:754 +msgid "Running this test produces the following:" +msgstr "" + +#: src/ch11-01-writing-tests.md:756 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling greeter v0.1.0 (file:///projects/greeter)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.91s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"greeter-170b942eb5bf5e3a)\n" +"\n" +"running 1 test\n" +"test tests::greeting_contains_name ... FAILED\n" +"\n" +"failures:\n" +"\n" +"---- tests::greeting_contains_name stdout ----\n" +"thread 'tests::greeting_contains_name' panicked at src/lib.rs:12:9:\n" +"assertion failed: result.contains(\"Carol\")\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"\n" +"\n" +"failures:\n" +" tests::greeting_contains_name\n" +"\n" +"test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered " +"out; finished in 0.00s\n" +"\n" +"error: test failed, to rerun pass `--lib`\n" +"```" +msgstr "" + +#: src/ch11-01-writing-tests.md:781 +msgid "" +"This result just indicates that the assertion failed and which line the " +"assertion is on. A more useful failure message would print the value from " +"the `greeting` function. Let’s add a custom failure message composed of a " +"format string with a placeholder filled in with the actual value we got from " +"the `greeting` function:" +msgstr "" + +#: src/ch11-01-writing-tests.md:801 +msgid "\"Greeting did not contain name, value was `{result}`\"" +msgstr "" + +#: src/ch11-01-writing-tests.md:807 +msgid "Now when we run the test, we’ll get a more informative error message:" +msgstr "" + +#: src/ch11-01-writing-tests.md:809 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling greeter v0.1.0 (file:///projects/greeter)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.93s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"greeter-170b942eb5bf5e3a)\n" +"\n" +"running 1 test\n" +"test tests::greeting_contains_name ... FAILED\n" +"\n" +"failures:\n" +"\n" +"---- tests::greeting_contains_name stdout ----\n" +"thread 'tests::greeting_contains_name' panicked at src/lib.rs:12:9:\n" +"Greeting did not contain name, value was `Hello!`\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"\n" +"\n" +"failures:\n" +" tests::greeting_contains_name\n" +"\n" +"test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered " +"out; finished in 0.00s\n" +"\n" +"error: test failed, to rerun pass `--lib`\n" +"```" +msgstr "" + +#: src/ch11-01-writing-tests.md:834 +msgid "" +"We can see the value we actually got in the test output, which would help us " +"debug what happened instead of what we were expecting to happen." +msgstr "" + +#: src/ch11-01-writing-tests.md:837 +msgid "Checking for Panics with `should_panic`" +msgstr "" + +#: src/ch11-01-writing-tests.md:839 +msgid "" +"In addition to checking return values, it’s important to check that our code " +"handles error conditions as we expect. For example, consider the `Guess` " +"type that we created in Chapter 9, Listing 9-13. Other code that uses " +"`Guess` depends on the guarantee that `Guess` instances will contain only " +"values between 1 and 100. We can write a test that ensures that attempting " +"to create a `Guess` instance with a value outside that range panics." +msgstr "" + +#: src/ch11-01-writing-tests.md:846 +msgid "" +"We do this by adding the attribute `should_panic` to our test function. The " +"test passes if the code inside the function panics; the test fails if the " +"code inside the function doesn’t panic." +msgstr "" + +#: src/ch11-01-writing-tests.md:850 +msgid "" +"Listing 11-8 shows a test that checks that the error conditions of `Guess::" +"new` happen when we expect them to." +msgstr "" + +#: src/ch11-01-writing-tests.md:884 +msgid "" +"We place the `#[should_panic]` attribute after the `#[test]` attribute and " +"before the test function it applies to. Let’s look at the result when this " +"test passes:" +msgstr "" + +#: src/ch11-01-writing-tests.md:888 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling guessing_game v0.1.0 (file:///projects/guessing_game)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.58s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"guessing_game-57d70c3acb738f4d)\n" +"\n" +"running 1 test\n" +"test tests::greater_than_100 - should panic ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests guessing_game\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-01-writing-tests.md:907 +msgid "" +"Looks good! Now let’s introduce a bug in our code by removing the condition " +"that the `new` function will panic if the value is greater than 100:" +msgstr "" + +#: src/ch11-01-writing-tests.md:938 +msgid "When we run the test in Listing 11-8, it will fail:" +msgstr "" + +#: src/ch11-01-writing-tests.md:940 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling guessing_game v0.1.0 (file:///projects/guessing_game)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.62s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"guessing_game-57d70c3acb738f4d)\n" +"\n" +"running 1 test\n" +"test tests::greater_than_100 - should panic ... FAILED\n" +"\n" +"failures:\n" +"\n" +"---- tests::greater_than_100 stdout ----\n" +"note: test did not panic as expected\n" +"\n" +"failures:\n" +" tests::greater_than_100\n" +"\n" +"test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered " +"out; finished in 0.00s\n" +"\n" +"error: test failed, to rerun pass `--lib`\n" +"```" +msgstr "" + +#: src/ch11-01-writing-tests.md:962 +msgid "" +"We don’t get a very helpful message in this case, but when we look at the " +"test function, we see that it’s annotated with `#[should_panic]`. The " +"failure we got means that the code in the test function did not cause a " +"panic." +msgstr "" + +#: src/ch11-01-writing-tests.md:966 +msgid "" +"Tests that use `should_panic` can be imprecise. A `should_panic` test would " +"pass even if the test panics for a different reason from the one we were " +"expecting. To make `should_panic` tests more precise, we can add an optional " +"`expected` parameter to the `should_panic` attribute. The test harness will " +"make sure that the failure message contains the provided text. For example, " +"consider the modified code for `Guess` in Listing 11-9 where the `new` " +"function panics with different messages depending on whether the value is " +"too small or too large." +msgstr "" + +#: src/ch11-01-writing-tests.md:988 src/ch11-01-writing-tests.md:1040 +msgid "\"Guess value must be greater than or equal to 1, got {value}.\"" +msgstr "" + +#: src/ch11-01-writing-tests.md:992 src/ch11-01-writing-tests.md:1036 +msgid "\"Guess value must be less than or equal to 100, got {value}.\"" +msgstr "" + +#: src/ch11-01-writing-tests.md:1005 src/ch11-01-writing-tests.md:1053 +msgid "\"less than or equal to 100\"" +msgstr "" + +#: src/ch11-01-writing-tests.md:1014 +msgid "" +"This test will pass because the value we put in the `should_panic` " +"attribute’s `expected` parameter is a substring of the message that the " +"`Guess::new` function panics with. We could have specified the entire panic " +"message that we expect, which in this case would be `Guess value must be " +"less than or equal to 100, got 200`. What you choose to specify depends on " +"how much of the panic message is unique or dynamic and how precise you want " +"your test to be. In this case, a substring of the panic message is enough to " +"ensure that the code in the test function executes the `else if value > 100` " +"case." +msgstr "" + +#: src/ch11-01-writing-tests.md:1023 +msgid "" +"To see what happens when a `should_panic` test with an `expected` message " +"fails, let’s again introduce a bug into our code by swapping the bodies of " +"the `if value < 1` and the `else if value > 100` blocks:" +msgstr "" + +#: src/ch11-01-writing-tests.md:1060 +msgid "This time when we run the `should_panic` test, it will fail:" +msgstr "" + +#: src/ch11-01-writing-tests.md:1062 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling guessing_game v0.1.0 (file:///projects/guessing_game)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.66s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"guessing_game-57d70c3acb738f4d)\n" +"\n" +"running 1 test\n" +"test tests::greater_than_100 - should panic ... FAILED\n" +"\n" +"failures:\n" +"\n" +"---- tests::greater_than_100 stdout ----\n" +"thread 'tests::greater_than_100' panicked at src/lib.rs:12:13:\n" +"Guess value must be greater than or equal to 1, got 200.\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"note: panic did not contain expected string\n" +" panic message: `\"Guess value must be greater than or equal to 1, got " +"200.\"`,\n" +" expected substring: `\"less than or equal to 100\"`\n" +"\n" +"failures:\n" +" tests::greater_than_100\n" +"\n" +"test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered " +"out; finished in 0.00s\n" +"\n" +"error: test failed, to rerun pass `--lib`\n" +"```" +msgstr "" + +#: src/ch11-01-writing-tests.md:1089 +msgid "" +"The failure message indicates that this test did indeed panic as we " +"expected, but the panic message did not include the expected string `less " +"than or equal to 100`. The panic message that we did get in this case was " +"`Guess value must be greater than or equal to 1, got 200.` Now we can start " +"figuring out where our bug is!" +msgstr "" + +#: src/ch11-01-writing-tests.md:1095 +msgid "Using `Result` in Tests" +msgstr "" + +#: src/ch11-01-writing-tests.md:1097 +msgid "" +"Our tests so far all panic when they fail. We can also write tests that use " +"`Result`! Here’s the test from Listing 11-1, rewritten to use " +"`Result` and return an `Err` instead of panicking:" +msgstr "" + +#: src/ch11-01-writing-tests.md:1117 +msgid "\"two plus two does not equal four\"" +msgstr "" + +#: src/ch11-01-writing-tests.md:1123 +msgid "" +"The `it_works` function now has the `Result<(), String>` return type. In the " +"body of the function, rather than calling the `assert_eq!` macro, we return " +"`Ok(())` when the test passes and an `Err` with a `String` inside when the " +"test fails." +msgstr "" + +#: src/ch11-01-writing-tests.md:1128 +msgid "" +"Writing tests so they return a `Result` enables you to use the " +"question mark operator in the body of tests, which can be a convenient way " +"to write tests that should fail if any operation within them returns an " +"`Err` variant." +msgstr "" + +#: src/ch11-01-writing-tests.md:1132 +msgid "" +"You can’t use the `#[should_panic]` annotation on tests that use `Result`. To assert that an operation returns an `Err` variant, _don’t_ use the " +"question mark operator on the `Result` value. Instead, use `assert!" +"(value.is_err())`." +msgstr "" + +#: src/ch11-01-writing-tests.md:1137 +msgid "" +"Now that you know several ways to write tests, let’s look at what is " +"happening when we run our tests and explore the different options we can use " +"with `cargo test`." +msgstr "" + +#: src/ch11-02-running-tests.md:3 +msgid "" +"Just as `cargo run` compiles your code and then runs the resultant binary, " +"`cargo test` compiles your code in test mode and runs the resultant test " +"binary. The default behavior of the binary produced by `cargo test` is to " +"run all the tests in parallel and capture output generated during test runs, " +"preventing the output from being displayed and making it easier to read the " +"output related to the test results. You can, however, specify command line " +"options to change this default behavior." +msgstr "" + +#: src/ch11-02-running-tests.md:11 +msgid "" +"Some command line options go to `cargo test`, and some go to the resultant " +"test binary. To separate these two types of arguments, you list the " +"arguments that go to `cargo test` followed by the separator `--` and then " +"the ones that go to the test binary. Running `cargo test --help` displays " +"the options you can use with `cargo test`, and running `cargo test -- --" +"help` displays the options you can use after the separator." +msgstr "" + +#: src/ch11-02-running-tests.md:18 +msgid "Running Tests in Parallel or Consecutively" +msgstr "" + +#: src/ch11-02-running-tests.md:20 +msgid "" +"When you run multiple tests, by default they run in parallel using threads, " +"meaning they finish running faster and you get feedback quicker. Because the " +"tests are running at the same time, you must make sure your tests don’t " +"depend on each other or on any shared state, including a shared environment, " +"such as the current working directory or environment variables." +msgstr "" + +#: src/ch11-02-running-tests.md:26 +msgid "" +"For example, say each of your tests runs some code that creates a file on " +"disk named _test-output.txt_ and writes some data to that file. Then each " +"test reads the data in that file and asserts that the file contains a " +"particular value, which is different in each test. Because the tests run at " +"the same time, one test might overwrite the file in the time between another " +"test writing and reading the file. The second test will then fail, not " +"because the code is incorrect but because the tests have interfered with " +"each other while running in parallel. One solution is to make sure each test " +"writes to a different file; another solution is to run the tests one at a " +"time." +msgstr "" + +#: src/ch11-02-running-tests.md:36 +msgid "" +"If you don’t want to run the tests in parallel or if you want more fine-" +"grained control over the number of threads used, you can send the `--test-" +"threads` flag and the number of threads you want to use to the test binary. " +"Take a look at the following example:" +msgstr "" + +#: src/ch11-02-running-tests.md:45 +msgid "" +"We set the number of test threads to `1`, telling the program not to use any " +"parallelism. Running the tests using one thread will take longer than " +"running them in parallel, but the tests won’t interfere with each other if " +"they share state." +msgstr "" + +#: src/ch11-02-running-tests.md:50 +msgid "Showing Function Output" +msgstr "" + +#: src/ch11-02-running-tests.md:52 +msgid "" +"By default, if a test passes, Rust’s test library captures anything printed " +"to standard output. For example, if we call `println!` in a test and the " +"test passes, we won’t see the `println!` output in the terminal; we’ll see " +"only the line that indicates the test passed. If a test fails, we’ll see " +"whatever was printed to standard output with the rest of the failure message." +msgstr "" + +#: src/ch11-02-running-tests.md:58 +msgid "" +"As an example, Listing 11-10 has a silly function that prints the value of " +"its parameter and returns 10, as well as a test that passes and a test that " +"fails." +msgstr "" + +#: src/ch11-02-running-tests.md:65 +msgid "\"I got the value {a}\"" +msgstr "" + +#: src/ch11-02-running-tests.md:89 +msgid "" +"When we run these tests with `cargo test`, we’ll see the following output:" +msgstr "" + +#: src/ch11-02-running-tests.md:91 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling silly-function v0.1.0 (file:///projects/silly-function)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.58s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"silly_function-160869f38cff9166)\n" +"\n" +"running 2 tests\n" +"test tests::this_test_will_fail ... FAILED\n" +"test tests::this_test_will_pass ... ok\n" +"\n" +"failures:\n" +"\n" +"---- tests::this_test_will_fail stdout ----\n" +"I got the value 8\n" +"thread 'tests::this_test_will_fail' panicked at src/lib.rs:19:9:\n" +"assertion `left == right` failed\n" +" left: 10\n" +" right: 5\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"\n" +"\n" +"failures:\n" +" tests::this_test_will_fail\n" +"\n" +"test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered " +"out; finished in 0.00s\n" +"\n" +"error: test failed, to rerun pass `--lib`\n" +"```" +msgstr "" + +#: src/ch11-02-running-tests.md:120 +msgid "" +"Note that nowhere in this output do we see `I got the value 4`, which is " +"printed when the test that passes runs. That output has been captured. The " +"output from the test that failed, `I got the value 8`, appears in the " +"section of the test summary output, which also shows the cause of the test " +"failure." +msgstr "" + +#: src/ch11-02-running-tests.md:125 +msgid "" +"If we want to see printed values for passing tests as well, we can tell Rust " +"to also show the output of successful tests with `--show-output`:" +msgstr "" + +#: src/ch11-02-running-tests.md:132 +msgid "" +"When we run the tests in Listing 11-10 again with the `--show-output` flag, " +"we see the following output:" +msgstr "" + +#: src/ch11-02-running-tests.md:135 +msgid "" +"```console\n" +"$ cargo test -- --show-output\n" +" Compiling silly-function v0.1.0 (file:///projects/silly-function)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.60s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"silly_function-160869f38cff9166)\n" +"\n" +"running 2 tests\n" +"test tests::this_test_will_fail ... FAILED\n" +"test tests::this_test_will_pass ... ok\n" +"\n" +"successes:\n" +"\n" +"---- tests::this_test_will_pass stdout ----\n" +"I got the value 4\n" +"\n" +"\n" +"successes:\n" +" tests::this_test_will_pass\n" +"\n" +"failures:\n" +"\n" +"---- tests::this_test_will_fail stdout ----\n" +"I got the value 8\n" +"thread 'tests::this_test_will_fail' panicked at src/lib.rs:19:9:\n" +"assertion `left == right` failed\n" +" left: 5\n" +" right: 10\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"\n" +"\n" +"failures:\n" +" tests::this_test_will_fail\n" +"\n" +"test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered " +"out; finished in 0.00s\n" +"\n" +"error: test failed, to rerun pass `--lib`\n" +"```" +msgstr "" + +#: src/ch11-02-running-tests.md:173 +msgid "Running a Subset of Tests by Name" +msgstr "" + +#: src/ch11-02-running-tests.md:175 +msgid "" +"Sometimes, running a full test suite can take a long time. If you’re working " +"on code in a particular area, you might want to run only the tests " +"pertaining to that code. You can choose which tests to run by passing `cargo " +"test` the name or names of the test(s) you want to run as an argument." +msgstr "" + +#: src/ch11-02-running-tests.md:180 +msgid "" +"To demonstrate how to run a subset of tests, we’ll first create three tests " +"for our `add_two` function, as shown in Listing 11-11, and choose which ones " +"to run." +msgstr "" + +#: src/ch11-02-running-tests.md:216 +msgid "" +"If we run the tests without passing any arguments, as we saw earlier, all " +"the tests will run in parallel:" +msgstr "" + +#: src/ch11-02-running-tests.md:219 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling adder v0.1.0 (file:///projects/adder)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.62s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"adder-92948b65e88960b4)\n" +"\n" +"running 3 tests\n" +"test tests::add_three_and_two ... ok\n" +"test tests::add_two_and_two ... ok\n" +"test tests::one_hundred ... ok\n" +"\n" +"test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests adder\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-02-running-tests.md:240 +msgid "Running Single Tests" +msgstr "" + +#: src/ch11-02-running-tests.md:242 +msgid "" +"We can pass the name of any test function to `cargo test` to run only that " +"test:" +msgstr "" + +#: src/ch11-02-running-tests.md:244 +msgid "" +"```console\n" +"$ cargo test one_hundred\n" +" Compiling adder v0.1.0 (file:///projects/adder)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.69s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"adder-92948b65e88960b4)\n" +"\n" +"running 1 test\n" +"test tests::one_hundred ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-02-running-tests.md:257 +msgid "" +"Only the test with the name `one_hundred` ran; the other two tests didn’t " +"match that name. The test output lets us know we had more tests that didn’t " +"run by displaying `2 filtered out` at the end." +msgstr "" + +#: src/ch11-02-running-tests.md:261 +msgid "" +"We can’t specify the names of multiple tests in this way; only the first " +"value given to `cargo test` will be used. But there is a way to run multiple " +"tests." +msgstr "" + +#: src/ch11-02-running-tests.md:264 +msgid "Filtering to Run Multiple Tests" +msgstr "" + +#: src/ch11-02-running-tests.md:266 +msgid "" +"We can specify part of a test name, and any test whose name matches that " +"value will be run. For example, because two of our tests’ names contain " +"`add`, we can run those two by running `cargo test add`:" +msgstr "" + +#: src/ch11-02-running-tests.md:270 +msgid "" +"```console\n" +"$ cargo test add\n" +" Compiling adder v0.1.0 (file:///projects/adder)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.61s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"adder-92948b65e88960b4)\n" +"\n" +"running 2 tests\n" +"test tests::add_three_and_two ... ok\n" +"test tests::add_two_and_two ... ok\n" +"\n" +"test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-02-running-tests.md:284 +msgid "" +"This command ran all tests with `add` in the name and filtered out the test " +"named `one_hundred`. Also note that the module in which a test appears " +"becomes part of the test’s name, so we can run all the tests in a module by " +"filtering on the module’s name." +msgstr "" + +#: src/ch11-02-running-tests.md:289 +msgid "Ignoring Some Tests Unless Specifically Requested" +msgstr "" + +#: src/ch11-02-running-tests.md:291 +msgid "" +"Sometimes a few specific tests can be very time-consuming to execute, so you " +"might want to exclude them during most runs of `cargo test`. Rather than " +"listing as arguments all tests you do want to run, you can instead annotate " +"the time-consuming tests using the `ignore` attribute to exclude them, as " +"shown here:" +msgstr "" + +#: src/ch11-02-running-tests.md:317 +msgid "// code that takes an hour to run\n" +msgstr "" + +#: src/ch11-02-running-tests.md:322 +msgid "" +"After `#[test]`, we add the `#[ignore]` line to the test we want to exclude. " +"Now when we run our tests, `it_works` runs, but `expensive_test` doesn’t:" +msgstr "" + +#: src/ch11-02-running-tests.md:325 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling adder v0.1.0 (file:///projects/adder)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.60s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"adder-92948b65e88960b4)\n" +"\n" +"running 2 tests\n" +"test tests::expensive_test ... ignored\n" +"test tests::it_works ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests adder\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-02-running-tests.md:345 +msgid "" +"The `expensive_test` function is listed as `ignored`. If we want to run only " +"the ignored tests, we can use `cargo test -- --ignored`:" +msgstr "" + +#: src/ch11-02-running-tests.md:348 +msgid "" +"```console\n" +"$ cargo test -- --ignored\n" +" Compiling adder v0.1.0 (file:///projects/adder)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.61s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"adder-92948b65e88960b4)\n" +"\n" +"running 1 test\n" +"test expensive_test ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests adder\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-02-running-tests.md:367 +msgid "" +"By controlling which tests run, you can make sure your `cargo test` results " +"will be returned quickly. When you’re at a point where it makes sense to " +"check the results of the `ignored` tests and you have time to wait for the " +"results, you can run `cargo test -- --ignored` instead. If you want to run " +"all tests whether they’re ignored or not, you can run `cargo test -- --" +"include-ignored`." +msgstr "" + +#: src/ch11-03-test-organization.md:3 +msgid "" +"As mentioned at the start of the chapter, testing is a complex discipline, " +"and different people use different terminology and organization. The Rust " +"community thinks about tests in terms of two main categories: unit tests and " +"integration tests. _Unit tests_ are small and more focused, testing one " +"module in isolation at a time, and can test private interfaces. _Integration " +"tests_ are entirely external to your library and use your code in the same " +"way any other external code would, using only the public interface and " +"potentially exercising multiple modules per test." +msgstr "" + +#: src/ch11-03-test-organization.md:12 +msgid "" +"Writing both kinds of tests is important to ensure that the pieces of your " +"library are doing what you expect them to, separately and together." +msgstr "" + +#: src/ch11-03-test-organization.md:15 +msgid "Unit Tests" +msgstr "" + +#: src/ch11-03-test-organization.md:17 +msgid "" +"The purpose of unit tests is to test each unit of code in isolation from the " +"rest of the code to quickly pinpoint where code is and isn’t working as " +"expected. You’ll put unit tests in the _src_ directory in each file with the " +"code that they’re testing. The convention is to create a module named " +"`tests` in each file to contain the test functions and to annotate the " +"module with `cfg(test)`." +msgstr "" + +#: src/ch11-03-test-organization.md:24 +msgid "The Tests Module and `#[cfg(test)]`" +msgstr "" + +#: src/ch11-03-test-organization.md:26 +msgid "" +"The `#[cfg(test)]` annotation on the `tests` module tells Rust to compile " +"and run the test code only when you run `cargo test`, not when you run " +"`cargo build`. This saves compile time when you only want to build the " +"library and saves space in the resultant compiled artifact because the tests " +"are not included. You’ll see that because integration tests go in a " +"different directory, they don’t need the `#[cfg(test)]` annotation. However, " +"because unit tests go in the same files as the code, you’ll use " +"`#[cfg(test)]` to specify that they shouldn’t be included in the compiled " +"result." +msgstr "" + +#: src/ch11-03-test-organization.md:35 +msgid "" +"Recall that when we generated the new `adder` project in the first section " +"of this chapter, Cargo generated this code for us:" +msgstr "" + +#: src/ch11-03-test-organization.md:57 +msgid "" +"On the automatically generated `tests` module, the attribute `cfg` stands " +"for _configuration_ and tells Rust that the following item should only be " +"included given a certain configuration option. In this case, the " +"configuration option is `test`, which is provided by Rust for compiling and " +"running tests. By using the `cfg` attribute, Cargo compiles our test code " +"only if we actively run the tests with `cargo test`. This includes any " +"helper functions that might be within this module, in addition to the " +"functions annotated with `#[test]`." +msgstr "" + +#: src/ch11-03-test-organization.md:65 +msgid "Testing Private Functions" +msgstr "" + +#: src/ch11-03-test-organization.md:67 +msgid "" +"There’s debate within the testing community about whether or not private " +"functions should be tested directly, and other languages make it difficult " +"or impossible to test private functions. Regardless of which testing " +"ideology you adhere to, Rust’s privacy rules do allow you to test private " +"functions. Consider the code in Listing 11-12 with the private function " +"`internal_adder`." +msgstr "" + +#: src/ch11-03-test-organization.md:98 +msgid "" +"Note that the `internal_adder` function is not marked as `pub`. Tests are " +"just Rust code, and the `tests` module is just another module. As we " +"discussed in the [“Paths for Referring to an Item in the Module Tree”]" +"(ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html) section, items in child modules can use the items in their ancestor " +"modules. In this test, we bring all of the `tests` module’s parent’s items " +"into scope with `use super::*`, and then the test can call `internal_adder`. " +"If you don’t think private functions should be tested, there’s nothing in " +"Rust that will compel you to do so." +msgstr "" + +#: src/ch11-03-test-organization.md:107 +msgid "Integration Tests" +msgstr "" + +#: src/ch11-03-test-organization.md:109 +msgid "" +"In Rust, integration tests are entirely external to your library. They use " +"your library in the same way any other code would, which means they can only " +"call functions that are part of your library’s public API. Their purpose is " +"to test whether many parts of your library work together correctly. Units of " +"code that work correctly on their own could have problems when integrated, " +"so test coverage of the integrated code is important as well. To create " +"integration tests, you first need a _tests_ directory." +msgstr "" + +#: src/ch11-03-test-organization.md:117 +msgid "The _tests_ Directory" +msgstr "" + +#: src/ch11-03-test-organization.md:119 +msgid "" +"We create a _tests_ directory at the top level of our project directory, " +"next to _src_. Cargo knows to look for integration test files in this " +"directory. We can then make as many test files as we want, and Cargo will " +"compile each of the files as an individual crate." +msgstr "" + +#: src/ch11-03-test-organization.md:124 +msgid "" +"Let’s create an integration test. With the code in Listing 11-12 still in " +"the _src/lib.rs_ file, make a _tests_ directory, and create a new file named " +"_tests/integration_test.rs_. Your directory structure should look like this:" +msgstr "" + +#: src/ch11-03-test-organization.md:138 +msgid "" +"Enter the code in Listing 11-13 into the _tests/integration_test.rs_ file." +msgstr "" + +#: src/ch11-03-test-organization.md:154 +msgid "" +"Each file in the _tests_ directory is a separate crate, so we need to bring " +"our library into each test crate’s scope. For that reason we add `use adder::" +"add_two;` at the top of the code, which we didn’t need in the unit tests." +msgstr "" + +#: src/ch11-03-test-organization.md:158 +msgid "" +"We don’t need to annotate any code in _tests/integration_test.rs_ with " +"`#[cfg(test)]`. Cargo treats the _tests_ directory specially and compiles " +"files in this directory only when we run `cargo test`. Run `cargo test` now:" +msgstr "" + +#: src/ch11-03-test-organization.md:162 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling adder v0.1.0 (file:///projects/adder)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 1.31s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"adder-1082c4b063a8fbe6)\n" +"\n" +"running 1 test\n" +"test tests::internal ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Running tests/integration_test.rs (target/debug/deps/" +"integration_test-1082c4b063a8fbe6)\n" +"\n" +"running 1 test\n" +"test it_adds_two ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests adder\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-03-test-organization.md:188 +msgid "" +"The three sections of output include the unit tests, the integration test, " +"and the doc tests. Note that if any test in a section fails, the following " +"sections will not be run. For example, if a unit test fails, there won’t be " +"any output for integration and doc tests because those tests will only be " +"run if all unit tests are passing." +msgstr "" + +#: src/ch11-03-test-organization.md:194 +msgid "" +"The first section for the unit tests is the same as we’ve been seeing: one " +"line for each unit test (one named `internal` that we added in Listing " +"11-12) and then a summary line for the unit tests." +msgstr "" + +#: src/ch11-03-test-organization.md:198 +msgid "" +"The integration tests section starts with the line `Running tests/" +"integration_test.rs`. Next, there is a line for each test function in that " +"integration test and a summary line for the results of the integration test " +"just before the `Doc-tests adder` section starts." +msgstr "" + +#: src/ch11-03-test-organization.md:203 +msgid "" +"Each integration test file has its own section, so if we add more files in " +"the _tests_ directory, there will be more integration test sections." +msgstr "" + +#: src/ch11-03-test-organization.md:206 +msgid "" +"We can still run a particular integration test function by specifying the " +"test function’s name as an argument to `cargo test`. To run all the tests in " +"a particular integration test file, use the `--test` argument of `cargo " +"test` followed by the name of the file:" +msgstr "" + +#: src/ch11-03-test-organization.md:211 +msgid "" +"```console\n" +"$ cargo test --test integration_test\n" +" Compiling adder v0.1.0 (file:///projects/adder)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.64s\n" +" Running tests/integration_test.rs (target/debug/deps/" +"integration_test-82e7799c1bc62298)\n" +"\n" +"running 1 test\n" +"test it_adds_two ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-03-test-organization.md:224 +msgid "" +"This command runs only the tests in the _tests/integration_test.rs_ file." +msgstr "" + +#: src/ch11-03-test-organization.md:226 +msgid "Submodules in Integration Tests" +msgstr "" + +#: src/ch11-03-test-organization.md:228 +msgid "" +"As you add more integration tests, you might want to make more files in the " +"_tests_ directory to help organize them; for example, you can group the test " +"functions by the functionality they’re testing. As mentioned earlier, each " +"file in the _tests_ directory is compiled as its own separate crate, which " +"is useful for creating separate scopes to more closely imitate the way end " +"users will be using your crate. However, this means files in the _tests_ " +"directory don’t share the same behavior as files in _src_ do, as you learned " +"in Chapter 7 regarding how to separate code into modules and files." +msgstr "" + +#: src/ch11-03-test-organization.md:237 +msgid "" +"The different behavior of _tests_ directory files is most noticeable when " +"you have a set of helper functions to use in multiple integration test files " +"and you try to follow the steps in the [“Separating Modules into Different " +"Files”](ch07-05-separating-modules-into-different-files.html) " +"section of Chapter 7 to extract them into a common module. For example, if " +"we create _tests/common.rs_ and place a function named `setup` in it, we can " +"add some code to `setup` that we want to call from multiple test functions " +"in multiple test files:" +msgstr "" + +#: src/ch11-03-test-organization.md:245 +msgid "Filename: tests/common.rs" +msgstr "" + +#: src/ch11-03-test-organization.md:249 +msgid "// setup code specific to your library's tests would go here\n" +msgstr "" + +#: src/ch11-03-test-organization.md:253 +msgid "" +"When we run the tests again, we’ll see a new section in the test output for " +"the _common.rs_ file, even though this file doesn’t contain any test " +"functions nor did we call the `setup` function from anywhere:" +msgstr "" + +#: src/ch11-03-test-organization.md:257 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling adder v0.1.0 (file:///projects/adder)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.89s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"adder-92948b65e88960b4)\n" +"\n" +"running 1 test\n" +"test tests::internal ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Running tests/common.rs (target/debug/deps/common-92948b65e88960b4)\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Running tests/integration_test.rs (target/debug/deps/" +"integration_test-92948b65e88960b4)\n" +"\n" +"running 1 test\n" +"test it_adds_two ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests adder\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch11-03-test-organization.md:289 +msgid "" +"Having `common` appear in the test results with `running 0 tests` displayed " +"for it is not what we wanted. We just wanted to share some code with the " +"other integration test files. To avoid having `common` appear in the test " +"output, instead of creating _tests/common.rs_, we’ll create _tests/common/" +"mod.rs_. The project directory now looks like this:" +msgstr "" + +#: src/ch11-03-test-organization.md:306 +msgid "" +"This is the older naming convention that Rust also understands that we " +"mentioned in the [“Alternate File Paths”](ch07-05-separating-modules-into-" +"different-files.html#alternate-file-paths) section of Chapter " +"7. Naming the file this way tells Rust not to treat the `common` module as " +"an integration test file. When we move the `setup` function code into _tests/" +"common/mod.rs_ and delete the _tests/common.rs_ file, the section in the " +"test output will no longer appear. Files in subdirectories of the _tests_ " +"directory don’t get compiled as separate crates or have sections in the test " +"output." +msgstr "" + +#: src/ch11-03-test-organization.md:315 +msgid "" +"After we’ve created _tests/common/mod.rs_, we can use it from any of the " +"integration test files as a module. Here’s an example of calling the `setup` " +"function from the `it_adds_two` test in _tests/integration_test.rs_:" +msgstr "" + +#: src/ch11-03-test-organization.md:319 +msgid "Filename: tests/integration_test.rs" +msgstr "" + +#: src/ch11-03-test-organization.md:335 +msgid "" +"Note that the `mod common;` declaration is the same as the module " +"declaration we demonstrated in Listing 7-21. Then, in the test function, we " +"can call the `common::setup()` function." +msgstr "" + +#: src/ch11-03-test-organization.md:339 +msgid "Integration Tests for Binary Crates" +msgstr "" + +#: src/ch11-03-test-organization.md:341 +msgid "" +"If our project is a binary crate that only contains a _src/main.rs_ file and " +"doesn’t have a _src/lib.rs_ file, we can’t create integration tests in the " +"_tests_ directory and bring functions defined in the _src/main.rs_ file into " +"scope with a `use` statement. Only library crates expose functions that " +"other crates can use; binary crates are meant to be run on their own." +msgstr "" + +#: src/ch11-03-test-organization.md:347 +msgid "" +"This is one of the reasons Rust projects that provide a binary have a " +"straightforward _src/main.rs_ file that calls logic that lives in the _src/" +"lib.rs_ file. Using that structure, integration tests _can_ test the library " +"crate with `use` to make the important functionality available. If the " +"important functionality works, the small amount of code in the _src/main.rs_ " +"file will work as well, and that small amount of code doesn’t need to be " +"tested." +msgstr "" + +#: src/ch11-03-test-organization.md:356 +msgid "" +"Rust’s testing features provide a way to specify how code should function to " +"ensure it continues to work as you expect, even as you make changes. Unit " +"tests exercise different parts of a library separately and can test private " +"implementation details. Integration tests check that many parts of the " +"library work together correctly, and they use the library’s public API to " +"test the code in the same way external code will use it. Even though Rust’s " +"type system and ownership rules help prevent some kinds of bugs, tests are " +"still important to reduce logic bugs having to do with how your code is " +"expected to behave." +msgstr "" + +#: src/ch11-03-test-organization.md:365 +msgid "" +"Let’s combine the knowledge you learned in this chapter and in previous " +"chapters to work on a project!" +msgstr "" + +#: src/ch12-00-an-io-project.md:3 +msgid "" +"This chapter is a recap of the many skills you’ve learned so far and an " +"exploration of a few more standard library features. We’ll build a command " +"line tool that interacts with file and command line input/output to practice " +"some of the Rust concepts you now have under your belt." +msgstr "" + +#: src/ch12-00-an-io-project.md:8 +msgid "" +"Rust’s speed, safety, single binary output, and cross-platform support make " +"it an ideal language for creating command line tools, so for our project, " +"we’ll make our own version of the classic command line search tool `grep` " +"(**g**lobally search a **r**egular **e**xpression and **p**rint). In the " +"simplest use case, `grep` searches a specified file for a specified string. " +"To do so, `grep` takes as its arguments a file path and a string. Then it " +"reads the file, finds lines in that file that contain the string argument, " +"and prints those lines." +msgstr "" + +#: src/ch12-00-an-io-project.md:17 +msgid "" +"Along the way, we’ll show how to make our command line tool use the terminal " +"features that many other command line tools use. We’ll read the value of an " +"environment variable to allow the user to configure the behavior of our " +"tool. We’ll also print error messages to the standard error console stream " +"(`stderr`) instead of standard output (`stdout`), so, for example, the user " +"can redirect successful output to a file while still seeing error messages " +"onscreen." +msgstr "" + +#: src/ch12-00-an-io-project.md:24 +msgid "" +"One Rust community member, Andrew Gallant, has already created a fully " +"featured, very fast version of `grep`, called `ripgrep`. By comparison, our " +"version will be fairly simple, but this chapter will give you some of the " +"background knowledge you need to understand a real-world project such as " +"`ripgrep`." +msgstr "" + +#: src/ch12-00-an-io-project.md:30 +msgid "" +"Our `grep` project will combine a number of concepts you’ve learned so far:" +msgstr "" + +#: src/ch12-00-an-io-project.md:32 +msgid "" +"Organizing code (using what you learned about modules in [Chapter 7](ch07-00-" +"managing-growing-projects-with-packages-crates-and-modules.html))" +msgstr "" + +#: src/ch12-00-an-io-project.md:34 +msgid "" +"Using vectors and strings (collections, [Chapter 8](ch08-00-common-" +"collections.html))" +msgstr "" + +#: src/ch12-00-an-io-project.md:35 +msgid "" +"Handling errors ([Chapter 9](ch09-00-error-handling.html))" +msgstr "" + +#: src/ch12-00-an-io-project.md:36 +msgid "" +"Using traits and lifetimes where appropriate ([Chapter 10](ch10-00-generics." +"html))" +msgstr "" + +#: src/ch12-00-an-io-project.md:38 +msgid "Writing tests ([Chapter 11](ch11-00-testing.html))" +msgstr "" + +#: src/ch12-00-an-io-project.md:40 +msgid "" +"We’ll also briefly introduce closures, iterators, and trait objects, which " +"Chapters [13](ch13-00-functional-features.html) and [17]" +"(ch17-00-oop.html) will cover in detail." +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:3 +msgid "" +"Let’s create a new project with, as always, `cargo new`. We’ll call our " +"project `minigrep` to distinguish it from the `grep` tool that you might " +"already have on your system." +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:13 +msgid "" +"The first task is to make `minigrep` accept its two command line arguments: " +"the file path and a string to search for. That is, we want to be able to run " +"our program with `cargo run`, two hyphens to indicate the following " +"arguments are for our program rather than for `cargo`, a string to search " +"for, and a path to a file to search in, like so:" +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:23 +msgid "" +"Right now, the program generated by `cargo new` cannot process arguments we " +"give it. Some existing libraries on [crates.io](https://crates.io/) can help " +"with writing a program that accepts command line arguments, but because " +"you’re just learning this concept, let’s implement this capability ourselves." +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:28 +msgid "Reading the Argument Values" +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:30 +msgid "" +"To enable `minigrep` to read the values of command line arguments we pass to " +"it, we’ll need the `std::env::args` function provided in Rust’s standard " +"library. This function returns an iterator of the command line arguments " +"passed to `minigrep`. We’ll cover iterators fully in [Chapter 13](ch13-00-" +"functional-features.html). For now, you only need to know two details about iterators: iterators " +"produce a series of values, and we can call the `collect` method on an " +"iterator to turn it into a collection, such as a vector, that contains all " +"the elements the iterator produces." +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:39 +msgid "" +"The code in Listing 12-1 allows your `minigrep` program to read any command " +"line arguments passed to it and then collect the values into a vector." +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:55 +msgid "" +"First, we bring the `std::env` module into scope with a `use` statement so " +"we can use its `args` function. Notice that the `std::env::args` function is " +"nested in two levels of modules. As we discussed in [Chapter 7](ch07-04-" +"bringing-paths-into-scope-with-the-use-keyword.html#creating-idiomatic-use-" +"paths), in cases where the desired function is nested in more " +"than one module, we’ve chosen to bring the parent module into scope rather " +"than the function. By doing so, we can easily use other functions from `std::" +"env`. It’s also less ambiguous than adding `use std::env::args` and then " +"calling the function with just `args`, because `args` might easily be " +"mistaken for a function that’s defined in the current module." +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:65 +msgid "The `args` Function and Invalid Unicode" +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:67 +msgid "" +"Note that `std::env::args` will panic if any argument contains invalid " +"Unicode. If your program needs to accept arguments containing invalid " +"Unicode, use `std::env::args_os` instead. That function returns an iterator " +"that produces `OsString` values instead of `String` values. We’ve chosen to " +"use `std::env::args` here for simplicity, because `OsString` values differ " +"per platform and are more complex to work with than `String` values." +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:74 +msgid "" +"On the first line of `main`, we call `env::args`, and we immediately use " +"`collect` to turn the iterator into a vector containing all the values " +"produced by the iterator. We can use the `collect` function to create many " +"kinds of collections, so we explicitly annotate the type of `args` to " +"specify that we want a vector of strings. Although we very rarely need to " +"annotate types in Rust, `collect` is one function you do often need to " +"annotate because Rust isn’t able to infer the kind of collection you want." +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:82 +msgid "" +"Finally, we print the vector using the debug macro. Let’s try running the " +"code first with no arguments and then with two arguments:" +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:85 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.61s\n" +" Running `target/debug/minigrep`\n" +"[src/main.rs:5:5] args = [\n" +" \"target/debug/minigrep\",\n" +"]\n" +"```" +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:95 +msgid "" +"```console\n" +"$ cargo run -- needle haystack\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.57s\n" +" Running `target/debug/minigrep needle haystack`\n" +"[src/main.rs:5:5] args = [\n" +" \"target/debug/minigrep\",\n" +" \"needle\",\n" +" \"haystack\",\n" +"]\n" +"```" +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:107 +msgid "" +"Notice that the first value in the vector is `\"target/debug/minigrep\"`, " +"which is the name of our binary. This matches the behavior of the arguments " +"list in C, letting programs use the name by which they were invoked in their " +"execution. It’s often convenient to have access to the program name in case " +"you want to print it in messages or change behavior of the program based on " +"what command line alias was used to invoke the program. But for the purposes " +"of this chapter, we’ll ignore it and save only the two arguments we need." +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:115 +msgid "Saving the Argument Values in Variables" +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:117 +msgid "" +"The program is currently able to access the values specified as command line " +"arguments. Now we need to save the values of the two arguments in variables " +"so we can use the values throughout the rest of the program. We do that in " +"Listing 12-2." +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:133 +#: src/ch12-02-reading-a-file.md:42 +#: src/ch12-03-improving-error-handling-and-modularity.md:86 +msgid "\"Searching for {query}\"" +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:134 +#: src/ch12-02-reading-a-file.md:43 +#: src/ch12-03-improving-error-handling-and-modularity.md:87 +msgid "\"In file {file_path}\"" +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:140 +msgid "" +"As we saw when we printed the vector, the program’s name takes up the first " +"value in the vector at `args[0]`, so we’re starting arguments at index `1`. " +"The first argument `minigrep` takes is the string we’re searching for, so we " +"put a reference to the first argument in the variable `query`. The second " +"argument will be the file path, so we put a reference to the second argument " +"in the variable `file_path`." +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:147 +msgid "" +"We temporarily print the values of these variables to prove that the code is " +"working as we intend. Let’s run this program again with the arguments `test` " +"and `sample.txt`:" +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:151 +msgid "" +"```console\n" +"$ cargo run -- test sample.txt\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s\n" +" Running `target/debug/minigrep test sample.txt`\n" +"Searching for test\n" +"In file sample.txt\n" +"```" +msgstr "" + +#: src/ch12-01-accepting-command-line-arguments.md:160 +msgid "" +"Great, the program is working! The values of the arguments we need are being " +"saved into the right variables. Later we’ll add some error handling to deal " +"with certain potential erroneous situations, such as when the user provides " +"no arguments; for now, we’ll ignore that situation and work on adding file-" +"reading capabilities instead." +msgstr "" + +#: src/ch12-02-reading-a-file.md:3 +msgid "" +"Now we’ll add functionality to read the file specified in the `file_path` " +"argument. First, we need a sample file to test it with: we’ll use a file " +"with a small amount of text over multiple lines with some repeated words. " +"Listing 12-3 has an Emily Dickinson poem that will work well! Create a file " +"called _poem.txt_ at the root level of your project, and enter the poem “I’m " +"Nobody! Who are you?”" +msgstr "" + +#: src/ch12-02-reading-a-file.md:26 +msgid "" +"With the text in place, edit _src/main.rs_ and add code to read the file, as " +"shown in Listing 12-4." +msgstr "" + +#: src/ch12-02-reading-a-file.md:46 +#: src/ch12-03-improving-error-handling-and-modularity.md:90 +#: src/ch12-03-improving-error-handling-and-modularity.md:153 +#: src/ch12-03-improving-error-handling-and-modularity.md:248 +#: src/ch12-03-improving-error-handling-and-modularity.md:321 +#: src/ch12-03-improving-error-handling-and-modularity.md:412 +#: src/ch12-03-improving-error-handling-and-modularity.md:484 +#: src/ch12-03-improving-error-handling-and-modularity.md:581 +msgid "\"Should have been able to read the file\"" +msgstr "" + +#: src/ch12-02-reading-a-file.md:48 +#: src/ch12-03-improving-error-handling-and-modularity.md:92 +#: src/ch12-03-improving-error-handling-and-modularity.md:157 +#: src/ch12-03-improving-error-handling-and-modularity.md:250 +#: src/ch12-03-improving-error-handling-and-modularity.md:323 +#: src/ch12-03-improving-error-handling-and-modularity.md:414 +#: src/ch12-03-improving-error-handling-and-modularity.md:486 +#: src/ch12-03-improving-error-handling-and-modularity.md:583 +#: src/ch12-03-improving-error-handling-and-modularity.md:651 +#: src/ch12-03-improving-error-handling-and-modularity.md:779 +#: src/ch12-03-improving-error-handling-and-modularity.md:860 +msgid "\"With text:\\n{contents}\"" +msgstr "" + +#: src/ch12-02-reading-a-file.md:54 +msgid "" +"First, we bring in a relevant part of the standard library with a `use` " +"statement: we need `std::fs` to handle files." +msgstr "" + +#: src/ch12-02-reading-a-file.md:57 +msgid "" +"In `main`, the new statement `fs::read_to_string` takes the `file_path`, " +"opens that file, and returns a `std::io::Result` of the file’s " +"contents." +msgstr "" + +#: src/ch12-02-reading-a-file.md:60 +msgid "" +"After that, we again add a temporary `println!` statement that prints the " +"value of `contents` after the file is read, so we can check that the program " +"is working so far." +msgstr "" + +#: src/ch12-02-reading-a-file.md:64 +msgid "" +"Let’s run this code with any string as the first command line argument " +"(because we haven’t implemented the searching part yet) and the _poem.txt_ " +"file as the second argument:" +msgstr "" + +#: src/ch12-02-reading-a-file.md:68 +msgid "" +"```console\n" +"$ cargo run -- the poem.txt\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s\n" +" Running `target/debug/minigrep the poem.txt`\n" +"Searching for the\n" +"In file poem.txt\n" +"With text:\n" +"I'm nobody! Who are you?\n" +"Are you nobody, too?\n" +"Then there's a pair of us - don't tell!\n" +"They'd banish us, you know.\n" +"\n" +"How dreary to be somebody!\n" +"How public, like a frog\n" +"To tell your name the livelong day\n" +"To an admiring bog!\n" +"\n" +"```" +msgstr "" + +#: src/ch12-02-reading-a-file.md:88 +msgid "" +"Great! The code read and then printed the contents of the file. But the code " +"has a few flaws. At the moment, the `main` function has multiple " +"responsibilities: generally, functions are clearer and easier to maintain if " +"each function is responsible for only one idea. The other problem is that " +"we’re not handling errors as well as we could. The program is still small, " +"so these flaws aren’t a big problem, but as the program grows, it will be " +"harder to fix them cleanly. It’s good practice to begin refactoring early on " +"when developing a program, because it’s much easier to refactor smaller " +"amounts of code. We’ll do that next." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:3 +msgid "" +"To improve our program, we’ll fix four problems that have to do with the " +"program’s structure and how it’s handling potential errors. First, our " +"`main` function now performs two tasks: it parses arguments and reads files. " +"As our program grows, the number of separate tasks the `main` function " +"handles will increase. As a function gains responsibilities, it becomes more " +"difficult to reason about, harder to test, and harder to change without " +"breaking one of its parts. It’s best to separate functionality so each " +"function is responsible for one task." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:12 +msgid "" +"This issue also ties into the second problem: although `query` and " +"`file_path` are configuration variables to our program, variables like " +"`contents` are used to perform the program’s logic. The longer `main` " +"becomes, the more variables we’ll need to bring into scope; the more " +"variables we have in scope, the harder it will be to keep track of the " +"purpose of each. It’s best to group the configuration variables into one " +"structure to make their purpose clear." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:19 +msgid "" +"The third problem is that we’ve used `expect` to print an error message when " +"reading the file fails, but the error message just prints `Should have been " +"able to read the file`. Reading a file can fail in a number of ways: for " +"example, the file could be missing, or we might not have permission to open " +"it. Right now, regardless of the situation, we’d print the same error " +"message for everything, which wouldn’t give the user any information!" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:26 +msgid "" +"Fourth, we use `expect` to handle an error, and if the user runs our program " +"without specifying enough arguments, they’ll get an `index out of bounds` " +"error from Rust that doesn’t clearly explain the problem. It would be best " +"if all the error-handling code were in one place so future maintainers had " +"only one place to consult the code if the error-handling logic needed to " +"change. Having all the error-handling code in one place will also ensure " +"that we’re printing messages that will be meaningful to our end users." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:34 +msgid "Let’s address these four problems by refactoring our project." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:36 +msgid "Separation of Concerns for Binary Projects" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:38 +msgid "" +"The organizational problem of allocating responsibility for multiple tasks " +"to the `main` function is common to many binary projects. As a result, the " +"Rust community has developed guidelines for splitting the separate concerns " +"of a binary program when `main` starts getting large. This process has the " +"following steps:" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:44 +msgid "" +"Split your program into a _main.rs_ and a _lib.rs_ and move your program’s " +"logic to _lib.rs_." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:46 +msgid "" +"As long as your command line parsing logic is small, it can remain in _main." +"rs_." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:48 +msgid "" +"When the command line parsing logic starts getting complicated, extract it " +"from _main.rs_ and move it to _lib.rs_." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:51 +msgid "" +"The responsibilities that remain in the `main` function after this process " +"should be limited to the following:" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:54 +msgid "Calling the command line parsing logic with the argument values" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:55 +msgid "Setting up any other configuration" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:56 +msgid "Calling a `run` function in _lib.rs_" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:57 +msgid "Handling the error if `run` returns an error" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:59 +msgid "" +"This pattern is about separating concerns: _main.rs_ handles running the " +"program, and _lib.rs_ handles all the logic of the task at hand. Because you " +"can’t test the `main` function directly, this structure lets you test all of " +"your program’s logic by moving it into functions in _lib.rs_. The code that " +"remains in _main.rs_ will be small enough to verify its correctness by " +"reading it. Let’s rework our program by following this process." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:66 +msgid "Extracting the Argument Parser" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:68 +msgid "" +"We’ll extract the functionality for parsing arguments into a function that " +"`main` will call to prepare for moving the command line parsing logic to " +"_src/lib.rs_. Listing 12-5 shows the new start of `main` that calls a new " +"function `parse_config`, which we’ll define in _src/main.rs_ for the moment." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:105 +msgid "" +"We’re still collecting the command line arguments into a vector, but instead " +"of assigning the argument value at index 1 to the variable `query` and the " +"argument value at index 2 to the variable `file_path` within the `main` " +"function, we pass the whole vector to the `parse_config` function. The " +"`parse_config` function then holds the logic that determines which argument " +"goes in which variable and passes the values back to `main`. We still create " +"the `query` and `file_path` variables in `main`, but `main` no longer has " +"the responsibility of determining how the command line arguments and " +"variables correspond." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:115 +msgid "" +"This rework may seem like overkill for our small program, but we’re " +"refactoring in small, incremental steps. After making this change, run the " +"program again to verify that the argument parsing still works. It’s good to " +"check your progress often, to help identify the cause of problems when they " +"occur." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:120 +msgid "Grouping Configuration Values" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:122 +msgid "" +"We can take another small step to improve the `parse_config` function " +"further. At the moment, we’re returning a tuple, but then we immediately " +"break that tuple into individual parts again. This is a sign that perhaps we " +"don’t have the right abstraction yet." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:127 +msgid "" +"Another indicator that shows there’s room for improvement is the `config` " +"part of `parse_config`, which implies that the two values we return are " +"related and are both part of one configuration value. We’re not currently " +"conveying this meaning in the structure of the data other than by grouping " +"the two values into a tuple; we’ll instead put the two values into one " +"struct and give each of the struct fields a meaningful name. Doing so will " +"make it easier for future maintainers of this code to understand how the " +"different values relate to each other and what their purpose is." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:136 +msgid "Listing 12-6 shows the improvements to the `parse_config` function." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:149 +#: src/ch12-03-improving-error-handling-and-modularity.md:244 +#: src/ch12-03-improving-error-handling-and-modularity.md:317 +#: src/ch12-03-improving-error-handling-and-modularity.md:408 +#: src/ch12-03-improving-error-handling-and-modularity.md:480 +#: src/ch12-03-improving-error-handling-and-modularity.md:573 +#: src/ch12-03-improving-error-handling-and-modularity.md:642 +#: src/ch12-03-improving-error-handling-and-modularity.md:767 +#: src/ch12-03-improving-error-handling-and-modularity.md:892 +msgid "\"Searching for {}\"" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:150 +#: src/ch12-03-improving-error-handling-and-modularity.md:245 +#: src/ch12-03-improving-error-handling-and-modularity.md:318 +#: src/ch12-03-improving-error-handling-and-modularity.md:409 +#: src/ch12-03-improving-error-handling-and-modularity.md:481 +#: src/ch12-03-improving-error-handling-and-modularity.md:574 +#: src/ch12-03-improving-error-handling-and-modularity.md:643 +#: src/ch12-03-improving-error-handling-and-modularity.md:768 +#: src/ch12-03-improving-error-handling-and-modularity.md:893 +msgid "\"In file {}\"" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:175 +msgid "" +"We’ve added a struct named `Config` defined to have fields named `query` and " +"`file_path`. The signature of `parse_config` now indicates that it returns a " +"`Config` value. In the body of `parse_config`, where we used to return " +"string slices that reference `String` values in `args`, we now define " +"`Config` to contain owned `String` values. The `args` variable in `main` is " +"the owner of the argument values and is only letting the `parse_config` " +"function borrow them, which means we’d violate Rust’s borrowing rules if " +"`Config` tried to take ownership of the values in `args`." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:184 +msgid "" +"There are a number of ways we could manage the `String` data; the easiest, " +"though somewhat inefficient, route is to call the `clone` method on the " +"values. This will make a full copy of the data for the `Config` instance to " +"own, which takes more time and memory than storing a reference to the string " +"data. However, cloning the data also makes our code very straightforward " +"because we don’t have to manage the lifetimes of the references; in this " +"circumstance, giving up a little performance to gain simplicity is a " +"worthwhile trade-off." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:192 +msgid "The Trade-Offs of Using `clone`" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:194 +msgid "" +"There’s a tendency among many Rustaceans to avoid using `clone` to fix " +"ownership problems because of its runtime cost. In [Chapter 13](ch13-00-" +"functional-features.html), you’ll learn how to use more " +"efficient methods in this type of situation. But for now, it’s okay to copy " +"a few strings to continue making progress because you’ll make these copies " +"only once and your file path and query string are very small. It’s better to " +"have a working program that’s a bit inefficient than to try to hyperoptimize " +"code on your first pass. As you become more experienced with Rust, it’ll be " +"easier to start with the most efficient solution, but for now, it’s " +"perfectly acceptable to call `clone`." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:205 +msgid "" +"We’ve updated `main` so it places the instance of `Config` returned by " +"`parse_config` into a variable named `config`, and we updated the code that " +"previously used the separate `query` and `file_path` variables so it now " +"uses the fields on the `Config` struct instead." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:210 +msgid "" +"Now our code more clearly conveys that `query` and `file_path` are related " +"and that their purpose is to configure how the program will work. Any code " +"that uses these values knows to find them in the `config` instance in the " +"fields named for their purpose." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:215 +msgid "Creating a Constructor for `Config`" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:217 +msgid "" +"So far, we’ve extracted the logic responsible for parsing the command line " +"arguments from `main` and placed it in the `parse_config` function. Doing so " +"helped us to see that the `query` and `file_path` values were related and " +"that relationship should be conveyed in our code. We then added a `Config` " +"struct to name the related purpose of `query` and `file_path` and to be able " +"to return the values’ names as struct field names from the `parse_config` " +"function." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:224 +msgid "" +"So now that the purpose of the `parse_config` function is to create a " +"`Config` instance, we can change `parse_config` from a plain function to a " +"function named `new` that is associated with the `Config` struct. Making " +"this change will make the code more idiomatic. We can create instances of " +"types in the standard library, such as `String`, by calling `String::new`. " +"Similarly, by changing `parse_config` into a `new` function associated with " +"`Config`, we’ll be able to create instances of `Config` by calling `Config::" +"new`. Listing 12-7 shows the changes we need to make." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:274 +msgid "" +"We’ve updated `main` where we were calling `parse_config` to instead call " +"`Config::new`. We’ve changed the name of `parse_config` to `new` and moved " +"it within an `impl` block, which associates the `new` function with " +"`Config`. Try compiling this code again to make sure it works." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:279 +msgid "Fixing the Error Handling" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:281 +msgid "" +"Now we’ll work on fixing our error handling. Recall that attempting to " +"access the values in the `args` vector at index 1 or index 2 will cause the " +"program to panic if the vector contains fewer than three items. Try running " +"the program without any arguments; it will look like this:" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:286 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s\n" +" Running `target/debug/minigrep`\n" +"thread 'main' panicked at src/main.rs:27:21:\n" +"index out of bounds: the len is 1 but the index is 1\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"```" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:296 +msgid "" +"The line `index out of bounds: the len is 1 but the index is 1` is an error " +"message intended for programmers. It won’t help our end users understand " +"what they should do instead. Let’s fix that now." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:300 +msgid "Improving the Error Message" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:302 +msgid "" +"In Listing 12-8, we add a check in the `new` function that will verify that " +"the slice is long enough before accessing index 1 and 2. If the slice isn’t " +"long enough, the program panics and displays a better error message." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:335 +#: src/ch12-03-improving-error-handling-and-modularity.md:425 +#: src/ch12-03-improving-error-handling-and-modularity.md:497 +#: src/ch12-03-improving-error-handling-and-modularity.md:596 +#: src/ch12-03-improving-error-handling-and-modularity.md:664 +#: src/ch12-03-improving-error-handling-and-modularity.md:792 +#: src/ch12-03-improving-error-handling-and-modularity.md:846 +#: src/ch12-04-testing-the-librarys-functionality.md:52 +#: src/ch12-04-testing-the-librarys-functionality.md:115 +#: src/ch12-04-testing-the-librarys-functionality.md:267 +#: src/ch12-04-testing-the-librarys-functionality.md:334 +#: src/ch12-04-testing-the-librarys-functionality.md:402 +#: src/ch12-04-testing-the-librarys-functionality.md:507 +#: src/ch12-05-working-with-environment-variables.md:33 +#: src/ch12-05-working-with-environment-variables.md:137 +#: src/ch12-05-working-with-environment-variables.md:290 +#: src/ch12-05-working-with-environment-variables.md:397 +#: src/ch12-05-working-with-environment-variables.md:511 +#: src/ch13-03-improving-our-io-project.md:32 +#: src/ch13-03-improving-our-io-project.md:232 +#: src/ch13-03-improving-our-io-project.md:493 +msgid "\"not enough arguments\"" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:349 +msgid "" +"This code is similar to [the `Guess::new` function we wrote in Listing 9-13]" +"(ch09-03-to-panic-or-not-to-panic.html#creating-custom-types-for-" +"validation), where we called `panic!` when the `value` " +"argument was out of the range of valid values. Instead of checking for a " +"range of values here, we’re checking that the length of `args` is at least 3 " +"and the rest of the function can operate under the assumption that this " +"condition has been met. If `args` has fewer than three items, this condition " +"will be true, and we call the `panic!` macro to end the program immediately." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:357 +msgid "" +"With these extra few lines of code in `new`, let’s run the program without " +"any arguments again to see what the error looks like now:" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:360 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s\n" +" Running `target/debug/minigrep`\n" +"thread 'main' panicked at src/main.rs:26:13:\n" +"not enough arguments\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"```" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:370 +msgid "" +"This output is better: we now have a reasonable error message. However, we " +"also have extraneous information we don’t want to give to our users. Perhaps " +"using the technique we used in Listing 9-13 isn’t the best to use here: a " +"call to `panic!` is more appropriate for a programming problem than a usage " +"problem, [as discussed in Chapter 9](ch09-03-to-panic-or-not-to-panic." +"html#guidelines-for-error-handling). Instead, we’ll use the " +"other technique you learned about in Chapter 9—[returning a `Result`]" +"(ch09-02-recoverable-errors-with-result.html) that indicates " +"either success or an error." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:379 +msgid "" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:381 +msgid "Returning a `Result` Instead of Calling `panic!`" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:383 +msgid "" +"We can instead return a `Result` value that will contain a `Config` instance " +"in the successful case and will describe the problem in the error case. " +"We’re also going to change the function name from `new` to `build` because " +"many programmers expect `new` functions to never fail. When `Config::build` " +"is communicating to `main`, we can use the `Result` type to signal there was " +"a problem. Then we can change `main` to convert an `Err` variant into a more " +"practical error for our users without the surrounding text about `thread " +"'main'` and `RUST_BACKTRACE` that a call to `panic!` causes." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:392 +msgid "" +"Listing 12-9 shows the changes we need to make to the return value of the " +"function we’re now calling `Config::build` and the body of the function " +"needed to return a `Result`. Note that this won’t compile until we update " +"`main` as well, which we’ll do in the next listing." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:438 +msgid "" +"Our `build` function returns a `Result` with a `Config` instance in the " +"success case and a `&'static str` in the error case. Our error values will " +"always be string literals that have the `'static` lifetime." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:442 +msgid "" +"We’ve made two changes in the body of the function: instead of calling " +"`panic!` when the user doesn’t pass enough arguments, we now return an `Err` " +"value, and we’ve wrapped the `Config` return value in an `Ok`. These changes " +"make the function conform to its new type signature." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:447 +msgid "" +"Returning an `Err` value from `Config::build` allows the `main` function to " +"handle the `Result` value returned from the `build` function and exit the " +"process more cleanly in the error case." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:452 +msgid "" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:454 +msgid "Calling `Config::build` and Handling Errors" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:456 +msgid "" +"To handle the error case and print a user-friendly message, we need to " +"update `main` to handle the `Result` being returned by `Config::build`, as " +"shown in Listing 12-10. We’ll also take the responsibility of exiting the " +"command line tool with a nonzero error code away from `panic!` and instead " +"implement it by hand. A nonzero exit status is a convention to signal to the " +"process that called our program that the program exited with an error state." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:474 +#: src/ch12-03-improving-error-handling-and-modularity.md:569 +#: src/ch12-03-improving-error-handling-and-modularity.md:638 +#: src/ch12-03-improving-error-handling-and-modularity.md:763 +#: src/ch12-03-improving-error-handling-and-modularity.md:888 +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:69 +#: src/ch13-03-improving-our-io-project.md:161 +#: src/ch13-03-improving-our-io-project.md:188 +msgid "\"Problem parsing arguments: {err}\"" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:510 +msgid "" +"In this listing, we’ve used a method we haven’t covered in detail yet: " +"`unwrap_or_else`, which is defined on `Result` by the standard " +"library. Using `unwrap_or_else` allows us to define some custom, non-`panic!" +"` error handling. If the `Result` is an `Ok` value, this method’s behavior " +"is similar to `unwrap`: it returns the inner value `Ok` is wrapping. " +"However, if the value is an `Err` value, this method calls the code in the " +"_closure_, which is an anonymous function we define and pass as an argument " +"to `unwrap_or_else`. We’ll cover closures in more detail in [Chapter 13]" +"(ch13-00-functional-features.html). For now, you just need to " +"know that `unwrap_or_else` will pass the inner value of the `Err`, which in " +"this case is the static string `\"not enough arguments\"` that we added in " +"Listing 12-9, to our closure in the argument `err` that appears between the " +"vertical pipes. The code in the closure can then use the `err` value when it " +"runs." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:524 +msgid "" +"We’ve added a new `use` line to bring `process` from the standard library " +"into scope. The code in the closure that will be run in the error case is " +"only two lines: we print the `err` value and then call `process::exit`. The " +"`process::exit` function will stop the program immediately and return the " +"number that was passed as the exit status code. This is similar to the " +"`panic!`\\-based handling we used in Listing 12-8, but we no longer get all " +"the extra output. Let’s try it:" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:532 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.48s\n" +" Running `target/debug/minigrep`\n" +"Problem parsing arguments: not enough arguments\n" +"```" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:540 +msgid "Great! This output is much friendlier for our users." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:542 +msgid "Extracting Logic from `main`" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:544 +msgid "" +"Now that we’ve finished refactoring the configuration parsing, let’s turn to " +"the program’s logic. As we stated in [“Separation of Concerns for Binary " +"Projects”](#separation-of-concerns-for-binary-projects), " +"we’ll extract a function named `run` that will hold all the logic currently " +"in the `main` function that isn’t involved with setting up configuration or " +"handling errors. When we’re done, `main` will be concise and easy to verify " +"by inspection, and we’ll be able to write tests for all the other logic." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:552 +msgid "" +"Listing 12-11 shows the extracted `run` function. For now, we’re just making " +"the small, incremental improvement of extracting the function. We’re still " +"defining the function in _src/main.rs_." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:609 +msgid "" +"The `run` function now contains all the remaining logic from `main`, " +"starting from reading the file. The `run` function takes the `Config` " +"instance as an argument." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:613 +msgid "Returning Errors from the `run` Function" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:615 +msgid "" +"With the remaining program logic separated into the `run` function, we can " +"improve the error handling, as we did with `Config::build` in Listing 12-9. " +"Instead of allowing the program to panic by calling `expect`, the `run` " +"function will return a `Result` when something goes wrong. This will " +"let us further consolidate the logic around handling errors into `main` in a " +"user-friendly way. Listing 12-12 shows the changes we need to make to the " +"signature and body of `run`." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:677 +msgid "" +"We’ve made three significant changes here. First, we changed the return type " +"of the `run` function to `Result<(), Box>`. This function " +"previously returned the unit type, `()`, and we keep that as the value " +"returned in the `Ok` case." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:682 +msgid "" +"For the error type, we used the _trait object_ `Box` (and we’ve " +"brought `std::error::Error` into scope with a `use` statement at the top). " +"We’ll cover trait objects in [Chapter 17](ch17-00-oop.html). " +"For now, just know that `Box` means the function will return a " +"type that implements the `Error` trait, but we don’t have to specify what " +"particular type the return value will be. This gives us flexibility to " +"return error values that may be of different types in different error cases. " +"The `dyn` keyword is short for “dynamic.”" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:691 +msgid "" +"Second, we’ve removed the call to `expect` in favor of the `?` operator, as " +"we talked about in [Chapter 9](ch09-02-recoverable-errors-with-result.html#a-" +"shortcut-for-propagating-errors-the--operator). Rather than " +"`panic!` on an error, `?` will return the error value from the current " +"function for the caller to handle." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:696 +msgid "" +"Third, the `run` function now returns an `Ok` value in the success case. " +"We’ve declared the `run` function’s success type as `()` in the signature, " +"which means we need to wrap the unit type value in the `Ok` value. This " +"`Ok(())` syntax might look a bit strange at first, but using `()` like this " +"is the idiomatic way to indicate that we’re calling `run` for its side " +"effects only; it doesn’t return a value we need." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:703 +msgid "When you run this code, it will compile but will display a warning:" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:705 +msgid "" +"```console\n" +"$ cargo run -- the poem.txt\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +"warning: unused `Result` that must be used\n" +" --> src/main.rs:19:5\n" +" |\n" +"19 | run(config);\n" +" | ^^^^^^^^^^^\n" +" |\n" +" = note: this `Result` may be an `Err` variant, which should be handled\n" +" = note: `#[warn(unused_must_use)]` on by default\n" +"help: use `let _ = ...` to ignore the resulting value\n" +" |\n" +"19 | let _ = run(config);\n" +" | +++++++\n" +"\n" +"warning: `minigrep` (bin \"minigrep\") generated 1 warning\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.71s\n" +" Running `target/debug/minigrep the poem.txt`\n" +"Searching for the\n" +"In file poem.txt\n" +"With text:\n" +"I'm nobody! Who are you?\n" +"Are you nobody, too?\n" +"Then there's a pair of us - don't tell!\n" +"They'd banish us, you know.\n" +"\n" +"How dreary to be somebody!\n" +"How public, like a frog\n" +"To tell your name the livelong day\n" +"To an admiring bog!\n" +"\n" +"```" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:739 +msgid "" +"Rust tells us that our code ignored the `Result` value and the `Result` " +"value might indicate that an error occurred. But we’re not checking to see " +"whether or not there was an error, and the compiler reminds us that we " +"probably meant to have some error-handling code here! Let’s rectify that " +"problem now." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:744 +msgid "Handling Errors Returned from `run` in `main`" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:746 +msgid "" +"We’ll check for errors and handle them using a technique similar to one we " +"used with `Config::build` in Listing 12-10, but with a slight difference:" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:771 +#: src/ch12-03-improving-error-handling-and-modularity.md:897 +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:74 +#: src/ch13-03-improving-our-io-project.md:168 +#: src/ch13-03-improving-our-io-project.md:195 +msgid "\"Application error: {e}\"" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:803 +msgid "" +"We use `if let` rather than `unwrap_or_else` to check whether `run` returns " +"an `Err` value and call `process::exit(1)` if it does. The `run` function " +"doesn’t return a value that we want to `unwrap` in the same way that " +"`Config::build` returns the `Config` instance. Because `run` returns `()` in " +"the success case, we only care about detecting an error, so we don’t need " +"`unwrap_or_else` to return the unwrapped value, which would only be `()`." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:810 +msgid "" +"The bodies of the `if let` and the `unwrap_or_else` functions are the same " +"in both cases: we print the error and exit." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:813 +msgid "Splitting Code into a Library Crate" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:815 +msgid "" +"Our `minigrep` project is looking good so far! Now we’ll split the _src/main." +"rs_ file and put some code into the _src/lib.rs_ file. That way we can test " +"the code and have a _src/main.rs_ file with fewer responsibilities." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:819 +msgid "" +"Let’s move all the code that isn’t the `main` function from _src/main.rs_ to " +"_src/lib.rs_:" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:822 +msgid "The `run` function definition" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:823 +msgid "The relevant `use` statements" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:824 +msgid "The definition of `Config`" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:825 +msgid "The `Config::build` function definition" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:827 +msgid "" +"The contents of _src/lib.rs_ should have the signatures shown in Listing " +"12-13 (we’ve omitted the bodies of the functions for brevity). Note that " +"this won’t compile until we modify _src/main.rs_ in Listing 12-14." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:868 +msgid "" +"We’ve made liberal use of the `pub` keyword: on `Config`, on its fields and " +"its `build` method, and on the `run` function. We now have a library crate " +"that has a public API we can test!" +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:872 +msgid "" +"Now we need to bring the code we moved to _src/lib.rs_ into the scope of the " +"binary crate in _src/main.rs_, as shown in Listing 12-14." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:905 +msgid "" +"We add a `use minigrep::Config` line to bring the `Config` type from the " +"library crate into the binary crate’s scope, and we prefix the `run` " +"function with our crate name. Now all the functionality should be connected " +"and should work. Run the program with `cargo run` and make sure everything " +"works correctly." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:911 +msgid "" +"Whew! That was a lot of work, but we’ve set ourselves up for success in the " +"future. Now it’s much easier to handle errors, and we’ve made the code more " +"modular. Almost all of our work will be done in _src/lib.rs_ from here on " +"out." +msgstr "" + +#: src/ch12-03-improving-error-handling-and-modularity.md:915 +msgid "" +"Let’s take advantage of this newfound modularity by doing something that " +"would have been difficult with the old code but is easy with the new code: " +"we’ll write some tests!" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:1 +msgid "Developing the Library’s Functionality with Test-Driven Development" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:3 +msgid "" +"Now that we’ve extracted the logic into _src/lib.rs_ and left the argument " +"collecting and error handling in _src/main.rs_, it’s much easier to write " +"tests for the core functionality of our code. We can call functions directly " +"with various arguments and check return values without having to call our " +"binary from the command line." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:9 +msgid "" +"In this section, we’ll add the searching logic to the `minigrep` program " +"using the test-driven development (TDD) process with the following steps:" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:12 +msgid "" +"Write a test that fails and run it to make sure it fails for the reason you " +"expect." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:14 +msgid "Write or modify just enough code to make the new test pass." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:15 +msgid "" +"Refactor the code you just added or changed and make sure the tests continue " +"to pass." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:17 +msgid "Repeat from step 1!" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:19 +msgid "" +"Though it’s just one of many ways to write software, TDD can help drive code " +"design. Writing the test before you write the code that makes the test pass " +"helps to maintain high test coverage throughout the process." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:23 +msgid "" +"We’ll test drive the implementation of the functionality that will actually " +"do the searching for the query string in the file contents and produce a " +"list of lines that match the query. We’ll add this functionality in a " +"function called `search`." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:28 +msgid "Writing a Failing Test" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:30 +msgid "" +"Because we don’t need them anymore, let’s remove the `println!` statements " +"from _src/lib.rs_ and _src/main.rs_ that we used to check the program’s " +"behavior. Then, in _src/lib.rs_, add a `tests` module with a test function, " +"as we did in [Chapter 11](ch11-01-writing-tests.html#the-anatomy-of-a-test-" +"function). The test function specifies the behavior we want " +"the `search` function to have: it will take a query and the text to search, " +"and it will return only the lines from the text that contain the query. " +"Listing 12-15 shows this test, which won’t compile yet." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:74 +#: src/ch12-04-testing-the-librarys-functionality.md:141 +#: src/ch12-04-testing-the-librarys-functionality.md:295 +#: src/ch12-04-testing-the-librarys-functionality.md:364 +#: src/ch12-04-testing-the-librarys-functionality.md:436 +#: src/ch12-04-testing-the-librarys-functionality.md:545 +#: src/ch12-05-working-with-environment-variables.md:71 +#: src/ch12-05-working-with-environment-variables.md:191 +#: src/ch12-05-working-with-environment-variables.md:350 +#: src/ch12-05-working-with-environment-variables.md:457 +#: src/ch12-05-working-with-environment-variables.md:577 +#: src/ch13-03-improving-our-io-project.md:98 +#: src/ch13-03-improving-our-io-project.md:298 +#: src/ch13-03-improving-our-io-project.md:437 +#: src/ch13-03-improving-our-io-project.md:527 +#: src/ch13-03-improving-our-io-project.md:631 +msgid "\"duct\"" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:75 +msgid "" +"\"\\\n" +"Rust:\n" +"safe, fast, productive.\n" +"Pick three.\"" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:80 +#: src/ch12-04-testing-the-librarys-functionality.md:147 +#: src/ch12-04-testing-the-librarys-functionality.md:301 +#: src/ch12-04-testing-the-librarys-functionality.md:370 +#: src/ch12-04-testing-the-librarys-functionality.md:442 +#: src/ch12-04-testing-the-librarys-functionality.md:551 +#: src/ch12-05-working-with-environment-variables.md:78 +#: src/ch12-05-working-with-environment-variables.md:198 +#: src/ch12-05-working-with-environment-variables.md:357 +#: src/ch12-05-working-with-environment-variables.md:464 +#: src/ch12-05-working-with-environment-variables.md:584 +#: src/ch13-03-improving-our-io-project.md:105 +#: src/ch13-03-improving-our-io-project.md:305 +#: src/ch13-03-improving-our-io-project.md:444 +#: src/ch13-03-improving-our-io-project.md:533 +#: src/ch13-03-improving-our-io-project.md:638 +msgid "\"safe, fast, productive.\"" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:87 +msgid "" +"This test searches for the string `\"duct\"`. The text we’re searching is " +"three lines, only one of which contains `\"duct\"` (Note that the backslash " +"after the opening double quote tells Rust not to put a newline character at " +"the beginning of the contents of this string literal). We assert that the " +"value returned from the `search` function contains only the line we expect." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:93 +msgid "" +"We aren’t yet able to run this test and watch it fail because the test " +"doesn’t even compile: the `search` function doesn’t exist yet! In accordance " +"with TDD principles, we’ll add just enough code to get the test to compile " +"and run by adding a definition of the `search` function that always returns " +"an empty vector, as shown in Listing 12-16. Then the test should compile and " +"fail because an empty vector doesn’t match a vector containing the line `" +"\"safe, fast, productive.\"`" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:142 +#: src/ch12-04-testing-the-librarys-functionality.md:296 +#: src/ch12-04-testing-the-librarys-functionality.md:365 +#: src/ch12-04-testing-the-librarys-functionality.md:437 +#: src/ch12-04-testing-the-librarys-functionality.md:546 +#: src/ch13-03-improving-our-io-project.md:528 +msgid "" +"\"\\\n" +"# Rust:\n" +"# safe, fast, productive.\n" +"# Pick three.\"" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:154 +msgid "" +"Notice that we need to define an explicit lifetime `'a` in the signature of " +"`search` and use that lifetime with the `contents` argument and the return " +"value. Recall in [Chapter 10](ch10-03-lifetime-syntax.html) " +"that the lifetime parameters specify which argument lifetime is connected to " +"the lifetime of the return value. In this case, we indicate that the " +"returned vector should contain string slices that reference slices of the " +"argument `contents` (rather than the argument `query`)." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:162 +msgid "" +"In other words, we tell Rust that the data returned by the `search` function " +"will live as long as the data passed into the `search` function in the " +"`contents` argument. This is important! The data referenced _by_ a slice " +"needs to be valid for the reference to be valid; if the compiler assumes " +"we’re making string slices of `query` rather than `contents`, it will do its " +"safety checking incorrectly." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:169 +msgid "" +"If we forget the lifetime annotations and try to compile this function, " +"we’ll get this error:" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:172 +msgid "" +"```console\n" +"$ cargo build\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +"error[E0106]: missing lifetime specifier\n" +" --> src/lib.rs:28:51\n" +" |\n" +"28 | pub fn search(query: &str, contents: &str) -> Vec<&str> {\n" +" | ---- ---- ^ expected named " +"lifetime parameter\n" +" |\n" +" = help: this function's return type contains a borrowed value, but the " +"signature does not say whether it is borrowed from `query` or `contents`\n" +"help: consider introducing a named lifetime parameter\n" +" |\n" +"28 | pub fn search<'a>(query: &'a str, contents: &'a str) -> Vec<&'a str> {\n" +" | ++++ ++ ++ ++\n" +"\n" +"For more information about this error, try `rustc --explain E0106`.\n" +"error: could not compile `minigrep` (lib) due to 1 previous error\n" +"```" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:191 +msgid "" +"Rust can’t possibly know which of the two arguments we need, so we need to " +"tell it explicitly. Because `contents` is the argument that contains all of " +"our text and we want to return the parts of that text that match, we know " +"`contents` is the argument that should be connected to the return value " +"using the lifetime syntax." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:197 +msgid "" +"Other programming languages don’t require you to connect arguments to return " +"values in the signature, but this practice will get easier over time. You " +"might want to compare this example with the [“Validating References with " +"Lifetimes”](ch10-03-lifetime-syntax.html#validating-references-with-" +"lifetimes) section in Chapter 10." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:203 +msgid "Now let’s run the test:" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:205 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.97s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"minigrep-9cd200e5fac0fc94)\n" +"\n" +"running 1 test\n" +"test tests::one_result ... FAILED\n" +"\n" +"failures:\n" +"\n" +"---- tests::one_result stdout ----\n" +"thread 'tests::one_result' panicked at src/lib.rs:44:9:\n" +"assertion `left == right` failed\n" +" left: [\"safe, fast, productive.\"]\n" +" right: []\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"\n" +"\n" +"failures:\n" +" tests::one_result\n" +"\n" +"test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered " +"out; finished in 0.00s\n" +"\n" +"error: test failed, to rerun pass `--lib`\n" +"```" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:232 +msgid "" +"Great, the test fails, exactly as we expected. Let’s get the test to pass!" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:234 +msgid "Writing Code to Pass the Test" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:236 +msgid "" +"Currently, our test is failing because we always return an empty vector. To " +"fix that and implement `search`, our program needs to follow these steps:" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:239 +msgid "Iterate through each line of the contents." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:240 +msgid "Check whether the line contains our query string." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:241 +msgid "If it does, add it to the list of values we’re returning." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:242 +msgid "If it doesn’t, do nothing." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:243 +msgid "Return the list of results that match." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:245 +msgid "Let’s work through each step, starting with iterating through lines." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:247 +msgid "Iterating Through Lines with the `lines` Method" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:249 +msgid "" +"Rust has a helpful method to handle line-by-line iteration of strings, " +"conveniently named `lines`, that works as shown in Listing 12-17. Note this " +"won’t compile yet." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:285 +#: src/ch12-04-testing-the-librarys-functionality.md:353 +msgid "// do something with line\n" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:308 +msgid "" +"The `lines` method returns an iterator. We’ll talk about iterators in depth " +"in [Chapter 13](ch13-02-iterators.html), but recall that you " +"saw this way of using an iterator in [Listing 3-5](ch03-05-control-flow." +"html#looping-through-a-collection-with-for), where we used a " +"`for` loop with an iterator to run some code on each item in a collection." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:313 +msgid "Searching Each Line for the Query" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:315 +msgid "" +"Next, we’ll check whether the current line contains our query string. " +"Fortunately, strings have a helpful method named `contains` that does this " +"for us! Add a call to the `contains` method in the `search` function, as " +"shown in Listing 12-18. Note this still won’t compile yet." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:377 +msgid "" +"At the moment, we’re building up functionality. To get it to compile, we " +"need to return a value from the body as we indicated we would in the " +"function signature." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:381 +msgid "Storing Matching Lines" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:383 +msgid "" +"To finish this function, we need a way to store the matching lines that we " +"want to return. For that, we can make a mutable vector before the `for` loop " +"and call the `push` method to store a `line` in the vector. After the `for` " +"loop, we return the vector, as shown in Listing 12-19." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:449 +msgid "" +"Now the `search` function should return only the lines that contain `query`, " +"and our test should pass. Let’s run the test:" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:452 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 1.22s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"minigrep-9cd200e5fac0fc94)\n" +"\n" +"running 1 test\n" +"test tests::one_result ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Running unittests src/main.rs (target/debug/deps/" +"minigrep-9cd200e5fac0fc94)\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests minigrep\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:477 +msgid "Our test passed, so we know it works!" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:479 +msgid "" +"At this point, we could consider opportunities for refactoring the " +"implementation of the search function while keeping the tests passing to " +"maintain the same functionality. The code in the search function isn’t too " +"bad, but it doesn’t take advantage of some useful features of iterators. " +"We’ll return to this example in [Chapter 13](ch13-02-iterators.html), where we’ll explore iterators in detail, and look at how to " +"improve it." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:486 +msgid "Using the `search` Function in the `run` Function" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:488 +msgid "" +"Now that the `search` function is working and tested, we need to call " +"`search` from our `run` function. We need to pass the `config.query` value " +"and the `contents` that `run` reads from the file to the `search` function. " +"Then `run` will print each line returned from `search`:" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:521 +#: src/ch12-05-working-with-environment-variables.md:47 +#: src/ch12-05-working-with-environment-variables.md:151 +#: src/ch12-05-working-with-environment-variables.md:310 +#: src/ch12-05-working-with-environment-variables.md:417 +#: src/ch12-05-working-with-environment-variables.md:537 +#: src/ch13-03-improving-our-io-project.md:58 +#: src/ch13-03-improving-our-io-project.md:258 +#: src/ch13-03-improving-our-io-project.md:397 +#: src/ch13-03-improving-our-io-project.md:596 +msgid "\"{line}\"" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:556 +msgid "" +"We’re still using a `for` loop to return each line from `search` and print " +"it." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:558 +msgid "" +"Now the entire program should work! Let’s try it out, first with a word that " +"should return exactly one line from the Emily Dickinson poem, “frog”:" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:561 +msgid "" +"```console\n" +"$ cargo run -- frog poem.txt\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.38s\n" +" Running `target/debug/minigrep frog poem.txt`\n" +"How public, like a frog\n" +"```" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:569 +msgid "Cool! Now let’s try a word that will match multiple lines, like “body”:" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:571 +msgid "" +"```console\n" +"$ cargo run -- body poem.txt\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s\n" +" Running `target/debug/minigrep body poem.txt`\n" +"I'm nobody! Who are you?\n" +"Are you nobody, too?\n" +"How dreary to be somebody!\n" +"```" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:581 +msgid "" +"And finally, let’s make sure that we don’t get any lines when we search for " +"a word that isn’t anywhere in the poem, such as “monomorphization”:" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:584 +msgid "" +"```console\n" +"$ cargo run -- monomorphization poem.txt\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s\n" +" Running `target/debug/minigrep monomorphization poem.txt`\n" +"```" +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:591 +msgid "" +"Excellent! We’ve built our own mini version of a classic tool and learned a " +"lot about how to structure applications. We’ve also learned a bit about file " +"input and output, lifetimes, testing, and command line parsing." +msgstr "" + +#: src/ch12-04-testing-the-librarys-functionality.md:595 +msgid "" +"To round out this project, we’ll briefly demonstrate how to work with " +"environment variables and how to print to standard error, both of which are " +"useful when you’re writing command line programs." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:3 +msgid "" +"We’ll improve `minigrep` by adding an extra feature: an option for case-" +"insensitive searching that the user can turn on via an environment variable. " +"We could make this feature a command line option and require that users " +"enter it each time they want it to apply, but by instead making it an " +"environment variable, we allow our users to set the environment variable " +"once and have all their searches be case insensitive in that terminal " +"session." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:10 +msgid "Writing a Failing Test for the Case-Insensitive `search` Function" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:12 +msgid "" +"We first add a new `search_case_insensitive` function that will be called " +"when the environment variable has a value. We’ll continue to follow the TDD " +"process, so the first step is again to write a failing test. We’ll add a new " +"test for the new `search_case_insensitive` function and rename our old test " +"from `one_result` to `case_sensitive` to clarify the differences between the " +"two tests, as shown in Listing 12-20." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:72 +msgid "" +"\"\\\n" +"Rust:\n" +"safe, fast, productive.\n" +"Pick three.\n" +"Duct tape.\"" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:83 +#: src/ch12-05-working-with-environment-variables.md:203 +#: src/ch12-05-working-with-environment-variables.md:362 +#: src/ch12-05-working-with-environment-variables.md:469 +#: src/ch12-05-working-with-environment-variables.md:589 +#: src/ch13-03-improving-our-io-project.md:110 +#: src/ch13-03-improving-our-io-project.md:310 +#: src/ch13-03-improving-our-io-project.md:449 +#: src/ch13-03-improving-our-io-project.md:643 +msgid "\"rUsT\"" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:84 +msgid "" +"\"\\\n" +"Rust:\n" +"safe, fast, productive.\n" +"Pick three.\n" +"Trust me.\"" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:91 +#: src/ch12-05-working-with-environment-variables.md:211 +#: src/ch12-05-working-with-environment-variables.md:370 +#: src/ch12-05-working-with-environment-variables.md:477 +#: src/ch12-05-working-with-environment-variables.md:597 +#: src/ch13-03-improving-our-io-project.md:118 +#: src/ch13-03-improving-our-io-project.md:318 +#: src/ch13-03-improving-our-io-project.md:457 +#: src/ch13-03-improving-our-io-project.md:651 +msgid "\"Rust:\"" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:91 +#: src/ch12-05-working-with-environment-variables.md:211 +#: src/ch12-05-working-with-environment-variables.md:370 +#: src/ch12-05-working-with-environment-variables.md:477 +#: src/ch12-05-working-with-environment-variables.md:597 +#: src/ch13-03-improving-our-io-project.md:118 +#: src/ch13-03-improving-our-io-project.md:318 +#: src/ch13-03-improving-our-io-project.md:457 +#: src/ch13-03-improving-our-io-project.md:651 +msgid "\"Trust me.\"" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:100 +msgid "" +"Note that we’ve edited the old test’s `contents` too. We’ve added a new line " +"with the text `\"Duct tape.\"` using a capital D that shouldn’t match the " +"query `\"duct\"` when we’re searching in a case-sensitive manner. Changing " +"the old test in this way helps ensure that we don’t accidentally break the " +"case-sensitive search functionality that we’ve already implemented. This " +"test should pass now and should continue to pass as we work on the case-" +"insensitive search." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:107 +msgid "" +"The new test for the case-_insensitive_ search uses `\"rUsT\"` as its query. " +"In the `search_case_insensitive` function we’re about to add, the query `" +"\"rUsT\"` should match the line containing `\"Rust:\"` with a capital R and " +"match the line `\"Trust me.\"` even though both have different casing from " +"the query. This is our failing test, and it will fail to compile because we " +"haven’t yet defined the `search_case_insensitive` function. Feel free to add " +"a skeleton implementation that always returns an empty vector, similar to " +"the way we did for the `search` function in Listing 12-16 to see the test " +"compile and fail." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:116 +msgid "Implementing the `search_case_insensitive` Function" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:118 +msgid "" +"The `search_case_insensitive` function, shown in Listing 12-21, will be " +"almost the same as the `search` function. The only difference is that we’ll " +"lowercase the `query` and each `line` so whatever the case of the input " +"arguments, they’ll be the same case when we check whether the line contains " +"the query." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:192 +#: src/ch12-05-working-with-environment-variables.md:351 +#: src/ch12-05-working-with-environment-variables.md:458 +#: src/ch12-05-working-with-environment-variables.md:578 +#: src/ch13-03-improving-our-io-project.md:99 +#: src/ch13-03-improving-our-io-project.md:299 +#: src/ch13-03-improving-our-io-project.md:438 +#: src/ch13-03-improving-our-io-project.md:632 +msgid "" +"\"\\\n" +"# Rust:\n" +"# safe, fast, productive.\n" +"# Pick three.\n" +"# Duct tape.\"" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:204 +#: src/ch12-05-working-with-environment-variables.md:363 +#: src/ch12-05-working-with-environment-variables.md:470 +#: src/ch12-05-working-with-environment-variables.md:590 +#: src/ch13-03-improving-our-io-project.md:111 +#: src/ch13-03-improving-our-io-project.md:311 +#: src/ch13-03-improving-our-io-project.md:450 +#: src/ch13-03-improving-our-io-project.md:644 +msgid "" +"\"\\\n" +"# Rust:\n" +"# safe, fast, productive.\n" +"# Pick three.\n" +"# Trust me.\"" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:220 +msgid "" +"First, we lowercase the `query` string and store it in a shadowed variable " +"with the same name. Calling `to_lowercase` on the query is necessary so no " +"matter whether the user’s query is `\"rust\"`, `\"RUST\"`, `\"Rust\"`, or `" +"\"rUsT\"`, we’ll treat the query as if it were `\"rust\"` and be insensitive " +"to the case. While `to_lowercase` will handle basic Unicode, it won’t be " +"100% accurate. If we were writing a real application, we’d want to do a bit " +"more work here, but this section is about environment variables, not " +"Unicode, so we’ll leave it at that here." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:229 +msgid "" +"Note that `query` is now a `String` rather than a string slice, because " +"calling `to_lowercase` creates new data rather than referencing existing " +"data. Say the query is `\"rUsT\"`, as an example: that string slice doesn’t " +"contain a lowercase `u` or `t` for us to use, so we have to allocate a new " +"`String` containing `\"rust\"`. When we pass `query` as an argument to the " +"`contains` method now, we need to add an ampersand because the signature of " +"`contains` is defined to take a string slice." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:237 +msgid "" +"Next, we add a call to `to_lowercase` on each `line` to lowercase all " +"characters. Now that we’ve converted `line` and `query` to lowercase, we’ll " +"find matches no matter what the case of the query is." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:241 +msgid "Let’s see if this implementation passes the tests:" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:243 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 1.33s\n" +" Running unittests src/lib.rs (target/debug/deps/" +"minigrep-9cd200e5fac0fc94)\n" +"\n" +"running 2 tests\n" +"test tests::case_insensitive ... ok\n" +"test tests::case_sensitive ... ok\n" +"\n" +"test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Running unittests src/main.rs (target/debug/deps/" +"minigrep-9cd200e5fac0fc94)\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests minigrep\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +"```" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:269 +msgid "" +"Great! They passed. Now, let’s call the new `search_case_insensitive` " +"function from the `run` function. First, we’ll add a configuration option to " +"the `Config` struct to switch between case-sensitive and case-insensitive " +"search. Adding this field will cause compiler errors because we aren’t " +"initializing this field anywhere yet:" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:377 +msgid "" +"We added the `ignore_case` field that holds a Boolean. Next, we need the " +"`run` function to check the `ignore_case` field’s value and use that to " +"decide whether to call the `search` function or the " +"`search_case_insensitive` function, as shown in Listing 12-22. This still " +"won’t compile yet." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:486 +msgid "" +"Finally, we need to check for the environment variable. The functions for " +"working with environment variables are in the `env` module in the standard " +"library, so we bring that module into scope at the top of _src/lib.rs_. Then " +"we’ll use the `var` function from the `env` module to check if any value has " +"been set for an environment variable named `IGNORE_CASE`, as shown in " +"Listing 12-23." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:517 +#: src/ch13-03-improving-our-io-project.md:38 +#: src/ch13-03-improving-our-io-project.md:238 +#: src/ch13-03-improving-our-io-project.md:377 +#: src/ch13-03-improving-our-io-project.md:576 +msgid "\"IGNORE_CASE\"" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:606 +msgid "" +"Here, we create a new variable `ignore_case`. To set its value, we call the " +"`env::var` function and pass it the name of the `IGNORE_CASE` environment " +"variable. The `env::var` function returns a `Result` that will be the " +"successful `Ok` variant that contains the value of the environment variable " +"if the environment variable is set to any value. It will return the `Err` " +"variant if the environment variable is not set." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:613 +msgid "" +"We’re using the `is_ok` method on the `Result` to check whether the " +"environment variable is set, which means the program should do a case-" +"insensitive search. If the `IGNORE_CASE` environment variable isn’t set to " +"anything, `is_ok` will return false and the program will perform a case-" +"sensitive search. We don’t care about the _value_ of the environment " +"variable, just whether it’s set or unset, so we’re checking `is_ok` rather " +"than using `unwrap`, `expect`, or any of the other methods we’ve seen on " +"`Result`." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:621 +msgid "" +"We pass the value in the `ignore_case` variable to the `Config` instance so " +"the `run` function can read that value and decide whether to call " +"`search_case_insensitive` or `search`, as we implemented in Listing 12-22." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:625 +msgid "" +"Let’s give it a try! First, we’ll run our program without the environment " +"variable set and with the query `to`, which should match any line that " +"contains the word “to” in all lowercase:" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:629 +msgid "" +"```console\n" +"$ cargo run -- to poem.txt\n" +" Compiling minigrep v0.1.0 (file:///projects/minigrep)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s\n" +" Running `target/debug/minigrep to poem.txt`\n" +"Are you nobody, too?\n" +"How dreary to be somebody!\n" +"```" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:638 +msgid "" +"Looks like that still works! Now, let’s run the program with `IGNORE_CASE` " +"set to `1` but with the same query `to`." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:645 +msgid "" +"If you’re using PowerShell, you will need to set the environment variable " +"and run the program as separate commands:" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:652 +msgid "" +"This will make `IGNORE_CASE` persist for the remainder of your shell " +"session. It can be unset with the `Remove-Item` cmdlet:" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:659 +msgid "" +"We should get lines that contain “to” that might have uppercase letters:" +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:674 +msgid "" +"Excellent, we also got lines containing “To”! Our `minigrep` program can now " +"do case-insensitive searching controlled by an environment variable. Now you " +"know how to manage options set using either command line arguments or " +"environment variables." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:679 +msgid "" +"Some programs allow arguments _and_ environment variables for the same " +"configuration. In those cases, the programs decide that one or the other " +"takes precedence. For another exercise on your own, try controlling case " +"sensitivity through either a command line argument or an environment " +"variable. Decide whether the command line argument or the environment " +"variable should take precedence if the program is run with one set to case " +"sensitive and one set to ignore case." +msgstr "" + +#: src/ch12-05-working-with-environment-variables.md:687 +msgid "" +"The `std::env` module contains many more useful features for dealing with " +"environment variables: check out its documentation to see what is available." +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:3 +msgid "" +"At the moment, we’re writing all of our output to the terminal using the " +"`println!` macro. In most terminals, there are two kinds of output: " +"_standard output_ (`stdout`) for general information and _standard error_ " +"(`stderr`) for error messages. This distinction enables users to choose to " +"direct the successful output of a program to a file but still print error " +"messages to the screen." +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:10 +msgid "" +"The `println!` macro is only capable of printing to standard output, so we " +"have to use something else to print to standard error." +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:13 +msgid "Checking Where Errors Are Written" +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:15 +msgid "" +"First, let’s observe how the content printed by `minigrep` is currently " +"being written to standard output, including any error messages we want to " +"write to standard error instead. We’ll do that by redirecting the standard " +"output stream to a file while intentionally causing an error. We won’t " +"redirect the standard error stream, so any content sent to standard error " +"will continue to display on the screen." +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:22 +msgid "" +"Command line programs are expected to send error messages to the standard " +"error stream so we can still see error messages on the screen even if we " +"redirect the standard output stream to a file. Our program is not currently " +"well-behaved: we’re about to see that it saves the error message output to a " +"file instead!" +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:27 +msgid "" +"To demonstrate this behavior, we’ll run the program with `>` and the file " +"path, _output.txt_, that we want to redirect the standard output stream to. " +"We won’t pass any arguments, which should cause an error:" +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:35 +msgid "" +"The `>` syntax tells the shell to write the contents of standard output to " +"_output.txt_ instead of the screen. We didn’t see the error message we were " +"expecting printed to the screen, so that means it must have ended up in the " +"file. This is what _output.txt_ contains:" +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:44 +msgid "" +"Yup, our error message is being printed to standard output. It’s much more " +"useful for error messages like this to be printed to standard error so only " +"data from a successful run ends up in the file. We’ll change that." +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:48 +msgid "Printing Errors to Standard Error" +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:50 +msgid "" +"We’ll use the code in Listing 12-24 to change how error messages are " +"printed. Because of the refactoring we did earlier in this chapter, all the " +"code that prints error messages is in one function, `main`. The standard " +"library provides the `eprintln!` macro that prints to the standard error " +"stream, so let’s change the two places we were calling `println!` to print " +"errors to use `eprintln!` instead." +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:82 +msgid "" +"Let’s now run the program again in the same way, without any arguments and " +"redirecting standard output with `>`:" +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:90 +msgid "" +"Now we see the error onscreen and _output.txt_ contains nothing, which is " +"the behavior we expect of command line programs." +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:93 +msgid "" +"Let’s run the program again with arguments that don’t cause an error but " +"still redirect standard output to a file, like so:" +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:100 +msgid "" +"We won’t see any output to the terminal, and _output.txt_ will contain our " +"results:" +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:103 +msgid "Filename: output.txt" +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:110 +msgid "" +"This demonstrates that we’re now using standard output for successful output " +"and standard error for error output as appropriate." +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:115 +msgid "" +"This chapter recapped some of the major concepts you’ve learned so far and " +"covered how to perform common I/O operations in Rust. By using command line " +"arguments, files, environment variables, and the `eprintln!` macro for " +"printing errors, you’re now prepared to write command line applications. " +"Combined with the concepts in previous chapters, your code will be well " +"organized, store data effectively in the appropriate data structures, handle " +"errors nicely, and be well tested." +msgstr "" + +#: src/ch12-06-writing-to-stderr-instead-of-stdout.md:123 +msgid "" +"Next, we’ll explore some Rust features that were influenced by functional " +"languages: closures and iterators." +msgstr "" + +#: src/ch13-00-functional-features.md:3 +msgid "" +"Rust’s design has taken inspiration from many existing languages and " +"techniques, and one significant influence is _functional programming_. " +"Programming in a functional style often includes using functions as values " +"by passing them in arguments, returning them from other functions, assigning " +"them to variables for later execution, and so forth." +msgstr "" + +#: src/ch13-00-functional-features.md:9 +msgid "" +"In this chapter, we won’t debate the issue of what functional programming is " +"or isn’t but will instead discuss some features of Rust that are similar to " +"features in many languages often referred to as functional." +msgstr "" + +#: src/ch13-00-functional-features.md:13 +msgid "More specifically, we’ll cover:" +msgstr "" + +#: src/ch13-00-functional-features.md:15 +msgid "_Closures_, a function-like construct you can store in a variable" +msgstr "" + +#: src/ch13-00-functional-features.md:16 +msgid "_Iterators_, a way of processing a series of elements" +msgstr "" + +#: src/ch13-00-functional-features.md:17 +msgid "" +"How to use closures and iterators to improve the I/O project in Chapter 12" +msgstr "" + +#: src/ch13-00-functional-features.md:18 +msgid "" +"The performance of closures and iterators (Spoiler alert: they’re faster " +"than you might think!)" +msgstr "" + +#: src/ch13-00-functional-features.md:21 +msgid "" +"We’ve already covered some other Rust features, such as pattern matching and " +"enums, that are also influenced by the functional style. Because mastering " +"closures and iterators is an important part of writing idiomatic, fast Rust " +"code, we’ll devote this entire chapter to them." +msgstr "" + +#: src/ch13-01-closures.md:2 +msgid "" +"" +msgstr "" + +#: src/ch13-01-closures.md:6 +msgid "" +"Rust’s closures are anonymous functions you can save in a variable or pass " +"as arguments to other functions. You can create the closure in one place and " +"then call the closure elsewhere to evaluate it in a different context. " +"Unlike functions, closures can capture values from the scope in which " +"they’re defined. We’ll demonstrate how these closure features allow for code " +"reuse and behavior customization." +msgstr "" + +#: src/ch13-01-closures.md:14 +msgid "" +" " +msgstr "" + +#: src/ch13-01-closures.md:18 +msgid "Capturing the Environment with Closures" +msgstr "" + +#: src/ch13-01-closures.md:20 +msgid "" +"We’ll first examine how we can use closures to capture values from the " +"environment they’re defined in for later use. Here’s the scenario: Every so " +"often, our t-shirt company gives away an exclusive, limited-edition shirt to " +"someone on our mailing list as a promotion. People on the mailing list can " +"optionally add their favorite color to their profile. If the person chosen " +"for a free shirt has their favorite color set, they get that color shirt. If " +"the person hasn’t specified a favorite color, they get whatever color the " +"company currently has the most of." +msgstr "" + +#: src/ch13-01-closures.md:29 +msgid "" +"There are many ways to implement this. For this example, we’re going to use " +"an enum called `ShirtColor` that has the variants `Red` and `Blue` (limiting " +"the number of colors available for simplicity). We represent the company’s " +"inventory with an `Inventory` struct that has a field named `shirts` that " +"contains a `Vec` representing the shirt colors currently in " +"stock. The method `giveaway` defined on `Inventory` gets the optional shirt " +"color preference of the free shirt winner, and returns the shirt color the " +"person will get. This setup is shown in Listing 13-1:" +msgstr "" + +#: src/ch13-01-closures.md:82 src/ch13-01-closures.md:89 +msgid "\"The user with preference {:?} gets {:?}\"" +msgstr "" + +#: src/ch13-01-closures.md:97 +msgid "" +"The `store` defined in `main` has two blue shirts and one red shirt " +"remaining to distribute for this limited-edition promotion. We call the " +"`giveaway` method for a user with a preference for a red shirt and a user " +"without any preference." +msgstr "" + +#: src/ch13-01-closures.md:101 +msgid "" +"Again, this code could be implemented in many ways, and here, to focus on " +"closures, we’ve stuck to concepts you’ve already learned except for the body " +"of the `giveaway` method that uses a closure. In the `giveaway` method, we " +"get the user preference as a parameter of type `Option` and call " +"the `unwrap_or_else` method on `user_preference`. The [`unwrap_or_else` " +"method on `Option`](../std/option/enum.Option.html#method." +"unwrap_or_else) is defined by the standard library. It takes " +"one argument: a closure without any arguments that returns a value `T` (the " +"same type stored in the `Some` variant of the `Option`, in this case " +"`ShirtColor`). If the `Option` is the `Some` variant, `unwrap_or_else` " +"returns the value from within the `Some`. If the `Option` is the `None` " +"variant, `unwrap_or_else` calls the closure and returns the value returned " +"by the closure." +msgstr "" + +#: src/ch13-01-closures.md:114 +msgid "" +"We specify the closure expression `|| self.most_stocked()` as the argument " +"to `unwrap_or_else`. This is a closure that takes no parameters itself (if " +"the closure had parameters, they would appear between the two vertical " +"bars). The body of the closure calls `self.most_stocked()`. We’re defining " +"the closure here, and the implementation of `unwrap_or_else` will evaluate " +"the closure later if the result is needed." +msgstr "" + +#: src/ch13-01-closures.md:121 +msgid "Running this code prints:" +msgstr "" + +#: src/ch13-01-closures.md:123 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling shirt-company v0.1.0 (file:///projects/shirt-company)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.27s\n" +" Running `target/debug/shirt-company`\n" +"The user with preference Some(Red) gets Red\n" +"The user with preference None gets Blue\n" +"```" +msgstr "" + +#: src/ch13-01-closures.md:132 +msgid "" +"One interesting aspect here is that we’ve passed a closure that calls `self." +"most_stocked()` on the current `Inventory` instance. The standard library " +"didn’t need to know anything about the `Inventory` or `ShirtColor` types we " +"defined, or the logic we want to use in this scenario. The closure captures " +"an immutable reference to the `self` `Inventory` instance and passes it with " +"the code we specify to the `unwrap_or_else` method. Functions, on the other " +"hand, are not able to capture their environment in this way." +msgstr "" + +#: src/ch13-01-closures.md:140 +msgid "Closure Type Inference and Annotation" +msgstr "" + +#: src/ch13-01-closures.md:142 +msgid "" +"There are more differences between functions and closures. Closures don’t " +"usually require you to annotate the types of the parameters or the return " +"value like `fn` functions do. Type annotations are required on functions " +"because the types are part of an explicit interface exposed to your users. " +"Defining this interface rigidly is important for ensuring that everyone " +"agrees on what types of values a function uses and returns. Closures, on the " +"other hand, aren’t used in an exposed interface like this: they’re stored in " +"variables and used without naming them and exposing them to users of our " +"library." +msgstr "" + +#: src/ch13-01-closures.md:151 +msgid "" +"Closures are typically short and relevant only within a narrow context " +"rather than in any arbitrary scenario. Within these limited contexts, the " +"compiler can infer the types of the parameters and the return type, similar " +"to how it’s able to infer the types of most variables (there are rare cases " +"where the compiler needs closure type annotations too)." +msgstr "" + +#: src/ch13-01-closures.md:157 +msgid "" +"As with variables, we can add type annotations if we want to increase " +"explicitness and clarity at the cost of being more verbose than is strictly " +"necessary. Annotating the types for a closure would look like the definition " +"shown in Listing 13-2. In this example, we’re defining a closure and storing " +"it in a variable rather than defining the closure in the spot we pass it as " +"an argument as we did in Listing 13-1." +msgstr "" + +#: src/ch13-01-closures.md:172 +msgid "\"calculating slowly...\"" +msgstr "" + +#: src/ch13-01-closures.md:178 +msgid "\"Today, do {} pushups!\"" +msgstr "" + +#: src/ch13-01-closures.md:179 +msgid "\"Next, do {} situps!\"" +msgstr "" + +#: src/ch13-01-closures.md:182 +msgid "\"Take a break today! Remember to stay hydrated!\"" +msgstr "" + +#: src/ch13-01-closures.md:185 +msgid "\"Today, run for {} minutes!\"" +msgstr "" + +#: src/ch13-01-closures.md:202 +msgid "" +"With type annotations added, the syntax of closures looks more similar to " +"the syntax of functions. Here we define a function that adds 1 to its " +"parameter and a closure that has the same behavior, for comparison. We’ve " +"added some spaces to line up the relevant parts. This illustrates how " +"closure syntax is similar to function syntax except for the use of pipes and " +"the amount of syntax that is optional:" +msgstr "" + +#: src/ch13-01-closures.md:216 +msgid "" +"The first line shows a function definition, and the second line shows a " +"fully annotated closure definition. In the third line, we remove the type " +"annotations from the closure definition. In the fourth line, we remove the " +"brackets, which are optional because the closure body has only one " +"expression. These are all valid definitions that will produce the same " +"behavior when they’re called. The `add_one_v3` and `add_one_v4` lines " +"require the closures to be evaluated to be able to compile because the types " +"will be inferred from their usage. This is similar to `let v = Vec::new();` " +"needing either type annotations or values of some type to be inserted into " +"the `Vec` for Rust to be able to infer the type." +msgstr "" + +#: src/ch13-01-closures.md:226 +msgid "" +"For closure definitions, the compiler will infer one concrete type for each " +"of their parameters and for their return value. For instance, Listing 13-3 " +"shows the definition of a short closure that just returns the value it " +"receives as a parameter. This closure isn’t very useful except for the " +"purposes of this example. Note that we haven’t added any type annotations to " +"the definition. Because there are no type annotations, we can call the " +"closure with any type, which we’ve done here with `String` the first time. " +"If we then try to call `example_closure` with an integer, we’ll get an error." +msgstr "" + +#: src/ch13-01-closures.md:248 +msgid "The compiler gives us this error:" +msgstr "" + +#: src/ch13-01-closures.md:250 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling closure-example v0.1.0 (file:///projects/closure-example)\n" +"error[E0308]: mismatched types\n" +" --> src/main.rs:5:29\n" +" |\n" +"5 | let n = example_closure(5);\n" +" | --------------- ^- help: try using a conversion method: `." +"to_string()`\n" +" | | |\n" +" | | expected `String`, found integer\n" +" | arguments to this function are incorrect\n" +" |\n" +"note: expected because the closure was earlier called with an argument of " +"type `String`\n" +" --> src/main.rs:4:29\n" +" |\n" +"4 | let s = example_closure(String::from(\"hello\"));\n" +" | --------------- ^^^^^^^^^^^^^^^^^^^^^ expected because this " +"argument is of type `String`\n" +" | |\n" +" | in this closure call\n" +"note: closure parameter defined here\n" +" --> src/main.rs:2:28\n" +" |\n" +"2 | let example_closure = |x| x;\n" +" | ^\n" +"\n" +"For more information about this error, try `rustc --explain E0308`.\n" +"error: could not compile `closure-example` (bin \"closure-example\") due to " +"1 previous error\n" +"```" +msgstr "" + +#: src/ch13-01-closures.md:279 +msgid "" +"The first time we call `example_closure` with the `String` value, the " +"compiler infers the type of `x` and the return type of the closure to be " +"`String`. Those types are then locked into the closure in `example_closure`, " +"and we get a type error when we next try to use a different type with the " +"same closure." +msgstr "" + +#: src/ch13-01-closures.md:284 +msgid "Capturing References or Moving Ownership" +msgstr "" + +#: src/ch13-01-closures.md:286 +msgid "" +"Closures can capture values from their environment in three ways, which " +"directly map to the three ways a function can take a parameter: borrowing " +"immutably, borrowing mutably, and taking ownership. The closure will decide " +"which of these to use based on what the body of the function does with the " +"captured values." +msgstr "" + +#: src/ch13-01-closures.md:292 +msgid "" +"In Listing 13-4, we define a closure that captures an immutable reference to " +"the vector named `list` because it only needs an immutable reference to " +"print the value:" +msgstr "" + +#: src/ch13-01-closures.md:301 src/ch13-01-closures.md:343 +#: src/ch13-01-closures.md:393 +msgid "\"Before defining closure: {list:?}\"" +msgstr "" + +#: src/ch13-01-closures.md:303 +msgid "\"From closure: {list:?}\"" +msgstr "" + +#: src/ch13-01-closures.md:305 +msgid "\"Before calling closure: {list:?}\"" +msgstr "" + +#: src/ch13-01-closures.md:307 src/ch13-01-closures.md:348 +msgid "\"After calling closure: {list:?}\"" +msgstr "" + +#: src/ch13-01-closures.md:313 +msgid "" +"This example also illustrates that a variable can bind to a closure " +"definition, and we can later call the closure by using the variable name and " +"parentheses as if the variable name were a function name." +msgstr "" + +#: src/ch13-01-closures.md:317 +msgid "" +"Because we can have multiple immutable references to `list` at the same " +"time, `list` is still accessible from the code before the closure " +"definition, after the closure definition but before the closure is called, " +"and after the closure is called. This code compiles, runs, and prints:" +msgstr "" + +#: src/ch13-01-closures.md:322 +msgid "" +"```console\n" +"$ cargo run\n" +" Locking 1 package to latest compatible version\n" +" Adding closure-example v0.1.0 (/Users/carolnichols/rust/book/tmp/" +"listings/ch13-functional-features/listing-13-04)\n" +" Compiling closure-example v0.1.0 (file:///projects/closure-example)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.43s\n" +" Running `target/debug/closure-example`\n" +"Before defining closure: [1, 2, 3]\n" +"Before calling closure: [1, 2, 3]\n" +"From closure: [1, 2, 3]\n" +"After calling closure: [1, 2, 3]\n" +"```" +msgstr "" + +#: src/ch13-01-closures.md:335 +msgid "" +"Next, in Listing 13-5, we change the closure body so that it adds an element " +"to the `list` vector. The closure now captures a mutable reference:" +msgstr "" + +#: src/ch13-01-closures.md:354 +msgid "This code compiles, runs, and prints:" +msgstr "" + +#: src/ch13-01-closures.md:356 +msgid "" +"```console\n" +"$ cargo run\n" +" Locking 1 package to latest compatible version\n" +" Adding closure-example v0.1.0 (/Users/carolnichols/rust/book/tmp/" +"listings/ch13-functional-features/listing-13-05)\n" +" Compiling closure-example v0.1.0 (file:///projects/closure-example)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.43s\n" +" Running `target/debug/closure-example`\n" +"Before defining closure: [1, 2, 3]\n" +"After calling closure: [1, 2, 3, 7]\n" +"```" +msgstr "" + +#: src/ch13-01-closures.md:367 +msgid "" +"Note that there’s no longer a `println!` between the definition and the call " +"of the `borrows_mutably` closure: when `borrows_mutably` is defined, it " +"captures a mutable reference to `list`. We don’t use the closure again after " +"the closure is called, so the mutable borrow ends. Between the closure " +"definition and the closure call, an immutable borrow to print isn’t allowed " +"because no other borrows are allowed when there’s a mutable borrow. Try " +"adding a `println!` there to see what error message you get!" +msgstr "" + +#: src/ch13-01-closures.md:375 +msgid "" +"If you want to force the closure to take ownership of the values it uses in " +"the environment even though the body of the closure doesn’t strictly need " +"ownership, you can use the `move` keyword before the parameter list." +msgstr "" + +#: src/ch13-01-closures.md:379 +msgid "" +"This technique is mostly useful when passing a closure to a new thread to " +"move the data so that it’s owned by the new thread. We’ll discuss threads " +"and why you would want to use them in detail in Chapter 16 when we talk " +"about concurrency, but for now, let’s briefly explore spawning a new thread " +"using a closure that needs the `move` keyword. Listing 13-6 shows Listing " +"13-4 modified to print the vector in a new thread rather than in the main " +"thread:" +msgstr "" + +#: src/ch13-01-closures.md:395 +msgid "\"From thread: {list:?}\"" +msgstr "" + +#: src/ch13-01-closures.md:403 +msgid "" +"We spawn a new thread, giving the thread a closure to run as an argument. " +"The closure body prints out the list. In Listing 13-4, the closure only " +"captured `list` using an immutable reference because that's the least amount " +"of access to `list` needed to print it. In this example, even though the " +"closure body still only needs an immutable reference, we need to specify " +"that `list` should be moved into the closure by putting the `move` keyword " +"at the beginning of the closure definition. The new thread might finish " +"before the rest of the main thread finishes, or the main thread might finish " +"first. If the main thread maintained ownership of `list` but ended before " +"the new thread did and dropped `list`, the immutable reference in the thread " +"would be invalid. Therefore, the compiler requires that `list` be moved into " +"the closure given to the new thread so the reference will be valid. Try " +"removing the `move` keyword or using `list` in the main thread after the " +"closure is defined to see what compiler errors you get!" +msgstr "" + +#: src/ch13-01-closures.md:419 +msgid "" +" " +" " +msgstr "" + +#: src/ch13-01-closures.md:423 +msgid "Moving Captured Values Out of Closures and the `Fn` Traits" +msgstr "" + +#: src/ch13-01-closures.md:425 +msgid "" +"Once a closure has captured a reference or captured ownership of a value " +"from the environment where the closure is defined (thus affecting what, if " +"anything, is moved _into_ the closure), the code in the body of the closure " +"defines what happens to the references or values when the closure is " +"evaluated later (thus affecting what, if anything, is moved _out of_ the " +"closure). A closure body can do any of the following: move a captured value " +"out of the closure, mutate the captured value, neither move nor mutate the " +"value, or capture nothing from the environment to begin with." +msgstr "" + +#: src/ch13-01-closures.md:434 +msgid "" +"The way a closure captures and handles values from the environment affects " +"which traits the closure implements, and traits are how functions and " +"structs can specify what kinds of closures they can use. Closures will " +"automatically implement one, two, or all three of these `Fn` traits, in an " +"additive fashion, depending on how the closure’s body handles the values:" +msgstr "" + +#: src/ch13-01-closures.md:440 +msgid "" +"`FnOnce` applies to closures that can be called once. All closures implement " +"at least this trait, because all closures can be called. A closure that " +"moves captured values out of its body will only implement `FnOnce` and none " +"of the other `Fn` traits, because it can only be called once." +msgstr "" + +#: src/ch13-01-closures.md:444 +msgid "" +"`FnMut` applies to closures that don’t move captured values out of their " +"body, but that might mutate the captured values. These closures can be " +"called more than once." +msgstr "" + +#: src/ch13-01-closures.md:447 +msgid "" +"`Fn` applies to closures that don’t move captured values out of their body " +"and that don’t mutate captured values, as well as closures that capture " +"nothing from their environment. These closures can be called more than once " +"without mutating their environment, which is important in cases such as " +"calling a closure multiple times concurrently." +msgstr "" + +#: src/ch13-01-closures.md:453 +msgid "" +"Let’s look at the definition of the `unwrap_or_else` method on `Option` " +"that we used in Listing 13-1:" +msgstr "" + +#: src/ch13-01-closures.md:470 +msgid "" +"Recall that `T` is the generic type representing the type of the value in " +"the `Some` variant of an `Option`. That type `T` is also the return type of " +"the `unwrap_or_else` function: code that calls `unwrap_or_else` on an " +"`Option`, for example, will get a `String`." +msgstr "" + +#: src/ch13-01-closures.md:475 +msgid "" +"Next, notice that the `unwrap_or_else` function has the additional generic " +"type parameter `F`. The `F` type is the type of the parameter named `f`, " +"which is the closure we provide when calling `unwrap_or_else`." +msgstr "" + +#: src/ch13-01-closures.md:479 +msgid "" +"The trait bound specified on the generic type `F` is `FnOnce() -> T`, which " +"means `F` must be able to be called once, take no arguments, and return a " +"`T`. Using `FnOnce` in the trait bound expresses the constraint that " +"`unwrap_or_else` is only going to call `f` at most one time. In the body of " +"`unwrap_or_else`, we can see that if the `Option` is `Some`, `f` won’t be " +"called. If the `Option` is `None`, `f` will be called once. Because all " +"closures implement `FnOnce`, `unwrap_or_else` accepts all three kinds of " +"closures and is as flexible as it can be." +msgstr "" + +#: src/ch13-01-closures.md:488 +msgid "" +"Note: Functions can implement all three of the `Fn` traits too. If what we " +"want to do doesn’t require capturing a value from the environment, we can " +"use the name of a function rather than a closure where we need something " +"that implements one of the `Fn` traits. For example, on an `Option>` " +"value, we could call `unwrap_or_else(Vec::new)` to get a new, empty vector " +"if the value is `None`." +msgstr "" + +#: src/ch13-01-closures.md:495 +msgid "" +"Now let’s look at the standard library method `sort_by_key` defined on " +"slices, to see how that differs from `unwrap_or_else` and why `sort_by_key` " +"uses `FnMut` instead of `FnOnce` for the trait bound. The closure gets one " +"argument in the form of a reference to the current item in the slice being " +"considered, and returns a value of type `K` that can be ordered. This " +"function is useful when you want to sort a slice by a particular attribute " +"of each item. In Listing 13-7, we have a list of `Rectangle` instances and " +"we use `sort_by_key` to order them by their `width` attribute from low to " +"high:" +msgstr "" + +#: src/ch13-01-closures.md:521 src/ch13-01-closures.md:582 +msgid "\"{list:#?}\"" +msgstr "" + +#: src/ch13-01-closures.md:527 +msgid "This code prints:" +msgstr "" + +#: src/ch13-01-closures.md:529 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling rectangles v0.1.0 (file:///projects/rectangles)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.41s\n" +" Running `target/debug/rectangles`\n" +"[\n" +" Rectangle {\n" +" width: 3,\n" +" height: 5,\n" +" },\n" +" Rectangle {\n" +" width: 7,\n" +" height: 12,\n" +" },\n" +" Rectangle {\n" +" width: 10,\n" +" height: 1,\n" +" },\n" +"]\n" +"```" +msgstr "" + +#: src/ch13-01-closures.md:550 +msgid "" +"The reason `sort_by_key` is defined to take an `FnMut` closure is that it " +"calls the closure multiple times: once for each item in the slice. The " +"closure `|r| r.width` doesn’t capture, mutate, or move out anything from its " +"environment, so it meets the trait bound requirements." +msgstr "" + +#: src/ch13-01-closures.md:555 +msgid "" +"In contrast, Listing 13-8 shows an example of a closure that implements just " +"the `FnOnce` trait, because it moves a value out of the environment. The " +"compiler won’t let us use this closure with `sort_by_key`:" +msgstr "" + +#: src/ch13-01-closures.md:576 +msgid "\"closure called\"" +msgstr "" + +#: src/ch13-01-closures.md:588 +msgid "" +"This is a contrived, convoluted way (that doesn’t work) to try and count the " +"number of times `sort_by_key` calls the closure when sorting `list`. This " +"code attempts to do this counting by pushing `value`—a `String` from the " +"closure’s environment—into the `sort_operations` vector. The closure " +"captures `value` then moves `value` out of the closure by transferring " +"ownership of `value` to the `sort_operations` vector. This closure can be " +"called once; trying to call it a second time wouldn’t work because `value` " +"would no longer be in the environment to be pushed into `sort_operations` " +"again! Therefore, this closure only implements `FnOnce`. When we try to " +"compile this code, we get this error that `value` can’t be moved out of the " +"closure because the closure must implement `FnMut`:" +msgstr "" + +#: src/ch13-01-closures.md:600 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling rectangles v0.1.0 (file:///projects/rectangles)\n" +"error[E0507]: cannot move out of `value`, a captured variable in an `FnMut` " +"closure\n" +" --> src/main.rs:18:30\n" +" |\n" +"15 | let value = String::from(\"closure called\");\n" +" | ----- captured outer variable\n" +"16 |\n" +"17 | list.sort_by_key(|r| {\n" +" | --- captured by this `FnMut` closure\n" +"18 | sort_operations.push(value);\n" +" | ^^^^^ move occurs because `value` has type " +"`String`, which does not implement the `Copy` trait\n" +" |\n" +"help: consider cloning the value if the performance cost is acceptable\n" +" |\n" +"18 | sort_operations.push(value.clone());\n" +" | ++++++++\n" +"\n" +"For more information about this error, try `rustc --explain E0507`.\n" +"error: could not compile `rectangles` (bin \"rectangles\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch13-01-closures.md:623 +msgid "" +"The error points to the line in the closure body that moves `value` out of " +"the environment. To fix this, we need to change the closure body so that it " +"doesn’t move values out of the environment. To count the number of times the " +"closure is called, keeping a counter in the environment and incrementing its " +"value in the closure body is a more straightforward way to calculate that. " +"The closure in Listing 13-9 works with `sort_by_key` because it is only " +"capturing a mutable reference to the `num_sort_operations` counter and can " +"therefore be called more than once:" +msgstr "" + +#: src/ch13-01-closures.md:653 +msgid "\"{list:#?}, sorted in {num_sort_operations} operations\"" +msgstr "" + +#: src/ch13-01-closures.md:659 +msgid "" +"The `Fn` traits are important when defining or using functions or types that " +"make use of closures. In the next section, we’ll discuss iterators. Many " +"iterator methods take closure arguments, so keep these closure details in " +"mind as we continue!" +msgstr "" + +#: src/ch13-02-iterators.md:3 +msgid "" +"The iterator pattern allows you to perform some task on a sequence of items " +"in turn. An iterator is responsible for the logic of iterating over each " +"item and determining when the sequence has finished. When you use iterators, " +"you don’t have to reimplement that logic yourself." +msgstr "" + +#: src/ch13-02-iterators.md:8 +msgid "" +"In Rust, iterators are _lazy_, meaning they have no effect until you call " +"methods that consume the iterator to use it up. For example, the code in " +"Listing 13-10 creates an iterator over the items in the vector `v1` by " +"calling the `iter` method defined on `Vec`. This code by itself doesn’t " +"do anything useful." +msgstr "" + +#: src/ch13-02-iterators.md:26 +msgid "" +"The iterator is stored in the `v1_iter` variable. Once we’ve created an " +"iterator, we can use it in a variety of ways. In Listing 3-5 in Chapter 3, " +"we iterated over an array using a `for` loop to execute some code on each of " +"its items. Under the hood this implicitly created and then consumed an " +"iterator, but we glossed over how exactly that works until now." +msgstr "" + +#: src/ch13-02-iterators.md:32 +msgid "" +"In the example in Listing 13-11, we separate the creation of the iterator " +"from the use of the iterator in the `for` loop. When the `for` loop is " +"called using the iterator in `v1_iter`, each element in the iterator is used " +"in one iteration of the loop, which prints out each value." +msgstr "" + +#: src/ch13-02-iterators.md:46 +msgid "\"Got: {val}\"" +msgstr "" + +#: src/ch13-02-iterators.md:53 +msgid "" +"In languages that don’t have iterators provided by their standard libraries, " +"you would likely write this same functionality by starting a variable at " +"index 0, using that variable to index into the vector to get a value, and " +"incrementing the variable value in a loop until it reached the total number " +"of items in the vector." +msgstr "" + +#: src/ch13-02-iterators.md:59 +msgid "" +"Iterators handle all that logic for you, cutting down on repetitive code you " +"could potentially mess up. Iterators give you more flexibility to use the " +"same logic with many different kinds of sequences, not just data structures " +"you can index into, like vectors. Let’s examine how iterators do that." +msgstr "" + +#: src/ch13-02-iterators.md:64 +msgid "The `Iterator` Trait and the `next` Method" +msgstr "" + +#: src/ch13-02-iterators.md:66 +msgid "" +"All iterators implement a trait named `Iterator` that is defined in the " +"standard library. The definition of the trait looks like this:" +msgstr "" + +#: src/ch13-02-iterators.md:75 +msgid "// methods with default implementations elided\n" +msgstr "" + +#: src/ch13-02-iterators.md:79 +msgid "" +"Notice this definition uses some new syntax: `type Item` and `Self::Item`, " +"which are defining an _associated type_ with this trait. We’ll talk about " +"associated types in depth in Chapter 19. For now, all you need to know is " +"that this code says implementing the `Iterator` trait requires that you also " +"define an `Item` type, and this `Item` type is used in the return type of " +"the `next` method. In other words, the `Item` type will be the type returned " +"from the iterator." +msgstr "" + +#: src/ch13-02-iterators.md:87 +msgid "" +"The `Iterator` trait only requires implementors to define one method: the " +"`next` method, which returns one item of the iterator at a time wrapped in " +"`Some` and, when iteration is over, returns `None`." +msgstr "" + +#: src/ch13-02-iterators.md:91 +msgid "" +"We can call the `next` method on iterators directly; Listing 13-12 " +"demonstrates what values are returned from repeated calls to `next` on the " +"iterator created from the vector." +msgstr "" + +#: src/ch13-02-iterators.md:116 +msgid "" +"Note that we needed to make `v1_iter` mutable: calling the `next` method on " +"an iterator changes internal state that the iterator uses to keep track of " +"where it is in the sequence. In other words, this code _consumes_, or uses " +"up, the iterator. Each call to `next` eats up an item from the iterator. We " +"didn’t need to make `v1_iter` mutable when we used a `for` loop because the " +"loop took ownership of `v1_iter` and made it mutable behind the scenes." +msgstr "" + +#: src/ch13-02-iterators.md:123 +msgid "" +"Also note that the values we get from the calls to `next` are immutable " +"references to the values in the vector. The `iter` method produces an " +"iterator over immutable references. If we want to create an iterator that " +"takes ownership of `v1` and returns owned values, we can call `into_iter` " +"instead of `iter`. Similarly, if we want to iterate over mutable references, " +"we can call `iter_mut` instead of `iter`." +msgstr "" + +#: src/ch13-02-iterators.md:130 +msgid "Methods that Consume the Iterator" +msgstr "" + +#: src/ch13-02-iterators.md:132 +msgid "" +"The `Iterator` trait has a number of different methods with default " +"implementations provided by the standard library; you can find out about " +"these methods by looking in the standard library API documentation for the " +"`Iterator` trait. Some of these methods call the `next` method in their " +"definition, which is why you’re required to implement the `next` method when " +"implementing the `Iterator` trait." +msgstr "" + +#: src/ch13-02-iterators.md:139 +msgid "" +"Methods that call `next` are called _consuming adaptors_, because calling " +"them uses up the iterator. One example is the `sum` method, which takes " +"ownership of the iterator and iterates through the items by repeatedly " +"calling `next`, thus consuming the iterator. As it iterates through, it adds " +"each item to a running total and returns the total when iteration is " +"complete. Listing 13-13 has a test illustrating a use of the `sum` method:" +msgstr "" + +#: src/ch13-02-iterators.md:166 +msgid "" +"We aren’t allowed to use `v1_iter` after the call to `sum` because `sum` " +"takes ownership of the iterator we call it on." +msgstr "" + +#: src/ch13-02-iterators.md:169 +msgid "Methods that Produce Other Iterators" +msgstr "" + +#: src/ch13-02-iterators.md:171 +msgid "" +"_Iterator adaptors_ are methods defined on the `Iterator` trait that don’t " +"consume the iterator. Instead, they produce different iterators by changing " +"some aspect of the original iterator." +msgstr "" + +#: src/ch13-02-iterators.md:175 +msgid "" +"Listing 13-14 shows an example of calling the iterator adaptor method `map`, " +"which takes a closure to call on each item as the items are iterated " +"through. The `map` method returns a new iterator that produces the modified " +"items. The closure here creates a new iterator in which each item from the " +"vector will be incremented by 1:" +msgstr "" + +#: src/ch13-02-iterators.md:193 +msgid "However, this code produces a warning:" +msgstr "" + +#: src/ch13-02-iterators.md:195 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling iterators v0.1.0 (file:///projects/iterators)\n" +"warning: unused `Map` that must be used\n" +" --> src/main.rs:4:5\n" +" |\n" +"4 | v1.iter().map(|x| x + 1);\n" +" | ^^^^^^^^^^^^^^^^^^^^^^^^\n" +" |\n" +" = note: iterators are lazy and do nothing unless consumed\n" +" = note: `#[warn(unused_must_use)]` on by default\n" +"help: use `let _ = ...` to ignore the resulting value\n" +" |\n" +"4 | let _ = v1.iter().map(|x| x + 1);\n" +" | +++++++\n" +"\n" +"warning: `iterators` (bin \"iterators\") generated 1 warning\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.47s\n" +" Running `target/debug/iterators`\n" +"```" +msgstr "" + +#: src/ch13-02-iterators.md:216 +msgid "" +"The code in Listing 13-14 doesn’t do anything; the closure we’ve specified " +"never gets called. The warning reminds us why: iterator adaptors are lazy, " +"and we need to consume the iterator here." +msgstr "" + +#: src/ch13-02-iterators.md:220 +msgid "" +"To fix this warning and consume the iterator, we’ll use the `collect` " +"method, which we used in Chapter 12 with `env::args` in Listing 12-1. This " +"method consumes the iterator and collects the resulting values into a " +"collection data type." +msgstr "" + +#: src/ch13-02-iterators.md:225 +msgid "" +"In Listing 13-15, we collect the results of iterating over the iterator " +"that’s returned from the call to `map` into a vector. This vector will end " +"up containing each item from the original vector incremented by 1." +msgstr "" + +#: src/ch13-02-iterators.md:243 +msgid "" +"Because `map` takes a closure, we can specify any operation we want to " +"perform on each item. This is a great example of how closures let you " +"customize some behavior while reusing the iteration behavior that the " +"`Iterator` trait provides." +msgstr "" + +#: src/ch13-02-iterators.md:248 +msgid "" +"You can chain multiple calls to iterator adaptors to perform complex actions " +"in a readable way. But because all iterators are lazy, you have to call one " +"of the consuming adaptor methods to get results from calls to iterator " +"adaptors." +msgstr "" + +#: src/ch13-02-iterators.md:252 +msgid "Using Closures that Capture Their Environment" +msgstr "" + +#: src/ch13-02-iterators.md:254 +msgid "" +"Many iterator adapters take closures as arguments, and commonly the closures " +"we’ll specify as arguments to iterator adapters will be closures that " +"capture their environment." +msgstr "" + +#: src/ch13-02-iterators.md:258 +msgid "" +"For this example, we’ll use the `filter` method that takes a closure. The " +"closure gets an item from the iterator and returns a `bool`. If the closure " +"returns `true`, the value will be included in the iteration produced by " +"`filter`. If the closure returns `false`, the value won’t be included." +msgstr "" + +#: src/ch13-02-iterators.md:263 +msgid "" +"In Listing 13-16, we use `filter` with a closure that captures the " +"`shoe_size` variable from its environment to iterate over a collection of " +"`Shoe` struct instances. It will return only shoes that are the specified " +"size." +msgstr "" + +#: src/ch13-02-iterators.md:289 src/ch13-02-iterators.md:308 +msgid "\"sneaker\"" +msgstr "" + +#: src/ch13-02-iterators.md:293 +msgid "\"sandal\"" +msgstr "" + +#: src/ch13-02-iterators.md:297 src/ch13-02-iterators.md:312 +msgid "\"boot\"" +msgstr "" + +#: src/ch13-02-iterators.md:322 +msgid "" +"The `shoes_in_size` function takes ownership of a vector of shoes and a shoe " +"size as parameters. It returns a vector containing only shoes of the " +"specified size." +msgstr "" + +#: src/ch13-02-iterators.md:326 +msgid "" +"In the body of `shoes_in_size`, we call `into_iter` to create an iterator " +"that takes ownership of the vector. Then we call `filter` to adapt that " +"iterator into a new iterator that only contains elements for which the " +"closure returns `true`." +msgstr "" + +#: src/ch13-02-iterators.md:331 +msgid "" +"The closure captures the `shoe_size` parameter from the environment and " +"compares the value with each shoe’s size, keeping only shoes of the size " +"specified. Finally, calling `collect` gathers the values returned by the " +"adapted iterator into a vector that’s returned by the function." +msgstr "" + +#: src/ch13-02-iterators.md:336 +msgid "" +"The test shows that when we call `shoes_in_size`, we get back only shoes " +"that have the same size as the value we specified." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:3 +msgid "" +"With this new knowledge about iterators, we can improve the I/O project in " +"Chapter 12 by using iterators to make places in the code clearer and more " +"concise. Let’s look at how iterators can improve our implementation of the " +"`Config::build` function and the `search` function." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:8 +msgid "Removing a `clone` Using an Iterator" +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:10 +msgid "" +"In Listing 12-6, we added code that took a slice of `String` values and " +"created an instance of the `Config` struct by indexing into the slice and " +"cloning the values, allowing the `Config` struct to own those values. In " +"Listing 13-17, we’ve reproduced the implementation of the `Config::build` " +"function as it was in Listing 12-23:" +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:127 +msgid "" +"At the time, we said not to worry about the inefficient `clone` calls " +"because we would remove them in the future. Well, that time is now!" +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:130 +msgid "" +"We needed `clone` here because we have a slice with `String` elements in the " +"parameter `args`, but the `build` function doesn’t own `args`. To return " +"ownership of a `Config` instance, we had to clone the values from the " +"`query` and `file_path` fields of `Config` so the `Config` instance can own " +"its values." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:135 +msgid "" +"With our new knowledge about iterators, we can change the `build` function " +"to take ownership of an iterator as its argument instead of borrowing a " +"slice. We’ll use the iterator functionality instead of the code that checks " +"the length of the slice and indexes into specific locations. This will " +"clarify what the `Config::build` function is doing because the iterator will " +"access the values." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:141 +msgid "" +"Once `Config::build` takes ownership of the iterator and stops using " +"indexing operations that borrow, we can move the `String` values from the " +"iterator into `Config` rather than calling `clone` and making a new " +"allocation." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:145 +msgid "Using the Returned Iterator Directly" +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:147 +msgid "" +"Open your I/O project’s _src/main.rs_ file, which should look like this:" +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:174 +msgid "" +"We’ll first change the start of the `main` function that we had in Listing " +"12-24 to the code in Listing 13-18, which this time uses an iterator. This " +"won’t compile until we update `Config::build` as well." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:203 +msgid "" +"The `env::args` function returns an iterator! Rather than collecting the " +"iterator values into a vector and then passing a slice to `Config::build`, " +"now we’re passing ownership of the iterator returned from `env::args` to " +"`Config::build` directly." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:208 +msgid "" +"Next, we need to update the definition of `Config::build`. In your I/O " +"project’s _src/lib.rs_ file, let’s change the signature of `Config::build` " +"to look like Listing 13-19. This still won’t compile because we need to " +"update the function body." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:327 +msgid "" +"The standard library documentation for the `env::args` function shows that " +"the type of the iterator it returns is `std::env::Args`, and that type " +"implements the `Iterator` trait and returns `String` values." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:331 +msgid "" +"We’ve updated the signature of the `Config::build` function so the parameter " +"`args` has a generic type with the trait bounds `impl Iterator` instead of `&[String]`. This usage of the `impl Trait` syntax we " +"discussed in the [“Traits as Parameters”](ch10-02-traits.html#traits-as-" +"parameters) section of Chapter 10 means that `args` can be " +"any type that implements the `Iterator` trait and returns `String` items." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:338 +msgid "" +"Because we’re taking ownership of `args` and we’ll be mutating `args` by " +"iterating over it, we can add the `mut` keyword into the specification of " +"the `args` parameter to make it mutable." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:342 +msgid "Using `Iterator` Trait Methods Instead of Indexing" +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:344 +msgid "" +"Next, we’ll fix the body of `Config::build`. Because `args` implements the " +"`Iterator` trait, we know we can call the `next` method on it! Listing 13-20 " +"updates the code from Listing 12-23 to use the `next` method:" +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:369 +#: src/ch13-03-improving-our-io-project.md:568 +msgid "\"Didn't get a query string\"" +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:374 +#: src/ch13-03-improving-our-io-project.md:573 +msgid "\"Didn't get a file path\"" +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:466 +msgid "" +"Remember that the first value in the return value of `env::args` is the name " +"of the program. We want to ignore that and get to the next value, so first " +"we call `next` and do nothing with the return value. Second, we call `next` " +"to get the value we want to put in the `query` field of `Config`. If `next` " +"returns a `Some`, we use a `match` to extract the value. If it returns " +"`None`, it means not enough arguments were given and we return early with an " +"`Err` value. We do the same thing for the `file_path` value." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:474 +msgid "Making Code Clearer with Iterator Adaptors" +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:476 +msgid "" +"We can also take advantage of iterators in the `search` function in our I/O " +"project, which is reproduced here in Listing 13-21 as it was in Listing " +"12-19:" +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:540 +msgid "" +"We can write this code in a more concise way using iterator adaptor methods. " +"Doing so also lets us avoid having a mutable intermediate `results` vector. " +"The functional programming style prefers to minimize the amount of mutable " +"state to make code clearer. Removing the mutable state might enable a future " +"enhancement to make searching happen in parallel, because we wouldn’t have " +"to manage concurrent access to the `results` vector. Listing 13-22 shows " +"this change:" +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:660 +msgid "" +"Recall that the purpose of the `search` function is to return all lines in " +"`contents` that contain the `query`. Similar to the `filter` example in " +"Listing 13-16, this code uses the `filter` adaptor to keep only the lines " +"that `line.contains(query)` returns `true` for. We then collect the matching " +"lines into another vector with `collect`. Much simpler! Feel free to make " +"the same change to use iterator methods in the `search_case_insensitive` " +"function as well." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:668 +msgid "Choosing Between Loops or Iterators" +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:670 +msgid "" +"The next logical question is which style you should choose in your own code " +"and why: the original implementation in Listing 13-21 or the version using " +"iterators in Listing 13-22. Most Rust programmers prefer to use the iterator " +"style. It’s a bit tougher to get the hang of at first, but once you get a " +"feel for the various iterator adaptors and what they do, iterators can be " +"easier to understand. Instead of fiddling with the various bits of looping " +"and building new vectors, the code focuses on the high-level objective of " +"the loop. This abstracts away some of the commonplace code so it’s easier to " +"see the concepts that are unique to this code, such as the filtering " +"condition each element in the iterator must pass." +msgstr "" + +#: src/ch13-03-improving-our-io-project.md:681 +msgid "" +"But are the two implementations truly equivalent? The intuitive assumption " +"might be that the more low-level loop will be faster. Let’s talk about " +"performance." +msgstr "" + +#: src/ch13-04-performance.md:3 +msgid "" +"To determine whether to use loops or iterators, you need to know which " +"implementation is faster: the version of the `search` function with an " +"explicit `for` loop or the version with iterators." +msgstr "" + +#: src/ch13-04-performance.md:7 +msgid "" +"We ran a benchmark by loading the entire contents of _The Adventures of " +"Sherlock Holmes_ by Sir Arthur Conan Doyle into a `String` and looking for " +"the word _the_ in the contents. Here are the results of the benchmark on the " +"version of `search` using the `for` loop and the version using iterators:" +msgstr "" + +#: src/ch13-04-performance.md:17 +msgid "" +"The iterator version was slightly faster! We won’t explain the benchmark " +"code here, because the point is not to prove that the two versions are " +"equivalent but to get a general sense of how these two implementations " +"compare performance-wise." +msgstr "" + +#: src/ch13-04-performance.md:22 +msgid "" +"For a more comprehensive benchmark, you should check using various texts of " +"various sizes as the `contents`, different words and words of different " +"lengths as the `query`, and all kinds of other variations. The point is " +"this: iterators, although a high-level abstraction, get compiled down to " +"roughly the same code as if you’d written the lower-level code yourself. " +"Iterators are one of Rust’s _zero-cost abstractions_, by which we mean using " +"the abstraction imposes no additional runtime overhead. This is analogous to " +"how Bjarne Stroustrup, the original designer and implementor of C++, defines " +"_zero-overhead_ in “Foundations of C++” (2012):" +msgstr "" + +#: src/ch13-04-performance.md:32 +msgid "" +"In general, C++ implementations obey the zero-overhead principle: What you " +"don’t use, you don’t pay for. And further: What you do use, you couldn’t " +"hand code any better." +msgstr "" + +#: src/ch13-04-performance.md:36 +msgid "" +"As another example, the following code is taken from an audio decoder. The " +"decoding algorithm uses the linear prediction mathematical operation to " +"estimate future values based on a linear function of the previous samples. " +"This code uses an iterator chain to do some math on three variables in " +"scope: a `buffer` slice of data, an array of 12 `coefficients`, and an " +"amount by which to shift data in `qlp_shift`. We’ve declared the variables " +"within this example but not given them any values; although this code " +"doesn’t have much meaning outside of its context, it’s still a concise, real-" +"world example of how Rust translates high-level ideas to low-level code." +msgstr "" + +#: src/ch13-04-performance.md:61 +msgid "" +"To calculate the value of `prediction`, this code iterates through each of " +"the 12 values in `coefficients` and uses the `zip` method to pair the " +"coefficient values with the previous 12 values in `buffer`. Then, for each " +"pair, we multiply the values together, sum all the results, and shift the " +"bits in the sum `qlp_shift` bits to the right." +msgstr "" + +#: src/ch13-04-performance.md:67 +msgid "" +"Calculations in applications like audio decoders often prioritize " +"performance most highly. Here, we’re creating an iterator, using two " +"adaptors, and then consuming the value. What assembly code would this Rust " +"code compile to? Well, as of this writing, it compiles down to the same " +"assembly you’d write by hand. There’s no loop at all corresponding to the " +"iteration over the values in `coefficients`: Rust knows that there are 12 " +"iterations, so it “unrolls” the loop. _Unrolling_ is an optimization that " +"removes the overhead of the loop controlling code and instead generates " +"repetitive code for each iteration of the loop." +msgstr "" + +#: src/ch13-04-performance.md:77 +msgid "" +"All of the coefficients get stored in registers, which means accessing the " +"values is very fast. There are no bounds checks on the array access at " +"runtime. All these optimizations that Rust is able to apply make the " +"resulting code extremely efficient. Now that you know this, you can use " +"iterators and closures without fear! They make code seem like it’s higher " +"level but don’t impose a runtime performance penalty for doing so." +msgstr "" + +#: src/ch13-04-performance.md:86 +msgid "" +"Closures and iterators are Rust features inspired by functional programming " +"language ideas. They contribute to Rust’s capability to clearly express high-" +"level ideas at low-level performance. The implementations of closures and " +"iterators are such that runtime performance is not affected. This is part of " +"Rust’s goal to strive to provide zero-cost abstractions." +msgstr "" + +#: src/ch13-04-performance.md:92 +msgid "" +"Now that we’ve improved the expressiveness of our I/O project, let’s look at " +"some more features of `cargo` that will help us share the project with the " +"world." +msgstr "" + +#: src/ch14-00-more-about-cargo.md:1 +msgid "More About Cargo and Crates.io" +msgstr "" + +#: src/ch14-00-more-about-cargo.md:3 +msgid "" +"So far we’ve used only the most basic features of Cargo to build, run, and " +"test our code, but it can do a lot more. In this chapter, we’ll discuss some " +"of its other, more advanced features to show you how to do the following:" +msgstr "" + +#: src/ch14-00-more-about-cargo.md:7 +msgid "Customize your build through release profiles" +msgstr "" + +#: src/ch14-00-more-about-cargo.md:8 +msgid "Publish libraries on [crates.io](https://crates.io/)" +msgstr "" + +#: src/ch14-00-more-about-cargo.md:9 +msgid "Organize large projects with workspaces" +msgstr "" + +#: src/ch14-00-more-about-cargo.md:10 +msgid "Install binaries from [crates.io](https://crates.io/)" +msgstr "" + +#: src/ch14-00-more-about-cargo.md:11 +msgid "Extend Cargo using custom commands" +msgstr "" + +#: src/ch14-00-more-about-cargo.md:13 +msgid "" +"Cargo can do even more than the functionality we cover in this chapter, so " +"for a full explanation of all its features, see [its documentation](https://" +"doc.rust-lang.org/cargo/)." +msgstr "" + +#: src/ch14-01-release-profiles.md:3 +msgid "" +"In Rust, _release profiles_ are predefined and customizable profiles with " +"different configurations that allow a programmer to have more control over " +"various options for compiling code. Each profile is configured independently " +"of the others." +msgstr "" + +#: src/ch14-01-release-profiles.md:8 +msgid "" +"Cargo has two main profiles: the `dev` profile Cargo uses when you run " +"`cargo build` and the `release` profile Cargo uses when you run `cargo build " +"--release`. The `dev` profile is defined with good defaults for development, " +"and the `release` profile has good defaults for release builds." +msgstr "" + +#: src/ch14-01-release-profiles.md:13 +msgid "These profile names might be familiar from the output of your builds:" +msgstr "" + +#: src/ch14-01-release-profiles.md:29 +msgid "" +"The `dev` and `release` are these different profiles used by the compiler." +msgstr "" + +#: src/ch14-01-release-profiles.md:31 +msgid "" +"Cargo has default settings for each of the profiles that apply when you " +"haven't explicitly added any `[profile.*]` sections in the project’s _Cargo." +"toml_ file. By adding `[profile.*]` sections for any profile you want to " +"customize, you override any subset of the default settings. For example, " +"here are the default values for the `opt-level` setting for the `dev` and " +"`release` profiles:" +msgstr "" + +#: src/ch14-01-release-profiles.md:47 +msgid "" +"The `opt-level` setting controls the number of optimizations Rust will apply " +"to your code, with a range of 0 to 3. Applying more optimizations extends " +"compiling time, so if you’re in development and compiling your code often, " +"you’ll want fewer optimizations to compile faster even if the resulting code " +"runs slower. The default `opt-level` for `dev` is therefore `0`. When you’re " +"ready to release your code, it’s best to spend more time compiling. You’ll " +"only compile in release mode once, but you’ll run the compiled program many " +"times, so release mode trades longer compile time for code that runs faster. " +"That is why the default `opt-level` for the `release` profile is `3`." +msgstr "" + +#: src/ch14-01-release-profiles.md:57 +msgid "" +"You can override a default setting by adding a different value for it in " +"_Cargo.toml_. For example, if we want to use optimization level 1 in the " +"development profile, we can add these two lines to our project’s _Cargo." +"toml_ file:" +msgstr "" + +#: src/ch14-01-release-profiles.md:69 +msgid "" +"This code overrides the default setting of `0`. Now when we run `cargo " +"build`, Cargo will use the defaults for the `dev` profile plus our " +"customization to `opt-level`. Because we set `opt-level` to `1`, Cargo will " +"apply more optimizations than the default, but not as many as in a release " +"build." +msgstr "" + +#: src/ch14-01-release-profiles.md:74 +msgid "" +"For the full list of configuration options and defaults for each profile, " +"see [Cargo’s documentation](https://doc.rust-lang.org/cargo/reference/" +"profiles.html)." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:3 +msgid "" +"We’ve used packages from [crates.io](https://crates.io/) as " +"dependencies of our project, but you can also share your code with other " +"people by publishing your own packages. The crate registry at [crates.io]" +"(https://crates.io/) distributes the source code of your " +"packages, so it primarily hosts code that is open source." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:9 +msgid "" +"Rust and Cargo have features that make your published package easier for " +"people to find and use. We’ll talk about some of these features next and " +"then explain how to publish a package." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:13 +msgid "Making Useful Documentation Comments" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:15 +msgid "" +"Accurately documenting your packages will help other users know how and when " +"to use them, so it’s worth investing the time to write documentation. In " +"Chapter 3, we discussed how to comment Rust code using two slashes, `//`. " +"Rust also has a particular kind of comment for documentation, known " +"conveniently as a _documentation comment_, that will generate HTML " +"documentation. The HTML displays the contents of documentation comments for " +"public API items intended for programmers interested in knowing how to _use_ " +"your crate as opposed to how your crate is _implemented_." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:24 +msgid "" +"Documentation comments use three slashes, `///`, instead of two and support " +"Markdown notation for formatting the text. Place documentation comments just " +"before the item they’re documenting. Listing 14-1 shows documentation " +"comments for an `add_one` function in a crate named `my_crate`." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:32 +msgid "" +"/// Adds one to the number given.\n" +"///\n" +"/// # Examples\n" +"///\n" +"/// ```\n" +"/// let arg = 5;\n" +"/// let answer = my_crate::add_one(arg);\n" +"///\n" +"/// assert_eq!(6, answer);\n" +"/// ```\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:49 +msgid "" +"Here, we give a description of what the `add_one` function does, start a " +"section with the heading `Examples`, and then provide code that demonstrates " +"how to use the `add_one` function. We can generate the HTML documentation " +"from this documentation comment by running `cargo doc`. This command runs " +"the `rustdoc` tool distributed with Rust and puts the generated HTML " +"documentation in the _target/doc_ directory." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:56 +msgid "" +"For convenience, running `cargo doc --open` will build the HTML for your " +"current crate’s documentation (as well as the documentation for all of your " +"crate’s dependencies) and open the result in a web browser. Navigate to the " +"`add_one` function and you’ll see how the text in the documentation comments " +"is rendered, as shown in Figure 14-1:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:64 +msgid "" +"Figure 14-1: HTML documentation for the `add_one` " +"function" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:67 +msgid "Commonly Used Sections" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:69 +msgid "" +"We used the `# Examples` Markdown heading in Listing 14-1 to create a " +"section in the HTML with the title “Examples.” Here are some other sections " +"that crate authors commonly use in their documentation:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:73 +msgid "" +"**Panics**: The scenarios in which the function being documented could " +"panic. Callers of the function who don’t want their programs to panic should " +"make sure they don’t call the function in these situations." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:76 +msgid "" +"**Errors**: If the function returns a `Result`, describing the kinds of " +"errors that might occur and what conditions might cause those errors to be " +"returned can be helpful to callers so they can write code to handle the " +"different kinds of errors in different ways." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:80 +msgid "" +"**Safety**: If the function is `unsafe` to call (we discuss unsafety in " +"Chapter 19), there should be a section explaining why the function is unsafe " +"and covering the invariants that the function expects callers to uphold." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:84 +msgid "" +"Most documentation comments don’t need all of these sections, but this is a " +"good checklist to remind you of the aspects of your code users will be " +"interested in knowing about." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:88 +msgid "Documentation Comments as Tests" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:90 +msgid "" +"Adding example code blocks in your documentation comments can help " +"demonstrate how to use your library, and doing so has an additional bonus: " +"running `cargo test` will run the code examples in your documentation as " +"tests! Nothing is better than documentation with examples. But nothing is " +"worse than examples that don’t work because the code has changed since the " +"documentation was written. If we run `cargo test` with the documentation for " +"the `add_one` function from Listing 14-1, we will see a section in the test " +"results like this:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:113 +msgid "" +"Now if we change either the function or the example so the `assert_eq!` in " +"the example panics and run `cargo test` again, we’ll see that the doc tests " +"catch that the example and the code are out of sync with each other!" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:117 +msgid "Commenting Contained Items" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:119 +msgid "" +"The style of doc comment `//!` adds documentation to the item that contains " +"the comments rather than to the items following the comments. We typically " +"use these doc comments inside the crate root file (_src/lib.rs_ by " +"convention) or inside a module to document the crate or the module as a " +"whole." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:124 +msgid "" +"For example, to add documentation that describes the purpose of the " +"`my_crate` crate that contains the `add_one` function, we add documentation " +"comments that start with `//!` to the beginning of the _src/lib.rs_ file, as " +"shown in Listing 14-2:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:132 +msgid "" +"//! # My Crate\n" +"//!\n" +"//! `my_crate` is a collection of utilities to make performing certain\n" +"//! calculations more convenient.\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:136 +msgid "" +"/// Adds one to the number given.\n" +"// --snip--\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:139 +#: src/ch14-02-publishing-to-crates-io.md:141 +#: src/ch14-02-publishing-to-crates-io.md:145 src/ch20-02-multithreaded.md:599 +#: src/ch20-02-multithreaded.md:601 src/ch20-02-multithreaded.md:603 +#: src/ch20-02-multithreaded.md:697 src/ch20-02-multithreaded.md:699 +#: src/ch20-02-multithreaded.md:701 src/ch20-02-multithreaded.md:807 +#: src/ch20-02-multithreaded.md:809 src/ch20-02-multithreaded.md:811 +#: src/ch20-02-multithreaded.md:875 src/ch20-02-multithreaded.md:877 +#: src/ch20-02-multithreaded.md:879 src/ch20-02-multithreaded.md:995 +#: src/ch20-02-multithreaded.md:997 src/ch20-02-multithreaded.md:999 +#: src/ch20-02-multithreaded.md:1083 src/ch20-02-multithreaded.md:1085 +#: src/ch20-02-multithreaded.md:1087 src/ch20-02-multithreaded.md:1168 +#: src/ch20-02-multithreaded.md:1170 src/ch20-02-multithreaded.md:1172 +#: src/ch20-02-multithreaded.md:1321 src/ch20-02-multithreaded.md:1323 +#: src/ch20-02-multithreaded.md:1325 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:42 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:44 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:46 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:164 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:166 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:168 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:284 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:286 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:288 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:372 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:374 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:376 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:482 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:484 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:486 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:582 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:584 +#: src/ch20-03-graceful-shutdown-and-cleanup.md:586 +msgid "///\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:140 +msgid "/// # Examples\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:142 +#: src/ch14-02-publishing-to-crates-io.md:147 +msgid "/// ```\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:143 +msgid "/// let arg = 5;\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:144 +msgid "/// let answer = my_crate::add_one(arg);\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:146 +msgid "/// assert_eq!(6, answer);\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:155 +msgid "" +"Notice there isn’t any code after the last line that begins with `//!`. " +"Because we started the comments with `//!` instead of `///`, we’re " +"documenting the item that contains this comment rather than an item that " +"follows this comment. In this case, that item is the _src/lib.rs_ file, " +"which is the crate root. These comments describe the entire crate." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:161 +msgid "" +"When we run `cargo doc --open`, these comments will display on the front " +"page of the documentation for `my_crate` above the list of public items in " +"the crate, as shown in Figure 14-2:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:167 +msgid "" +"Figure 14-2: Rendered documentation for `my_crate`, " +"including the comment describing the crate as a whole" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:170 +msgid "" +"Documentation comments within items are useful for describing crates and " +"modules especially. Use them to explain the overall purpose of the container " +"to help your users understand the crate’s organization." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:174 +msgid "Exporting a Convenient Public API with `pub use`" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:176 +msgid "" +"The structure of your public API is a major consideration when publishing a " +"crate. People who use your crate are less familiar with the structure than " +"you are and might have difficulty finding the pieces they want to use if " +"your crate has a large module hierarchy." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:181 +msgid "" +"In Chapter 7, we covered how to make items public using the `pub` keyword, " +"and bring items into a scope with the `use` keyword. However, the structure " +"that makes sense to you while you’re developing a crate might not be very " +"convenient for your users. You might want to organize your structs in a " +"hierarchy containing multiple levels, but then people who want to use a type " +"you’ve defined deep in the hierarchy might have trouble finding out that " +"type exists. They might also be annoyed at having to enter `use` `my_crate::" +"some_module::another_module::UsefulType;` rather than `use` `my_crate::" +"UsefulType;`." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:191 +msgid "" +"The good news is that if the structure _isn’t_ convenient for others to use " +"from another library, you don’t have to rearrange your internal " +"organization: instead, you can re-export items to make a public structure " +"that’s different from your private structure by using `pub use`. Re-" +"exporting takes a public item in one location and makes it public in another " +"location, as if it were defined in the other location instead." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:198 +msgid "" +"For example, say we made a library named `art` for modeling artistic " +"concepts. Within this library are two modules: a `kinds` module containing " +"two enums named `PrimaryColor` and `SecondaryColor` and a `utils` module " +"containing a function named `mix`, as shown in Listing 14-3:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:206 +#: src/ch14-02-publishing-to-crates-io.md:288 +msgid "" +"//! # Art\n" +"//!\n" +"//! A library for modeling artistic concepts.\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:211 +#: src/ch14-02-publishing-to-crates-io.md:298 +msgid "/// The primary colors according to the RYB color model.\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:218 +#: src/ch14-02-publishing-to-crates-io.md:305 +msgid "/// The secondary colors according to the RYB color model.\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:229 +msgid "" +"/// Combines two primary colors in equal amounts to create\n" +" /// a secondary color.\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:240 +msgid "" +"Figure 14-3 shows what the front page of the documentation for this crate " +"generated by `cargo doc` would look like:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:245 +msgid "" +"Figure 14-3: Front page of the documentation for " +"`art` that lists the `kinds` and `utils` modules" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:248 +msgid "" +"Note that the `PrimaryColor` and `SecondaryColor` types aren’t listed on the " +"front page, nor is the `mix` function. We have to click `kinds` and `utils` " +"to see them." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:252 +msgid "" +"Another crate that depends on this library would need `use` statements that " +"bring the items from `art` into scope, specifying the module structure " +"that’s currently defined. Listing 14-4 shows an example of a crate that uses " +"the `PrimaryColor` and `mix` items from the `art` crate:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:272 +msgid "" +"The author of the code in Listing 14-4, which uses the `art` crate, had to " +"figure out that `PrimaryColor` is in the `kinds` module and `mix` is in the " +"`utils` module. The module structure of the `art` crate is more relevant to " +"developers working on the `art` crate than to those using it. The internal " +"structure doesn’t contain any useful information for someone trying to " +"understand how to use the `art` crate, but rather causes confusion because " +"developers who use it have to figure out where to look, and must specify the " +"module names in the `use` statements." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:281 +msgid "" +"To remove the internal organization from the public API, we can modify the " +"`art` crate code in Listing 14-3 to add `pub use` statements to re-export " +"the items at the top level, as shown in Listing 14-5:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:317 +msgid "/// Combines two primary colors in equal amounts to create\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:318 +msgid "/// a secondary color.\n" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:327 +msgid "" +"The API documentation that `cargo doc` generates for this crate will now " +"list and link re-exports on the front page, as shown in Figure 14-4, making " +"the `PrimaryColor` and `SecondaryColor` types and the `mix` function easier " +"to find." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:333 +msgid "" +"Figure 14-4: The front page of the documentation for " +"`art` that lists the re-exports" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:336 +msgid "" +"The `art` crate users can still see and use the internal structure from " +"Listing 14-3 as demonstrated in Listing 14-4, or they can use the more " +"convenient structure in Listing 14-5, as shown in Listing 14-6:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:356 +msgid "" +"In cases where there are many nested modules, re-exporting the types at the " +"top level with `pub use` can make a significant difference in the experience " +"of people who use the crate. Another common use of `pub use` is to re-export " +"definitions of a dependency in the current crate to make that crate's " +"definitions part of your crate’s public API." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:362 +msgid "" +"Creating a useful public API structure is more of an art than a science, and " +"you can iterate to find the API that works best for your users. Choosing " +"`pub use` gives you flexibility in how you structure your crate internally " +"and decouples that internal structure from what you present to your users. " +"Look at some of the code of crates you’ve installed to see if their internal " +"structure differs from their public API." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:369 +msgid "Setting Up a Crates.io Account" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:371 +msgid "" +"Before you can publish any crates, you need to create an account on [crates." +"io](https://crates.io/) and get an API token. To do so, visit " +"the home page at [crates.io](https://crates.io/) and log in " +"via a GitHub account. (The GitHub account is currently a requirement, but " +"the site might support other ways of creating an account in the future.) " +"Once you’re logged in, visit your account settings at [https://crates.io/me/]" +"(https://crates.io/me/) and retrieve your API key. Then run " +"the `cargo login` command and paste your API key when prompted, like this:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:385 +msgid "" +"This command will inform Cargo of your API token and store it locally in _~/." +"cargo/credentials_. Note that this token is a _secret_: do not share it with " +"anyone else. If you do share it with anyone for any reason, you should " +"revoke it and generate a new token on [crates.io](https://crates.io/)." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:391 +msgid "Adding Metadata to a New Crate" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:393 +msgid "" +"Let’s say you have a crate you want to publish. Before publishing, you’ll " +"need to add some metadata in the `[package]` section of the crate’s _Cargo." +"toml_ file." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:397 +msgid "" +"Your crate will need a unique name. While you’re working on a crate locally, " +"you can name a crate whatever you’d like. However, crate names on [crates.io]" +"(https://crates.io/) are allocated on a first-come, first-" +"served basis. Once a crate name is taken, no one else can publish a crate " +"with that name. Before attempting to publish a crate, search for the name " +"you want to use. If the name has been used, you will need to find another " +"name and edit the `name` field in the _Cargo.toml_ file under the " +"`[package]` section to use the new name for publishing, like so:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:408 +msgid "" +"```toml\n" +"[package]\n" +"name = \"guessing_game\"\n" +"```" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:413 +msgid "" +"Even if you’ve chosen a unique name, when you run `cargo publish` to publish " +"the crate at this point, you’ll get a warning and then an error:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:422 +msgid "" +"```console\n" +"$ cargo publish\n" +" Updating crates.io index\n" +"warning: manifest has no description, license, license-file, documentation, " +"homepage or repository.\n" +"See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata " +"for more info.\n" +"--snip--\n" +"error: failed to publish to registry at https://crates.io\n" +"\n" +"Caused by:\n" +" the remote server responded with an error: missing or empty metadata " +"fields: description, license. Please see https://doc.rust-lang.org/cargo/" +"reference/manifest.html for how to upload metadata\n" +"```" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:434 +msgid "" +"This errors because you’re missing some crucial information: a description " +"and license are required so people will know what your crate does and under " +"what terms they can use it. In _Cargo.toml_, add a description that's just a " +"sentence or two, because it will appear with your crate in search results. " +"For the `license` field, you need to give a _license identifier value_. The " +"[Linux Foundation’s Software Package Data Exchange (SPDX)](http://spdx.org/" +"licenses/) lists the identifiers you can use for this value. For example, to " +"specify that you’ve licensed your crate using the MIT License, add the `MIT` " +"identifier:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:445 +msgid "" +"```toml\n" +"[package]\n" +"name = \"guessing_game\"\n" +"license = \"MIT\"\n" +"```" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:451 +msgid "" +"If you want to use a license that doesn’t appear in the SPDX, you need to " +"place the text of that license in a file, include the file in your project, " +"and then use `license-file` to specify the name of that file instead of " +"using the `license` key." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:456 +msgid "" +"Guidance on which license is appropriate for your project is beyond the " +"scope of this book. Many people in the Rust community license their projects " +"in the same way as Rust by using a dual license of `MIT OR Apache-2.0`. This " +"practice demonstrates that you can also specify multiple license identifiers " +"separated by `OR` to have multiple licenses for your project." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:462 +msgid "" +"With a unique name, the version, your description, and a license added, the " +"_Cargo.toml_ file for a project that is ready to publish might look like " +"this:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:467 +msgid "" +"```toml\n" +"[package]\n" +"name = \"guessing_game\"\n" +"version = \"0.1.0\"\n" +"edition = \"2021\"\n" +"description = \"A fun game where you guess what number the computer has " +"chosen.\"\n" +"license = \"MIT OR Apache-2.0\"\n" +"\n" +"[dependencies]\n" +"```" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:478 +msgid "" +"[Cargo’s documentation](https://doc.rust-lang.org/cargo/) describes other " +"metadata you can specify to ensure others can discover and use your crate " +"more easily." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:482 +msgid "Publishing to Crates.io" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:484 +msgid "" +"Now that you’ve created an account, saved your API token, chosen a name for " +"your crate, and specified the required metadata, you’re ready to publish! " +"Publishing a crate uploads a specific version to [crates.io](https://crates." +"io/) for others to use." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:489 +msgid "" +"Be careful, because a publish is _permanent_. The version can never be " +"overwritten, and the code cannot be deleted. One major goal of [crates.io]" +"(https://crates.io/) is to act as a permanent archive of code " +"so that builds of all projects that depend on crates from [crates.io]" +"(https://crates.io/) will continue to work. Allowing version " +"deletions would make fulfilling that goal impossible. However, there is no " +"limit to the number of crate versions you can publish." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:497 +msgid "Run the `cargo publish` command again. It should succeed now:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:505 +msgid "" +"```console\n" +"$ cargo publish\n" +" Updating crates.io index\n" +" Packaging guessing_game v0.1.0 (file:///projects/guessing_game)\n" +" Verifying guessing_game v0.1.0 (file:///projects/guessing_game)\n" +" Compiling guessing_game v0.1.0\n" +"(file:///projects/guessing_game/target/package/guessing_game-0.1.0)\n" +" Finished dev [unoptimized + debuginfo] target(s) in 0.19s\n" +" Uploading guessing_game v0.1.0 (file:///projects/guessing_game)\n" +"```" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:516 +msgid "" +"Congratulations! You’ve now shared your code with the Rust community, and " +"anyone can easily add your crate as a dependency of their project." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:519 +msgid "Publishing a New Version of an Existing Crate" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:521 +msgid "" +"When you’ve made changes to your crate and are ready to release a new " +"version, you change the `version` value specified in your _Cargo.toml_ file " +"and republish. Use the [Semantic Versioning rules](http://semver.org/) to " +"decide what an appropriate next version number is based on the kinds of " +"changes you’ve made. Then run `cargo publish` to upload the new version." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:528 +msgid "" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:530 +msgid "Deprecating Versions from Crates.io with `cargo yank`" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:532 +msgid "" +"Although you can’t remove previous versions of a crate, you can prevent any " +"future projects from adding them as a new dependency. This is useful when a " +"crate version is broken for one reason or another. In such situations, Cargo " +"supports _yanking_ a crate version." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:537 +msgid "" +"Yanking a version prevents new projects from depending on that version while " +"allowing all existing projects that depend on it to continue. Essentially, a " +"yank means that all projects with a _Cargo.lock_ will not break, and any " +"future _Cargo.lock_ files generated will not use the yanked version." +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:542 +msgid "" +"To yank a version of a crate, in the directory of the crate that you’ve " +"previously published, run `cargo yank` and specify which version you want to " +"yank. For example, if we've published a crate named `guessing_game` version " +"1.0.1 and we want to yank it, in the project directory for `guessing_game` " +"we'd run:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:559 +msgid "" +"By adding `--undo` to the command, you can also undo a yank and allow " +"projects to start depending on a version again:" +msgstr "" + +#: src/ch14-02-publishing-to-crates-io.md:568 +msgid "" +"A yank _does not_ delete any code. It cannot, for example, delete " +"accidentally uploaded secrets. If that happens, you must reset those secrets " +"immediately." +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:3 +msgid "" +"In Chapter 12, we built a package that included a binary crate and a library " +"crate. As your project develops, you might find that the library crate " +"continues to get bigger and you want to split your package further into " +"multiple library crates. Cargo offers a feature called _workspaces_ that can " +"help manage multiple related packages that are developed in tandem." +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:9 +msgid "Creating a Workspace" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:11 +msgid "" +"A _workspace_ is a set of packages that share the same _Cargo.lock_ and " +"output directory. Let’s make a project using a workspace—we’ll use trivial " +"code so we can concentrate on the structure of the workspace. There are " +"multiple ways to structure a workspace, so we'll just show one common way. " +"We’ll have a workspace containing a binary and two libraries. The binary, " +"which will provide the main functionality, will depend on the two libraries. " +"One library will provide an `add_one` function, and a second library an " +"`add_two` function. These three crates will be part of the same workspace. " +"We’ll start by creating a new directory for the workspace:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:26 +msgid "" +"Next, in the _add_ directory, we create the _Cargo.toml_ file that will " +"configure the entire workspace. This file won’t have a `[package]` section. " +"Instead, it will start with a `[workspace]` section that will allow us to " +"add members to the workspace by specifying the path to the package with our " +"binary crate; in this case, that path is _adder_:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:34 +msgid "" +"```toml\n" +"[workspace]\n" +"\n" +"members = [\n" +" \"adder\",\n" +"]\n" +"```" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:42 +msgid "" +"Next, we’ll create the `adder` binary crate by running `cargo new` within " +"the _add_ directory:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:57 +msgid "" +"At this point, we can build the workspace by running `cargo build`. The " +"files in your _add_ directory should look like this:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:70 +msgid "" +"The workspace has one _target_ directory at the top level that the compiled " +"artifacts will be placed into; the `adder` package doesn’t have its own " +"_target_ directory. Even if we were to run `cargo build` from inside the " +"_adder_ directory, the compiled artifacts would still end up in _add/target_ " +"rather than _add/adder/target_. Cargo structures the _target_ directory in a " +"workspace like this because the crates in a workspace are meant to depend on " +"each other. If each crate had its own _target_ directory, each crate would " +"have to recompile each of the other crates in the workspace to place the " +"artifacts in its own _target_ directory. By sharing one _target_ directory, " +"the crates can avoid unnecessary rebuilding." +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:81 +msgid "Creating the Second Package in the Workspace" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:83 +msgid "" +"Next, let’s create another member package in the workspace and call it " +"`add_one`. Change the top-level _Cargo.toml_ to specify the _add_one_ path " +"in the `members` list:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:89 +msgid "" +"```toml\n" +"[workspace]\n" +"\n" +"members = [\n" +" \"adder\",\n" +" \"add_one\",\n" +"]\n" +"```" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:98 +msgid "Then generate a new library crate named `add_one`:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:112 +msgid "Your _add_ directory should now have these directories and files:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:128 +msgid "In the _add_one/src/lib.rs_ file, let’s add an `add_one` function:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:130 src/ch14-03-cargo-workspaces.md:302 +msgid "Filename: add_one/src/lib.rs" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:138 +msgid "" +"Now we can have the `adder` package with our binary depend on the `add_one` " +"package that has our library. First, we’ll need to add a path dependency on " +"`add_one` to _adder/Cargo.toml_." +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:142 +msgid "Filename: adder/Cargo.toml" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:144 +msgid "" +"```toml\n" +"[dependencies]\n" +"add_one = { path = \"../add_one\" }\n" +"```" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:149 +msgid "" +"Cargo doesn’t assume that crates in a workspace will depend on each other, " +"so we need to be explicit about the dependency relationships." +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:152 +msgid "" +"Next, let’s use the `add_one` function (from the `add_one` crate) in the " +"`adder` crate. Open the _adder/src/main.rs_ file and add a `use` line at the " +"top to bring the new `add_one` library crate into scope. Then change the " +"`main` function to call the `add_one` function, as in Listing 14-7." +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:164 +msgid "\"Hello, world! {num} plus one is {}!\"" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:170 +msgid "" +"Let’s build the workspace by running `cargo build` in the top-level _add_ " +"directory!" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:179 +msgid "" +"```console\n" +"$ cargo build\n" +" Compiling add_one v0.1.0 (file:///projects/add/add_one)\n" +" Compiling adder v0.1.0 (file:///projects/add/adder)\n" +" Finished dev [unoptimized + debuginfo] target(s) in 0.68s\n" +"```" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:186 +msgid "" +"To run the binary crate from the _add_ directory, we can specify which " +"package in the workspace we want to run by using the `-p` argument and the " +"package name with `cargo run`:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:203 +msgid "" +"This runs the code in _adder/src/main.rs_, which depends on the `add_one` " +"crate." +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:205 +msgid "Depending on an External Package in a Workspace" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:207 +msgid "" +"Notice that the workspace has only one _Cargo.lock_ file at the top level, " +"rather than having a _Cargo.lock_ in each crate’s directory. This ensures " +"that all crates are using the same version of all dependencies. If we add " +"the `rand` package to the _adder/Cargo.toml_ and _add_one/Cargo.toml_ files, " +"Cargo will resolve both of those to one version of `rand` and record that in " +"the one _Cargo.lock_. Making all crates in the workspace use the same " +"dependencies means the crates will always be compatible with each other. " +"Let’s add the `rand` crate to the `[dependencies]` section in the _add_one/" +"Cargo.toml_ file so we can use the `rand` crate in the `add_one` crate:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:223 +msgid "Filename: add_one/Cargo.toml" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:230 +msgid "" +"We can now add `use rand;` to the _add_one/src/lib.rs_ file, and building " +"the whole workspace by running `cargo build` in the _add_ directory will " +"bring in and compile the `rand` crate. We will get one warning because we " +"aren’t referring to the `rand` we brought into scope:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:241 +msgid "" +"```console\n" +"$ cargo build\n" +" Updating crates.io index\n" +" Downloaded rand v0.8.5\n" +" --snip--\n" +" Compiling rand v0.8.5\n" +" Compiling add_one v0.1.0 (file:///projects/add/add_one)\n" +"warning: unused import: `rand`\n" +" --> add_one/src/lib.rs:1:5\n" +" |\n" +"1 | use rand;\n" +" | ^^^^\n" +" |\n" +" = note: `#[warn(unused_imports)]` on by default\n" +"\n" +"warning: `add_one` (lib) generated 1 warning\n" +" Compiling adder v0.1.0 (file:///projects/add/adder)\n" +" Finished dev [unoptimized + debuginfo] target(s) in 10.18s\n" +"```" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:261 +msgid "" +"The top-level _Cargo.lock_ now contains information about the dependency of " +"`add_one` on `rand`. However, even though `rand` is used somewhere in the " +"workspace, we can’t use it in other crates in the workspace unless we add " +"`rand` to their _Cargo.toml_ files as well. For example, if we add `use rand;" +"` to the _adder/src/main.rs_ file for the `adder` package, we’ll get an " +"error:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:273 +msgid "" +"```console\n" +"$ cargo build\n" +" --snip--\n" +" Compiling adder v0.1.0 (file:///projects/add/adder)\n" +"error[E0432]: unresolved import `rand`\n" +" --> adder/src/main.rs:2:5\n" +" |\n" +"2 | use rand;\n" +" | ^^^^ no external crate `rand`\n" +"```" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:284 +msgid "" +"To fix this, edit the _Cargo.toml_ file for the `adder` package and indicate " +"that `rand` is a dependency for it as well. Building the `adder` package " +"will add `rand` to the list of dependencies for `adder` in _Cargo.lock_, but " +"no additional copies of `rand` will be downloaded. Cargo will ensure that " +"every crate in every package in the workspace using the `rand` package will " +"be using the same version as long as they specify compatible versions of " +"`rand`, saving us space and ensuring that the crates in the workspace will " +"be compatible with each other." +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:293 +msgid "" +"If crates in the workspace specify incompatible versions of the same " +"dependency, Cargo will resolve each of them, but will still try to resolve " +"as few versions as possible." +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:297 +msgid "Adding a Test to a Workspace" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:299 +msgid "" +"For another enhancement, let’s add a test of the `add_one::add_one` function " +"within the `add_one` crate:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:320 +msgid "" +"Now run `cargo test` in the top-level _add_ directory. Running `cargo test` " +"in a workspace structured like this one will run the tests for all the " +"crates in the workspace:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:331 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling add_one v0.1.0 (file:///projects/add/add_one)\n" +" Compiling adder v0.1.0 (file:///projects/add/adder)\n" +" Finished test [unoptimized + debuginfo] target(s) in 0.27s\n" +" Running unittests src/lib.rs (target/debug/deps/add_one-" +"f0253159197f7841)\n" +"\n" +"running 1 test\n" +"test tests::it_works ... ok\n" +"\n" +"test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Running unittests src/main.rs (target/debug/deps/" +"adder-49979ff40686fa8e)\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"\n" +" Doc-tests add_one\n" +"\n" +"running 0 tests\n" +"\n" +"test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; " +"finished in 0.00s\n" +"```" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:356 +msgid "" +"The first section of the output shows that the `it_works` test in the " +"`add_one` crate passed. The next section shows that zero tests were found in " +"the `adder` crate, and then the last section shows zero documentation tests " +"were found in the `add_one` crate." +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:361 +msgid "" +"We can also run tests for one particular crate in a workspace from the top-" +"level directory by using the `-p` flag and specifying the name of the crate " +"we want to test:" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:388 +msgid "" +"This output shows `cargo test` only ran the tests for the `add_one` crate " +"and didn’t run the `adder` crate tests." +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:391 +msgid "" +"If you publish the crates in the workspace to [crates.io](https://crates." +"io/), each crate in the workspace will need to be published separately. Like " +"`cargo test`, we can publish a particular crate in our workspace by using " +"the `-p` flag and specifying the name of the crate we want to publish." +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:396 +msgid "" +"For additional practice, add an `add_two` crate to this workspace in a " +"similar way as the `add_one` crate!" +msgstr "" + +#: src/ch14-03-cargo-workspaces.md:399 +msgid "" +"As your project grows, consider using a workspace: it’s easier to understand " +"smaller, individual components than one big blob of code. Furthermore, " +"keeping the crates in a workspace can make coordination between crates " +"easier if they are often changed at the same time." +msgstr "" + +#: src/ch14-04-installing-binaries.md:2 +msgid "" +msgstr "" + +#: src/ch14-04-installing-binaries.md:4 +msgid "Installing Binaries with `cargo install`" +msgstr "" + +#: src/ch14-04-installing-binaries.md:6 +msgid "" +"The `cargo install` command allows you to install and use binary crates " +"locally. This isn’t intended to replace system packages; it’s meant to be a " +"convenient way for Rust developers to install tools that others have shared " +"on [crates.io](https://crates.io/). Note that you can only " +"install packages that have binary targets. A _binary target_ is the runnable " +"program that is created if the crate has a _src/main.rs_ file or another " +"file specified as a binary, as opposed to a library target that isn’t " +"runnable on its own but is suitable for including within other programs. " +"Usually, crates have information in the _README_ file about whether a crate " +"is a library, has a binary target, or both." +msgstr "" + +#: src/ch14-04-installing-binaries.md:17 +msgid "" +"All binaries installed with `cargo install` are stored in the installation " +"root’s _bin_ folder. If you installed Rust using _rustup.rs_ and don’t have " +"any custom configurations, this directory will be _$HOME/.cargo/bin_. Ensure " +"that directory is in your `$PATH` to be able to run programs you’ve " +"installed with `cargo install`." +msgstr "" + +#: src/ch14-04-installing-binaries.md:23 +msgid "" +"For example, in Chapter 12 we mentioned that there’s a Rust implementation " +"of the `grep` tool called `ripgrep` for searching files. To install " +"`ripgrep`, we can run the following:" +msgstr "" + +#: src/ch14-04-installing-binaries.md:44 +msgid "" +"The second-to-last line of the output shows the location and the name of the " +"installed binary, which in the case of `ripgrep` is `rg`. As long as the " +"installation directory is in your `$PATH`, as mentioned previously, you can " +"then run `rg --help` and start using a faster, rustier tool for searching " +"files!" +msgstr "" + +#: src/ch14-05-extending-cargo.md:3 +msgid "" +"Cargo is designed so you can extend it with new subcommands without having " +"to modify Cargo. If a binary in your `$PATH` is named `cargo-something`, you " +"can run it as if it was a Cargo subcommand by running `cargo something`. " +"Custom commands like this are also listed when you run `cargo --list`. Being " +"able to use `cargo install` to install extensions and then run them just " +"like the built-in Cargo tools is a super convenient benefit of Cargo’s " +"design!" +msgstr "" + +#: src/ch14-05-extending-cargo.md:12 +msgid "" +"Sharing code with Cargo and [crates.io](https://crates.io/) " +"is part of what makes the Rust ecosystem useful for many different tasks. " +"Rust’s standard library is small and stable, but crates are easy to share, " +"use, and improve on a timeline different from that of the language. Don’t be " +"shy about sharing code that’s useful to you on [crates.io](https://crates." +"io/); it’s likely that it will be useful to someone else as well!" +msgstr "" + +#: src/ch15-00-smart-pointers.md:3 +msgid "" +"A _pointer_ is a general concept for a variable that contains an address in " +"memory. This address refers to, or “points at,” some other data. The most " +"common kind of pointer in Rust is a reference, which you learned about in " +"Chapter 4. References are indicated by the `&` symbol and borrow the value " +"they point to. They don’t have any special capabilities other than referring " +"to data, and have no overhead." +msgstr "" + +#: src/ch15-00-smart-pointers.md:10 +msgid "" +"_Smart pointers_, on the other hand, are data structures that act like a " +"pointer but also have additional metadata and capabilities. The concept of " +"smart pointers isn’t unique to Rust: smart pointers originated in C++ and " +"exist in other languages as well. Rust has a variety of smart pointers " +"defined in the standard library that provide functionality beyond that " +"provided by references. To explore the general concept, we’ll look at a " +"couple of different examples of smart pointers, including a _reference " +"counting_ smart pointer type. This pointer enables you to allow data to have " +"multiple owners by keeping track of the number of owners and, when no owners " +"remain, cleaning up the data." +msgstr "" + +#: src/ch15-00-smart-pointers.md:20 +msgid "" +"Rust, with its concept of ownership and borrowing, has an additional " +"difference between references and smart pointers: while references only " +"borrow data, in many cases, smart pointers _own_ the data they point to." +msgstr "" + +#: src/ch15-00-smart-pointers.md:24 +msgid "" +"Though we didn’t call them as such at the time, we’ve already encountered a " +"few smart pointers in this book, including `String` and `Vec` in Chapter " +"8. Both these types count as smart pointers because they own some memory and " +"allow you to manipulate it. They also have metadata and extra capabilities " +"or guarantees. `String`, for example, stores its capacity as metadata and " +"has the extra ability to ensure its data will always be valid UTF-8." +msgstr "" + +#: src/ch15-00-smart-pointers.md:31 +msgid "" +"Smart pointers are usually implemented using structs. Unlike an ordinary " +"struct, smart pointers implement the `Deref` and `Drop` traits. The `Deref` " +"trait allows an instance of the smart pointer struct to behave like a " +"reference so you can write your code to work with either references or smart " +"pointers. The `Drop` trait allows you to customize the code that’s run when " +"an instance of the smart pointer goes out of scope. In this chapter, we’ll " +"discuss both traits and demonstrate why they’re important to smart pointers." +msgstr "" + +#: src/ch15-00-smart-pointers.md:39 +msgid "" +"Given that the smart pointer pattern is a general design pattern used " +"frequently in Rust, this chapter won’t cover every existing smart pointer. " +"Many libraries have their own smart pointers, and you can even write your " +"own. We’ll cover the most common smart pointers in the standard library:" +msgstr "" + +#: src/ch15-00-smart-pointers.md:44 +msgid "`Box` for allocating values on the heap" +msgstr "" + +#: src/ch15-00-smart-pointers.md:45 +msgid "`Rc`, a reference counting type that enables multiple ownership" +msgstr "" + +#: src/ch15-00-smart-pointers.md:46 +msgid "" +"`Ref` and `RefMut`, accessed through `RefCell`, a type that " +"enforces the borrowing rules at runtime instead of compile time" +msgstr "" + +#: src/ch15-00-smart-pointers.md:49 +msgid "" +"In addition, we’ll cover the _interior mutability_ pattern where an " +"immutable type exposes an API for mutating an interior value. We’ll also " +"discuss _reference cycles_: how they can leak memory and how to prevent them." +msgstr "" + +#: src/ch15-00-smart-pointers.md:53 +msgid "Let’s dive in!" +msgstr "" + +#: src/ch15-01-box.md:3 +msgid "" +"The most straightforward smart pointer is a _box_, whose type is written " +"`Box`. Boxes allow you to store data on the heap rather than the stack. " +"What remains on the stack is the pointer to the heap data. Refer to Chapter " +"4 to review the difference between the stack and the heap." +msgstr "" + +#: src/ch15-01-box.md:8 +msgid "" +"Boxes don’t have performance overhead, other than storing their data on the " +"heap instead of on the stack. But they don’t have many extra capabilities " +"either. You’ll use them most often in these situations:" +msgstr "" + +#: src/ch15-01-box.md:12 +msgid "" +"When you have a type whose size can’t be known at compile time and you want " +"to use a value of that type in a context that requires an exact size" +msgstr "" + +#: src/ch15-01-box.md:14 +msgid "" +"When you have a large amount of data and you want to transfer ownership but " +"ensure the data won’t be copied when you do so" +msgstr "" + +#: src/ch15-01-box.md:16 +msgid "" +"When you want to own a value and you care only that it’s a type that " +"implements a particular trait rather than being of a specific type" +msgstr "" + +#: src/ch15-01-box.md:19 +msgid "" +"We’ll demonstrate the first situation in the [“Enabling Recursive Types with " +"Boxes”](#enabling-recursive-types-with-boxes) section. In the " +"second case, transferring ownership of a large amount of data can take a " +"long time because the data is copied around on the stack. To improve " +"performance in this situation, we can store the large amount of data on the " +"heap in a box. Then, only the small amount of pointer data is copied around " +"on the stack, while the data it references stays in one place on the heap. " +"The third case is known as a _trait object_, and Chapter 17 devotes an " +"entire section, [“Using Trait Objects That Allow for Values of Different " +"Types,”](ch17-02-trait-objects.html#using-trait-objects-that-allow-for-" +"values-of-different-types) just to that topic. So what you learn here you’ll apply again in " +"Chapter 17!" +msgstr "" + +#: src/ch15-01-box.md:31 +msgid "Using a `Box` to Store Data on the Heap" +msgstr "" + +#: src/ch15-01-box.md:33 +msgid "" +"Before we discuss the heap storage use case for `Box`, we’ll cover the " +"syntax and how to interact with values stored within a `Box`." +msgstr "" + +#: src/ch15-01-box.md:36 +msgid "" +"Listing 15-1 shows how to use a box to store an `i32` value on the heap:" +msgstr "" + +#: src/ch15-01-box.md:43 +msgid "\"b = {b}\"" +msgstr "" + +#: src/ch15-01-box.md:47 +msgid "" +"Listing 15-1: Storing an `i32` value on the heap " +"using a box" +msgstr "" + +#: src/ch15-01-box.md:50 +msgid "" +"We define the variable `b` to have the value of a `Box` that points to the " +"value `5`, which is allocated on the heap. This program will print `b = 5`; " +"in this case, we can access the data in the box similar to how we would if " +"this data were on the stack. Just like any owned value, when a box goes out " +"of scope, as `b` does at the end of `main`, it will be deallocated. The " +"deallocation happens both for the box (stored on the stack) and the data it " +"points to (stored on the heap)." +msgstr "" + +#: src/ch15-01-box.md:58 +msgid "" +"Putting a single value on the heap isn’t very useful, so you won’t use boxes " +"by themselves in this way very often. Having values like a single `i32` on " +"the stack, where they’re stored by default, is more appropriate in the " +"majority of situations. Let’s look at a case where boxes allow us to define " +"types that we wouldn’t be allowed to if we didn’t have boxes." +msgstr "" + +#: src/ch15-01-box.md:64 +msgid "Enabling Recursive Types with Boxes" +msgstr "" + +#: src/ch15-01-box.md:66 +msgid "" +"A value of _recursive type_ can have another value of the same type as part " +"of itself. Recursive types pose an issue because at compile time Rust needs " +"to know how much space a type takes up. However, the nesting of values of " +"recursive types could theoretically continue infinitely, so Rust can’t know " +"how much space the value needs. Because boxes have a known size, we can " +"enable recursive types by inserting a box in the recursive type definition." +msgstr "" + +#: src/ch15-01-box.md:73 +msgid "" +"As an example of a recursive type, let’s explore the _cons list_. This is a " +"data type commonly found in functional programming languages. The cons list " +"type we’ll define is straightforward except for the recursion; therefore, " +"the concepts in the example we’ll work with will be useful any time you get " +"into more complex situations involving recursive types." +msgstr "" + +#: src/ch15-01-box.md:79 +msgid "More Information About the Cons List" +msgstr "" + +#: src/ch15-01-box.md:81 +msgid "" +"A _cons list_ is a data structure that comes from the Lisp programming " +"language and its dialects and is made up of nested pairs, and is the Lisp " +"version of a linked list. Its name comes from the `cons` function (short for " +"“construct function”) in Lisp that constructs a new pair from its two " +"arguments. By calling `cons` on a pair consisting of a value and another " +"pair, we can construct cons lists made up of recursive pairs." +msgstr "" + +#: src/ch15-01-box.md:88 +msgid "" +"For example, here’s a pseudocode representation of a cons list containing " +"the list 1, 2, 3 with each pair in parentheses:" +msgstr "" + +#: src/ch15-01-box.md:95 +msgid "" +"Each item in a cons list contains two elements: the value of the current " +"item and the next item. The last item in the list contains only a value " +"called `Nil` without a next item. A cons list is produced by recursively " +"calling the `cons` function. The canonical name to denote the base case of " +"the recursion is `Nil`. Note that this is not the same as the “null” or " +"“nil” concept in Chapter 6, which is an invalid or absent value." +msgstr "" + +#: src/ch15-01-box.md:102 +msgid "" +"The cons list isn’t a commonly used data structure in Rust. Most of the time " +"when you have a list of items in Rust, `Vec` is a better choice to use. " +"Other, more complex recursive data types _are_ useful in various situations, " +"but by starting with the cons list in this chapter, we can explore how boxes " +"let us define a recursive data type without much distraction." +msgstr "" + +#: src/ch15-01-box.md:108 +msgid "" +"Listing 15-2 contains an enum definition for a cons list. Note that this " +"code won’t compile yet because the `List` type doesn’t have a known size, " +"which we’ll demonstrate." +msgstr "" + +#: src/ch15-01-box.md:123 +msgid "" +"Listing 15-2: The first attempt at defining an enum " +"to represent a cons list data structure of `i32` values" +msgstr "" + +#: src/ch15-01-box.md:126 +msgid "" +"Note: We’re implementing a cons list that holds only `i32` values for the " +"purposes of this example. We could have implemented it using generics, as we " +"discussed in Chapter 10, to define a cons list type that could store values " +"of any type." +msgstr "" + +#: src/ch15-01-box.md:131 +msgid "" +"Using the `List` type to store the list `1, 2, 3` would look like the code " +"in Listing 15-3:" +msgstr "" + +#: src/ch15-01-box.md:149 +msgid "" +"Listing 15-3: Using the `List` enum to store the " +"list `1, 2, 3`" +msgstr "" + +#: src/ch15-01-box.md:152 +msgid "" +"The first `Cons` value holds `1` and another `List` value. This `List` value " +"is another `Cons` value that holds `2` and another `List` value. This `List` " +"value is one more `Cons` value that holds `3` and a `List` value, which is " +"finally `Nil`, the non-recursive variant that signals the end of the list." +msgstr "" + +#: src/ch15-01-box.md:157 +msgid "" +"If we try to compile the code in Listing 15-3, we get the error shown in " +"Listing 15-4:" +msgstr "" + +#: src/ch15-01-box.md:160 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling cons-list v0.1.0 (file:///projects/cons-list)\n" +"error[E0072]: recursive type `List` has infinite size\n" +" --> src/main.rs:1:1\n" +" |\n" +"1 | enum List {\n" +" | ^^^^^^^^^\n" +"2 | Cons(i32, List),\n" +" | ---- recursive without indirection\n" +" |\n" +"help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the " +"cycle\n" +" |\n" +"2 | Cons(i32, Box),\n" +" | ++++ +\n" +"\n" +"error[E0391]: cycle detected when computing when `List` needs drop\n" +" --> src/main.rs:1:1\n" +" |\n" +"1 | enum List {\n" +" | ^^^^^^^^^\n" +" |\n" +" = note: ...which immediately requires computing when `List` needs drop " +"again\n" +" = note: cycle used when computing whether `List` needs drop\n" +" = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries " +"and https://rustc-dev-guide.rust-lang.org/query.html for more information\n" +"\n" +"Some errors have detailed explanations: E0072, E0391.\n" +"For more information about an error, try `rustc --explain E0072`.\n" +"error: could not compile `cons-list` (bin \"cons-list\") due to 2 previous " +"errors\n" +"```" +msgstr "" + +#: src/ch15-01-box.md:191 +msgid "" +"Listing 15-4: The error we get when attempting to " +"define a recursive enum" +msgstr "" + +#: src/ch15-01-box.md:194 +msgid "" +"The error shows this type “has infinite size.” The reason is that we’ve " +"defined `List` with a variant that is recursive: it holds another value of " +"itself directly. As a result, Rust can’t figure out how much space it needs " +"to store a `List` value. Let’s break down why we get this error. First, " +"we’ll look at how Rust decides how much space it needs to store a value of a " +"non-recursive type." +msgstr "" + +#: src/ch15-01-box.md:200 +msgid "Computing the Size of a Non-Recursive Type" +msgstr "" + +#: src/ch15-01-box.md:202 +msgid "" +"Recall the `Message` enum we defined in Listing 6-2 when we discussed enum " +"definitions in Chapter 6:" +msgstr "" + +#: src/ch15-01-box.md:216 +msgid "" +"To determine how much space to allocate for a `Message` value, Rust goes " +"through each of the variants to see which variant needs the most space. Rust " +"sees that `Message::Quit` doesn’t need any space, `Message::Move` needs " +"enough space to store two `i32` values, and so forth. Because only one " +"variant will be used, the most space a `Message` value will need is the " +"space it would take to store the largest of its variants." +msgstr "" + +#: src/ch15-01-box.md:223 +msgid "" +"Contrast this with what happens when Rust tries to determine how much space " +"a recursive type like the `List` enum in Listing 15-2 needs. The compiler " +"starts by looking at the `Cons` variant, which holds a value of type `i32` " +"and a value of type `List`. Therefore, `Cons` needs an amount of space equal " +"to the size of an `i32` plus the size of a `List`. To figure out how much " +"memory the `List` type needs, the compiler looks at the variants, starting " +"with the `Cons` variant. The `Cons` variant holds a value of type `i32` and " +"a value of type `List`, and this process continues infinitely, as shown in " +"Figure 15-1." +msgstr "" + +#: src/ch15-01-box.md:234 +msgid "" +"Figure 15-1: An infinite `List` consisting of " +"infinite `Cons` variants" +msgstr "" + +#: src/ch15-01-box.md:237 +msgid "Using `Box` to Get a Recursive Type with a Known Size" +msgstr "" + +#: src/ch15-01-box.md:239 +msgid "" +"Because Rust can’t figure out how much space to allocate for recursively " +"defined types, the compiler gives an error with this helpful suggestion:" +msgstr "" + +#: src/ch15-01-box.md:253 +msgid "" +"In this suggestion, “indirection” means that instead of storing a value " +"directly, we should change the data structure to store the value indirectly " +"by storing a pointer to the value instead." +msgstr "" + +#: src/ch15-01-box.md:257 +msgid "" +"Because a `Box` is a pointer, Rust always knows how much space a `Box` " +"needs: a pointer’s size doesn’t change based on the amount of data it’s " +"pointing to. This means we can put a `Box` inside the `Cons` variant " +"instead of another `List` value directly. The `Box` will point to the " +"next `List` value that will be on the heap rather than inside the `Cons` " +"variant. Conceptually, we still have a list, created with lists holding " +"other lists, but this implementation is now more like placing the items next " +"to one another rather than inside one another." +msgstr "" + +#: src/ch15-01-box.md:266 +msgid "" +"We can change the definition of the `List` enum in Listing 15-2 and the " +"usage of the `List` in Listing 15-3 to the code in Listing 15-5, which will " +"compile:" +msgstr "" + +#: src/ch15-01-box.md:284 +msgid "" +"Listing 15-5: Definition of `List` that uses " +"`Box` in order to have a known size" +msgstr "" + +#: src/ch15-01-box.md:287 +msgid "" +"The `Cons` variant needs the size of an `i32` plus the space to store the " +"box’s pointer data. The `Nil` variant stores no values, so it needs less " +"space than the `Cons` variant. We now know that any `List` value will take " +"up the size of an `i32` plus the size of a box’s pointer data. By using a " +"box, we’ve broken the infinite, recursive chain, so the compiler can figure " +"out the size it needs to store a `List` value. Figure 15-2 shows what the " +"`Cons` variant looks like now." +msgstr "" + +#: src/ch15-01-box.md:297 +msgid "" +"Figure 15-2: A `List` that is not infinitely sized " +"because `Cons` holds a `Box`" +msgstr "" + +#: src/ch15-01-box.md:300 +msgid "" +"Boxes provide only the indirection and heap allocation; they don’t have any " +"other special capabilities, like those we’ll see with the other smart " +"pointer types. They also don’t have the performance overhead that these " +"special capabilities incur, so they can be useful in cases like the cons " +"list where the indirection is the only feature we need. We’ll look at more " +"use cases for boxes in Chapter 17, too." +msgstr "" + +#: src/ch15-01-box.md:307 +msgid "" +"The `Box` type is a smart pointer because it implements the `Deref` " +"trait, which allows `Box` values to be treated like references. When a " +"`Box` value goes out of scope, the heap data that the box is pointing to " +"is cleaned up as well because of the `Drop` trait implementation. These two " +"traits will be even more important to the functionality provided by the " +"other smart pointer types we’ll discuss in the rest of this chapter. Let’s " +"explore these two traits in more detail." +msgstr "" + +#: src/ch15-02-deref.md:3 +msgid "" +"Implementing the `Deref` trait allows you to customize the behavior of the " +"_dereference operator_ `*` (not to be confused with the multiplication or " +"glob operator). By implementing `Deref` in such a way that a smart pointer " +"can be treated like a regular reference, you can write code that operates on " +"references and use that code with smart pointers too." +msgstr "" + +#: src/ch15-02-deref.md:9 +msgid "" +"Let’s first look at how the dereference operator works with regular " +"references. Then we’ll try to define a custom type that behaves like " +"`Box`, and see why the dereference operator doesn’t work like a reference " +"on our newly defined type. We’ll explore how implementing the `Deref` trait " +"makes it possible for smart pointers to work in ways similar to references. " +"Then we’ll look at Rust’s _deref coercion_ feature and how it lets us work " +"with either references or smart pointers." +msgstr "" + +#: src/ch15-02-deref.md:17 +msgid "" +"Note: There’s one big difference between the `MyBox` type we’re about to " +"build and the real `Box`: our version will not store its data on the " +"heap. We are focusing this example on `Deref`, so where the data is actually " +"stored is less important than the pointer-like behavior." +msgstr "" + +#: src/ch15-02-deref.md:23 +msgid "" +"" +msgstr "" + +#: src/ch15-02-deref.md:25 +msgid "Following the Pointer to the Value" +msgstr "" + +#: src/ch15-02-deref.md:27 +msgid "" +"A regular reference is a type of pointer, and one way to think of a pointer " +"is as an arrow to a value stored somewhere else. In Listing 15-6, we create " +"a reference to an `i32` value and then use the dereference operator to " +"follow the reference to the value:" +msgstr "" + +#: src/ch15-02-deref.md:44 +msgid "" +"Listing 15-6: Using the dereference operator to " +"follow a reference to an `i32` value" +msgstr "" + +#: src/ch15-02-deref.md:47 +msgid "" +"The variable `x` holds an `i32` value `5`. We set `y` equal to a reference " +"to `x`. We can assert that `x` is equal to `5`. However, if we want to make " +"an assertion about the value in `y`, we have to use `*y` to follow the " +"reference to the value it’s pointing to (hence _dereference_) so the " +"compiler can compare the actual value. Once we dereference `y`, we have " +"access to the integer value `y` is pointing to that we can compare with `5`." +msgstr "" + +#: src/ch15-02-deref.md:54 +msgid "" +"If we tried to write `assert_eq!(5, y);` instead, we would get this " +"compilation error:" +msgstr "" + +#: src/ch15-02-deref.md:57 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling deref-example v0.1.0 (file:///projects/deref-example)\n" +"error[E0277]: can't compare `{integer}` with `&{integer}`\n" +" --> src/main.rs:6:5\n" +" |\n" +"6 | assert_eq!(5, y);\n" +" | ^^^^^^^^^^^^^^^^ no implementation for `{integer} == &{integer}`\n" +" |\n" +" = help: the trait `PartialEq<&{integer}>` is not implemented for `{integer}" +"`\n" +" = note: this error originates in the macro `assert_eq` (in Nightly builds, " +"run with -Z macro-backtrace for more info)\n" +"\n" +"For more information about this error, try `rustc --explain E0277`.\n" +"error: could not compile `deref-example` (bin \"deref-example\") due to 1 " +"previous error\n" +"```" +msgstr "" + +#: src/ch15-02-deref.md:73 +msgid "" +"Comparing a number and a reference to a number isn’t allowed because they’re " +"different types. We must use the dereference operator to follow the " +"reference to the value it’s pointing to." +msgstr "" + +#: src/ch15-02-deref.md:77 +msgid "Using `Box` Like a Reference" +msgstr "" + +#: src/ch15-02-deref.md:79 +msgid "" +"We can rewrite the code in Listing 15-6 to use a `Box` instead of a " +"reference; the dereference operator used on the `Box` in Listing 15-7 " +"functions in the same way as the dereference operator used on the reference " +"in Listing 15-6:" +msgstr "" + +#: src/ch15-02-deref.md:96 +msgid "" +"Listing 15-7: Using the dereference operator on a " +"`Box`" +msgstr "" + +#: src/ch15-02-deref.md:99 +msgid "" +"The main difference between Listing 15-7 and Listing 15-6 is that here we " +"set `y` to be an instance of a `Box` pointing to a copied value of `x` " +"rather than a reference pointing to the value of `x`. In the last assertion, " +"we can use the dereference operator to follow the pointer of the `Box` in " +"the same way that we did when `y` was a reference. Next, we’ll explore what " +"is special about `Box` that enables us to use the dereference operator by " +"defining our own type." +msgstr "" + +#: src/ch15-02-deref.md:107 +msgid "Defining Our Own Smart Pointer" +msgstr "" + +#: src/ch15-02-deref.md:109 +msgid "" +"Let’s build a smart pointer similar to the `Box` type provided by the " +"standard library to experience how smart pointers behave differently from " +"references by default. Then we’ll look at how to add the ability to use the " +"dereference operator." +msgstr "" + +#: src/ch15-02-deref.md:114 +msgid "" +"The `Box` type is ultimately defined as a tuple struct with one element, " +"so Listing 15-8 defines a `MyBox` type in the same way. We’ll also define " +"a `new` function to match the `new` function defined on `Box`." +msgstr "" + +#: src/ch15-02-deref.md:132 +msgid "Listing 15-8: Defining a `MyBox` type" +msgstr "" + +#: src/ch15-02-deref.md:134 +msgid "" +"We define a struct named `MyBox` and declare a generic parameter `T`, " +"because we want our type to hold values of any type. The `MyBox` type is a " +"tuple struct with one element of type `T`. The `MyBox::new` function takes " +"one parameter of type `T` and returns a `MyBox` instance that holds the " +"value passed in." +msgstr "" + +#: src/ch15-02-deref.md:139 +msgid "" +"Let’s try adding the `main` function in Listing 15-7 to Listing 15-8 and " +"changing it to use the `MyBox` type we’ve defined instead of `Box`. " +"The code in Listing 15-9 won’t compile because Rust doesn’t know how to " +"dereference `MyBox`." +msgstr "" + +#: src/ch15-02-deref.md:164 +msgid "" +"Listing 15-9: Attempting to use `MyBox` in the " +"same way we used references and `Box`" +msgstr "" + +#: src/ch15-02-deref.md:167 +msgid "Here’s the resulting compilation error:" +msgstr "" + +#: src/ch15-02-deref.md:169 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling deref-example v0.1.0 (file:///projects/deref-example)\n" +"error[E0614]: type `MyBox<{integer}>` cannot be dereferenced\n" +" --> src/main.rs:14:19\n" +" |\n" +"14 | assert_eq!(5, *y);\n" +" | ^^\n" +"\n" +"For more information about this error, try `rustc --explain E0614`.\n" +"error: could not compile `deref-example` (bin \"deref-example\") due to 1 " +"previous error\n" +"```" +msgstr "" + +#: src/ch15-02-deref.md:182 +msgid "" +"Our `MyBox` type can’t be dereferenced because we haven’t implemented " +"that ability on our type. To enable dereferencing with the `*` operator, we " +"implement the `Deref` trait." +msgstr "" + +#: src/ch15-02-deref.md:186 +msgid "Treating a Type Like a Reference by Implementing the `Deref` Trait" +msgstr "" + +#: src/ch15-02-deref.md:188 +msgid "" +"As discussed in the [“Implementing a Trait on a Type”](ch10-02-traits." +"html#implementing-a-trait-on-a-type) section of Chapter 10, to implement a trait, we need to provide " +"implementations for the trait’s required methods. The `Deref` trait, " +"provided by the standard library, requires us to implement one method named " +"`deref` that borrows `self` and returns a reference to the inner data. " +"Listing 15-10 contains an implementation of `Deref` to add to the definition " +"of `MyBox`:" +msgstr "" + +#: src/ch15-02-deref.md:225 +msgid "" +"Listing 15-10: Implementing `Deref` on `MyBox`" +msgstr "" + +#: src/ch15-02-deref.md:227 +msgid "" +"The `type Target = T;` syntax defines an associated type for the `Deref` " +"trait to use. Associated types are a slightly different way of declaring a " +"generic parameter, but you don’t need to worry about them for now; we’ll " +"cover them in more detail in Chapter 19." +msgstr "" + +#: src/ch15-02-deref.md:232 +msgid "" +"We fill in the body of the `deref` method with `&self.0` so `deref` returns " +"a reference to the value we want to access with the `*` operator; recall " +"from the [“Using Tuple Structs without Named Fields to Create Different " +"Types”](ch05-01-defining-structs.html#using-tuple-structs-without-named-" +"fields-to-create-different-types) section of Chapter 5 that " +"`.0` accesses the first value in a tuple struct. The `main` function in " +"Listing 15-9 that calls `*` on the `MyBox` value now compiles, and the " +"assertions pass!" +msgstr "" + +#: src/ch15-02-deref.md:239 +msgid "" +"Without the `Deref` trait, the compiler can only dereference `&` references. " +"The `deref` method gives the compiler the ability to take a value of any " +"type that implements `Deref` and call the `deref` method to get a `&` " +"reference that it knows how to dereference." +msgstr "" + +#: src/ch15-02-deref.md:244 +msgid "" +"When we entered `*y` in Listing 15-9, behind the scenes Rust actually ran " +"this code:" +msgstr "" + +#: src/ch15-02-deref.md:251 +msgid "" +"Rust substitutes the `*` operator with a call to the `deref` method and then " +"a plain dereference so we don’t have to think about whether or not we need " +"to call the `deref` method. This Rust feature lets us write code that " +"functions identically whether we have a regular reference or a type that " +"implements `Deref`." +msgstr "" + +#: src/ch15-02-deref.md:257 +msgid "" +"The reason the `deref` method returns a reference to a value, and that the " +"plain dereference outside the parentheses in `*(y.deref())` is still " +"necessary, is to do with the ownership system. If the `deref` method " +"returned the value directly instead of a reference to the value, the value " +"would be moved out of `self`. We don’t want to take ownership of the inner " +"value inside `MyBox` in this case or in most cases where we use the " +"dereference operator." +msgstr "" + +#: src/ch15-02-deref.md:264 +msgid "" +"Note that the `*` operator is replaced with a call to the `deref` method and " +"then a call to the `*` operator just once, each time we use a `*` in our " +"code. Because the substitution of the `*` operator does not recurse " +"infinitely, we end up with data of type `i32`, which matches the `5` in " +"`assert_eq!` in Listing 15-9." +msgstr "" + +#: src/ch15-02-deref.md:270 +msgid "Implicit Deref Coercions with Functions and Methods" +msgstr "" + +#: src/ch15-02-deref.md:272 +msgid "" +"_Deref coercion_ converts a reference to a type that implements the `Deref` " +"trait into a reference to another type. For example, deref coercion can " +"convert `&String` to `&str` because `String` implements the `Deref` trait " +"such that it returns `&str`. Deref coercion is a convenience Rust performs " +"on arguments to functions and methods, and works only on types that " +"implement the `Deref` trait. It happens automatically when we pass a " +"reference to a particular type’s value as an argument to a function or " +"method that doesn’t match the parameter type in the function or method " +"definition. A sequence of calls to the `deref` method converts the type we " +"provided into the type the parameter needs." +msgstr "" + +#: src/ch15-02-deref.md:282 +msgid "" +"Deref coercion was added to Rust so that programmers writing function and " +"method calls don’t need to add as many explicit references and dereferences " +"with `&` and `*`. The deref coercion feature also lets us write more code " +"that can work for either references or smart pointers." +msgstr "" + +#: src/ch15-02-deref.md:287 +msgid "" +"To see deref coercion in action, let’s use the `MyBox` type we defined in " +"Listing 15-8 as well as the implementation of `Deref` that we added in " +"Listing 15-10. Listing 15-11 shows the definition of a function that has a " +"string slice parameter:" +msgstr "" + +#: src/ch15-02-deref.md:296 src/ch15-02-deref.md:331 src/ch15-02-deref.md:377 +msgid "\"Hello, {name}!\"" +msgstr "" + +#: src/ch15-02-deref.md:302 +msgid "" +"Listing 15-11: A `hello` function that has the " +"parameter `name` of type `&str`" +msgstr "" + +#: src/ch15-02-deref.md:305 +msgid "" +"We can call the `hello` function with a string slice as an argument, such as " +"`hello(\"Rust\");` for example. Deref coercion makes it possible to call " +"`hello` with a reference to a value of type `MyBox`, as shown in " +"Listing 15-12:" +msgstr "" + +#: src/ch15-02-deref.md:335 src/ch15-02-deref.md:381 +msgid "\"Rust\"" +msgstr "" + +#: src/ch15-02-deref.md:340 +msgid "" +"Listing 15-12: Calling `hello` with a reference to a " +"`MyBox` value, which works because of deref coercion" +msgstr "" + +#: src/ch15-02-deref.md:343 +msgid "" +"Here we’re calling the `hello` function with the argument `&m`, which is a " +"reference to a `MyBox` value. Because we implemented the `Deref` " +"trait on `MyBox` in Listing 15-10, Rust can turn `&MyBox` into " +"`&String` by calling `deref`. The standard library provides an " +"implementation of `Deref` on `String` that returns a string slice, and this " +"is in the API documentation for `Deref`. Rust calls `deref` again to turn " +"the `&String` into `&str`, which matches the `hello` function’s definition." +msgstr "" + +#: src/ch15-02-deref.md:351 +msgid "" +"If Rust didn’t implement deref coercion, we would have to write the code in " +"Listing 15-13 instead of the code in Listing 15-12 to call `hello` with a " +"value of type `&MyBox`." +msgstr "" + +#: src/ch15-02-deref.md:386 +msgid "" +"Listing 15-13: The code we would have to write if " +"Rust didn’t have deref coercion" +msgstr "" + +#: src/ch15-02-deref.md:389 +msgid "" +"The `(*m)` dereferences the `MyBox` into a `String`. Then the `&` " +"and `[..]` take a string slice of the `String` that is equal to the whole " +"string to match the signature of `hello`. This code without deref coercions " +"is harder to read, write, and understand with all of these symbols involved. " +"Deref coercion allows Rust to handle these conversions for us automatically." +msgstr "" + +#: src/ch15-02-deref.md:395 +msgid "" +"When the `Deref` trait is defined for the types involved, Rust will analyze " +"the types and use `Deref::deref` as many times as necessary to get a " +"reference to match the parameter’s type. The number of times that `Deref::" +"deref` needs to be inserted is resolved at compile time, so there is no " +"runtime penalty for taking advantage of deref coercion!" +msgstr "" + +#: src/ch15-02-deref.md:401 +msgid "How Deref Coercion Interacts with Mutability" +msgstr "" + +#: src/ch15-02-deref.md:403 +msgid "" +"Similar to how you use the `Deref` trait to override the `*` operator on " +"immutable references, you can use the `DerefMut` trait to override the `*` " +"operator on mutable references." +msgstr "" + +#: src/ch15-02-deref.md:407 +msgid "" +"Rust does deref coercion when it finds types and trait implementations in " +"three cases:" +msgstr "" + +#: src/ch15-02-deref.md:410 +msgid "From `&T` to `&U` when `T: Deref`" +msgstr "" + +#: src/ch15-02-deref.md:411 +msgid "From `&mut T` to `&mut U` when `T: DerefMut`" +msgstr "" + +#: src/ch15-02-deref.md:412 +msgid "From `&mut T` to `&U` when `T: Deref`" +msgstr "" + +#: src/ch15-02-deref.md:414 +msgid "" +"The first two cases are the same as each other except that the second " +"implements mutability. The first case states that if you have a `&T`, and " +"`T` implements `Deref` to some type `U`, you can get a `&U` transparently. " +"The second case states that the same deref coercion happens for mutable " +"references." +msgstr "" + +#: src/ch15-02-deref.md:419 +msgid "" +"The third case is trickier: Rust will also coerce a mutable reference to an " +"immutable one. But the reverse is _not_ possible: immutable references will " +"never coerce to mutable references. Because of the borrowing rules, if you " +"have a mutable reference, that mutable reference must be the only reference " +"to that data (otherwise, the program wouldn’t compile). Converting one " +"mutable reference to one immutable reference will never break the borrowing " +"rules. Converting an immutable reference to a mutable reference would " +"require that the initial immutable reference is the only immutable reference " +"to that data, but the borrowing rules don’t guarantee that. Therefore, Rust " +"can’t make the assumption that converting an immutable reference to a " +"mutable reference is possible." +msgstr "" + +#: src/ch15-03-drop.md:3 +msgid "" +"The second trait important to the smart pointer pattern is `Drop`, which " +"lets you customize what happens when a value is about to go out of scope. " +"You can provide an implementation for the `Drop` trait on any type, and that " +"code can be used to release resources like files or network connections." +msgstr "" + +#: src/ch15-03-drop.md:8 +msgid "" +"We’re introducing `Drop` in the context of smart pointers because the " +"functionality of the `Drop` trait is almost always used when implementing a " +"smart pointer. For example, when a `Box` is dropped it will deallocate " +"the space on the heap that the box points to." +msgstr "" + +#: src/ch15-03-drop.md:13 +msgid "" +"In some languages, for some types, the programmer must call code to free " +"memory or resources every time they finish using an instance of those types. " +"Examples include file handles, sockets, or locks. If they forget, the system " +"might become overloaded and crash. In Rust, you can specify that a " +"particular bit of code be run whenever a value goes out of scope, and the " +"compiler will insert this code automatically. As a result, you don’t need to " +"be careful about placing cleanup code everywhere in a program that an " +"instance of a particular type is finished with—you still won’t leak " +"resources!" +msgstr "" + +#: src/ch15-03-drop.md:22 +msgid "" +"You specify the code to run when a value goes out of scope by implementing " +"the `Drop` trait. The `Drop` trait requires you to implement one method " +"named `drop` that takes a mutable reference to `self`. To see when Rust " +"calls `drop`, let’s implement `drop` with `println!` statements for now." +msgstr "" + +#: src/ch15-03-drop.md:27 +msgid "" +"Listing 15-14 shows a `CustomSmartPointer` struct whose only custom " +"functionality is that it will print `Dropping CustomSmartPointer!` when the " +"instance goes out of scope, to show when Rust runs the `drop` function." +msgstr "" + +#: src/ch15-03-drop.md:40 src/ch15-03-drop.md:115 src/ch15-03-drop.md:181 +msgid "\"Dropping CustomSmartPointer with data `{}`!\"" +msgstr "" + +#: src/ch15-03-drop.md:46 +msgid "\"my stuff\"" +msgstr "" + +#: src/ch15-03-drop.md:49 +msgid "\"other stuff\"" +msgstr "" + +#: src/ch15-03-drop.md:51 +msgid "\"CustomSmartPointers created.\"" +msgstr "" + +#: src/ch15-03-drop.md:55 +msgid "" +"Listing 15-14: A `CustomSmartPointer` struct that " +"implements the `Drop` trait where we would put our cleanup code" +msgstr "" + +#: src/ch15-03-drop.md:58 +msgid "" +"The `Drop` trait is included in the prelude, so we don’t need to bring it " +"into scope. We implement the `Drop` trait on `CustomSmartPointer` and " +"provide an implementation for the `drop` method that calls `println!`. The " +"body of the `drop` function is where you would place any logic that you " +"wanted to run when an instance of your type goes out of scope. We’re " +"printing some text here to demonstrate visually when Rust will call `drop`." +msgstr "" + +#: src/ch15-03-drop.md:65 +msgid "" +"In `main`, we create two instances of `CustomSmartPointer` and then print " +"`CustomSmartPointers created`. At the end of `main`, our instances of " +"`CustomSmartPointer` will go out of scope, and Rust will call the code we " +"put in the `drop` method, printing our final message. Note that we didn’t " +"need to call the `drop` method explicitly." +msgstr "" + +#: src/ch15-03-drop.md:71 +msgid "When we run this program, we’ll see the following output:" +msgstr "" + +#: src/ch15-03-drop.md:73 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling drop-example v0.1.0 (file:///projects/drop-example)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.60s\n" +" Running `target/debug/drop-example`\n" +"CustomSmartPointers created.\n" +"Dropping CustomSmartPointer with data `other stuff`!\n" +"Dropping CustomSmartPointer with data `my stuff`!\n" +"```" +msgstr "" + +#: src/ch15-03-drop.md:83 +msgid "" +"Rust automatically called `drop` for us when our instances went out of " +"scope, calling the code we specified. Variables are dropped in the reverse " +"order of their creation, so `d` was dropped before `c`. This example’s " +"purpose is to give you a visual guide to how the `drop` method works; " +"usually you would specify the cleanup code that your type needs to run " +"rather than a print message." +msgstr "" + +#: src/ch15-03-drop.md:90 +msgid "Dropping a Value Early with `std::mem::drop`" +msgstr "" + +#: src/ch15-03-drop.md:92 +msgid "" +"Unfortunately, it’s not straightforward to disable the automatic `drop` " +"functionality. Disabling `drop` isn’t usually necessary; the whole point of " +"the `Drop` trait is that it’s taken care of automatically. Occasionally, " +"however, you might want to clean up a value early. One example is when using " +"smart pointers that manage locks: you might want to force the `drop` method " +"that releases the lock so that other code in the same scope can acquire the " +"lock. Rust doesn’t let you call the `Drop` trait’s `drop` method manually; " +"instead you have to call the `std::mem::drop` function provided by the " +"standard library if you want to force a value to be dropped before the end " +"of its scope." +msgstr "" + +#: src/ch15-03-drop.md:102 +msgid "" +"If we try to call the `Drop` trait’s `drop` method manually by modifying the " +"`main` function from Listing 15-14, as shown in Listing 15-15, we’ll get a " +"compiler error:" +msgstr "" + +#: src/ch15-03-drop.md:121 src/ch15-03-drop.md:187 +msgid "\"some data\"" +msgstr "" + +#: src/ch15-03-drop.md:123 src/ch15-03-drop.md:189 +msgid "\"CustomSmartPointer created.\"" +msgstr "" + +#: src/ch15-03-drop.md:125 src/ch15-03-drop.md:191 +msgid "\"CustomSmartPointer dropped before the end of main.\"" +msgstr "" + +#: src/ch15-03-drop.md:129 +msgid "" +"Listing 15-15: Attempting to call the `drop` method " +"from the `Drop` trait manually to clean up early" +msgstr "" + +#: src/ch15-03-drop.md:132 +msgid "When we try to compile this code, we’ll get this error:" +msgstr "" + +#: src/ch15-03-drop.md:134 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling drop-example v0.1.0 (file:///projects/drop-example)\n" +"error[E0040]: explicit use of destructor method\n" +" --> src/main.rs:16:7\n" +" |\n" +"16 | c.drop();\n" +" | ^^^^ explicit destructor calls not allowed\n" +" |\n" +"help: consider using `drop` function\n" +" |\n" +"16 | drop(c);\n" +" | +++++ ~\n" +"\n" +"For more information about this error, try `rustc --explain E0040`.\n" +"error: could not compile `drop-example` (bin \"drop-example\") due to 1 " +"previous error\n" +"```" +msgstr "" + +#: src/ch15-03-drop.md:152 +msgid "" +"This error message states that we’re not allowed to explicitly call `drop`. " +"The error message uses the term _destructor_, which is the general " +"programming term for a function that cleans up an instance. A _destructor_ " +"is analogous to a _constructor_, which creates an instance. The `drop` " +"function in Rust is one particular destructor." +msgstr "" + +#: src/ch15-03-drop.md:158 +msgid "" +"Rust doesn’t let us call `drop` explicitly because Rust would still " +"automatically call `drop` on the value at the end of `main`. This would " +"cause a _double free_ error because Rust would be trying to clean up the " +"same value twice." +msgstr "" + +#: src/ch15-03-drop.md:163 +msgid "" +"We can’t disable the automatic insertion of `drop` when a value goes out of " +"scope, and we can’t call the `drop` method explicitly. So, if we need to " +"force a value to be cleaned up early, we use the `std::mem::drop` function." +msgstr "" + +#: src/ch15-03-drop.md:167 +msgid "" +"The `std::mem::drop` function is different from the `drop` method in the " +"`Drop` trait. We call it by passing as an argument the value we want to " +"force drop. The function is in the prelude, so we can modify `main` in " +"Listing 15-15 to call the `drop` function, as shown in Listing 15-16:" +msgstr "" + +#: src/ch15-03-drop.md:195 +msgid "" +"Listing 15-16: Calling `std::mem::drop` to " +"explicitly drop a value before it goes out of scope" +msgstr "" + +#: src/ch15-03-drop.md:198 +msgid "Running this code will print the following:" +msgstr "" + +#: src/ch15-03-drop.md:200 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling drop-example v0.1.0 (file:///projects/drop-example)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.73s\n" +" Running `target/debug/drop-example`\n" +"CustomSmartPointer created.\n" +"Dropping CustomSmartPointer with data `some data`!\n" +"CustomSmartPointer dropped before the end of main.\n" +"```" +msgstr "" + +#: src/ch15-03-drop.md:210 +msgid "" +"The text ``Dropping CustomSmartPointer with data `some data`!`` is printed " +"between the `CustomSmartPointer created.` and `CustomSmartPointer dropped " +"before the end of main.` text, showing that the `drop` method code is called " +"to drop `c` at that point." +msgstr "" + +#: src/ch15-03-drop.md:215 +msgid "" +"You can use code specified in a `Drop` trait implementation in many ways to " +"make cleanup convenient and safe: for instance, you could use it to create " +"your own memory allocator! With the `Drop` trait and Rust’s ownership " +"system, you don’t have to remember to clean up because Rust does it " +"automatically." +msgstr "" + +#: src/ch15-03-drop.md:220 +msgid "" +"You also don’t have to worry about problems resulting from accidentally " +"cleaning up values still in use: the ownership system that makes sure " +"references are always valid also ensures that `drop` gets called only once " +"when the value is no longer being used." +msgstr "" + +#: src/ch15-03-drop.md:225 +msgid "" +"Now that we’ve examined `Box` and some of the characteristics of smart " +"pointers, let’s look at a few other smart pointers defined in the standard " +"library." +msgstr "" + +#: src/ch15-04-rc.md:3 +msgid "" +"In the majority of cases, ownership is clear: you know exactly which " +"variable owns a given value. However, there are cases when a single value " +"might have multiple owners. For example, in graph data structures, multiple " +"edges might point to the same node, and that node is conceptually owned by " +"all of the edges that point to it. A node shouldn’t be cleaned up unless it " +"doesn’t have any edges pointing to it and so has no owners." +msgstr "" + +#: src/ch15-04-rc.md:10 +msgid "" +"You have to enable multiple ownership explicitly by using the Rust type " +"`Rc`, which is an abbreviation for _reference counting_. The `Rc` type " +"keeps track of the number of references to a value to determine whether or " +"not the value is still in use. If there are zero references to a value, the " +"value can be cleaned up without any references becoming invalid." +msgstr "" + +#: src/ch15-04-rc.md:16 +msgid "" +"Imagine `Rc` as a TV in a family room. When one person enters to watch " +"TV, they turn it on. Others can come into the room and watch the TV. When " +"the last person leaves the room, they turn off the TV because it’s no longer " +"being used. If someone turns off the TV while others are still watching it, " +"there would be uproar from the remaining TV watchers!" +msgstr "" + +#: src/ch15-04-rc.md:22 +msgid "" +"We use the `Rc` type when we want to allocate some data on the heap for " +"multiple parts of our program to read and we can’t determine at compile time " +"which part will finish using the data last. If we knew which part would " +"finish last, we could just make that part the data’s owner, and the normal " +"ownership rules enforced at compile time would take effect." +msgstr "" + +#: src/ch15-04-rc.md:28 +msgid "" +"Note that `Rc` is only for use in single-threaded scenarios. When we " +"discuss concurrency in Chapter 16, we’ll cover how to do reference counting " +"in multithreaded programs." +msgstr "" + +#: src/ch15-04-rc.md:32 +msgid "Using `Rc` to Share Data" +msgstr "" + +#: src/ch15-04-rc.md:34 +msgid "" +"Let’s return to our cons list example in Listing 15-5. Recall that we " +"defined it using `Box`. This time, we’ll create two lists that both share " +"ownership of a third list. Conceptually, this looks similar to Figure 15-3:" +msgstr "" + +#: src/ch15-04-rc.md:40 +msgid "" +"Figure 15-3: Two lists, `b` and `c`, sharing " +"ownership of a third list, `a`" +msgstr "" + +#: src/ch15-04-rc.md:43 +msgid "" +"We’ll create list `a` that contains 5 and then 10. Then we’ll make two more " +"lists: `b` that starts with 3 and `c` that starts with 4. Both `b` and `c` " +"lists will then continue on to the first `a` list containing 5 and 10. In " +"other words, both lists will share the first list containing 5 and 10." +msgstr "" + +#: src/ch15-04-rc.md:48 +msgid "" +"Trying to implement this scenario using our definition of `List` with " +"`Box` won’t work, as shown in Listing 15-17:" +msgstr "" + +#: src/ch15-04-rc.md:68 +msgid "" +"Listing 15-17: Demonstrating we’re not allowed to " +"have two lists using `Box` that try to share ownership of a third list" +msgstr "" + +#: src/ch15-04-rc.md:71 +msgid "When we compile this code, we get this error:" +msgstr "" + +#: src/ch15-04-rc.md:73 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling cons-list v0.1.0 (file:///projects/cons-list)\n" +"error[E0382]: use of moved value: `a`\n" +" --> src/main.rs:11:30\n" +" |\n" +"9 | let a = Cons(5, Box::new(Cons(10, Box::new(Nil))));\n" +" | - move occurs because `a` has type `List`, which does not " +"implement the `Copy` trait\n" +"10 | let b = Cons(3, Box::new(a));\n" +" | - value moved here\n" +"11 | let c = Cons(4, Box::new(a));\n" +" | ^ value used here after move\n" +"\n" +"For more information about this error, try `rustc --explain E0382`.\n" +"error: could not compile `cons-list` (bin \"cons-list\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch15-04-rc.md:90 +msgid "" +"The `Cons` variants own the data they hold, so when we create the `b` list, " +"`a` is moved into `b` and `b` owns `a`. Then, when we try to use `a` again " +"when creating `c`, we’re not allowed to because `a` has been moved." +msgstr "" + +#: src/ch15-04-rc.md:94 +msgid "" +"We could change the definition of `Cons` to hold references instead, but " +"then we would have to specify lifetime parameters. By specifying lifetime " +"parameters, we would be specifying that every element in the list will live " +"at least as long as the entire list. This is the case for the elements and " +"lists in Listing 15-17, but not in every scenario." +msgstr "" + +#: src/ch15-04-rc.md:100 +msgid "" +"Instead, we’ll change our definition of `List` to use `Rc` in place of " +"`Box`, as shown in Listing 15-18. Each `Cons` variant will now hold a " +"value and an `Rc` pointing to a `List`. When we create `b`, instead of " +"taking ownership of `a`, we’ll clone the `Rc` that `a` is holding, " +"thereby increasing the number of references from one to two and letting `a` " +"and `b` share ownership of the data in that `Rc`. We’ll also clone `a` " +"when creating `c`, increasing the number of references from two to three. " +"Every time we call `Rc::clone`, the reference count to the data within the " +"`Rc` will increase, and the data won’t be cleaned up unless there are " +"zero references to it." +msgstr "" + +#: src/ch15-04-rc.md:129 +msgid "" +"Listing 15-18: A definition of `List` that uses " +"`Rc`" +msgstr "" + +#: src/ch15-04-rc.md:132 +msgid "" +"We need to add a `use` statement to bring `Rc` into scope because it’s " +"not in the prelude. In `main`, we create the list holding 5 and 10 and store " +"it in a new `Rc` in `a`. Then when we create `b` and `c`, we call the " +"`Rc::clone` function and pass a reference to the `Rc` in `a` as an " +"argument." +msgstr "" + +#: src/ch15-04-rc.md:138 +msgid "" +"We could have called `a.clone()` rather than `Rc::clone(&a)`, but Rust’s " +"convention is to use `Rc::clone` in this case. The implementation of `Rc::" +"clone` doesn’t make a deep copy of all the data like most types’ " +"implementations of `clone` do. The call to `Rc::clone` only increments the " +"reference count, which doesn’t take much time. Deep copies of data can take " +"a lot of time. By using `Rc::clone` for reference counting, we can visually " +"distinguish between the deep-copy kinds of clones and the kinds of clones " +"that increase the reference count. When looking for performance problems in " +"the code, we only need to consider the deep-copy clones and can disregard " +"calls to `Rc::clone`." +msgstr "" + +#: src/ch15-04-rc.md:149 +msgid "Cloning an `Rc` Increases the Reference Count" +msgstr "" + +#: src/ch15-04-rc.md:151 +msgid "" +"Let’s change our working example in Listing 15-18 so we can see the " +"reference counts changing as we create and drop references to the `Rc` " +"in `a`." +msgstr "" + +#: src/ch15-04-rc.md:154 +msgid "" +"In Listing 15-19, we’ll change `main` so it has an inner scope around list " +"`c`; then we can see how the reference count changes when `c` goes out of " +"scope." +msgstr "" + +#: src/ch15-04-rc.md:170 +msgid "\"count after creating a = {}\"" +msgstr "" + +#: src/ch15-04-rc.md:172 +msgid "\"count after creating b = {}\"" +msgstr "" + +#: src/ch15-04-rc.md:175 +msgid "\"count after creating c = {}\"" +msgstr "" + +#: src/ch15-04-rc.md:177 +msgid "\"count after c goes out of scope = {}\"" +msgstr "" + +#: src/ch15-04-rc.md:181 +msgid "" +"Listing 15-19: Printing the reference count" +msgstr "" + +#: src/ch15-04-rc.md:183 +msgid "" +"At each point in the program where the reference count changes, we print the " +"reference count, which we get by calling the `Rc::strong_count` function. " +"This function is named `strong_count` rather than `count` because the " +"`Rc` type also has a `weak_count`; we’ll see what `weak_count` is used " +"for in the [“Preventing Reference Cycles: Turning an `Rc` into a " +"`Weak`”](ch15-06-reference-cycles.html#preventing-reference-cycles-" +"turning-an-rct-into-a-weakt) section." +msgstr "" + +#: src/ch15-04-rc.md:190 +msgid "This code prints the following:" +msgstr "" + +#: src/ch15-04-rc.md:192 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling cons-list v0.1.0 (file:///projects/cons-list)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.45s\n" +" Running `target/debug/cons-list`\n" +"count after creating a = 1\n" +"count after creating b = 2\n" +"count after creating c = 3\n" +"count after c goes out of scope = 2\n" +"```" +msgstr "" + +#: src/ch15-04-rc.md:203 +msgid "" +"We can see that the `Rc` in `a` has an initial reference count of 1; " +"then each time we call `clone`, the count goes up by 1. When `c` goes out of " +"scope, the count goes down by 1. We don’t have to call a function to " +"decrease the reference count like we have to call `Rc::clone` to increase " +"the reference count: the implementation of the `Drop` trait decreases the " +"reference count automatically when an `Rc` value goes out of scope." +msgstr "" + +#: src/ch15-04-rc.md:210 +msgid "" +"What we can’t see in this example is that when `b` and then `a` go out of " +"scope at the end of `main`, the count is then 0, and the `Rc` is " +"cleaned up completely. Using `Rc` allows a single value to have multiple " +"owners, and the count ensures that the value remains valid as long as any of " +"the owners still exist." +msgstr "" + +#: src/ch15-04-rc.md:216 +msgid "" +"Via immutable references, `Rc` allows you to share data between multiple " +"parts of your program for reading only. If `Rc` allowed you to have " +"multiple mutable references too, you might violate one of the borrowing " +"rules discussed in Chapter 4: multiple mutable borrows to the same place can " +"cause data races and inconsistencies. But being able to mutate data is very " +"useful! In the next section, we’ll discuss the interior mutability pattern " +"and the `RefCell` type that you can use in conjunction with an `Rc` to " +"work with this immutability restriction." +msgstr "" + +#: src/ch15-05-interior-mutability.md:3 +msgid "" +"_Interior mutability_ is a design pattern in Rust that allows you to mutate " +"data even when there are immutable references to that data; normally, this " +"action is disallowed by the borrowing rules. To mutate data, the pattern " +"uses `unsafe` code inside a data structure to bend Rust’s usual rules that " +"govern mutation and borrowing. Unsafe code indicates to the compiler that " +"we’re checking the rules manually instead of relying on the compiler to " +"check them for us; we will discuss unsafe code more in Chapter 19." +msgstr "" + +#: src/ch15-05-interior-mutability.md:11 +msgid "" +"We can use types that use the interior mutability pattern only when we can " +"ensure that the borrowing rules will be followed at runtime, even though the " +"compiler can’t guarantee that. The `unsafe` code involved is then wrapped in " +"a safe API, and the outer type is still immutable." +msgstr "" + +#: src/ch15-05-interior-mutability.md:16 +msgid "" +"Let’s explore this concept by looking at the `RefCell` type that follows " +"the interior mutability pattern." +msgstr "" + +#: src/ch15-05-interior-mutability.md:19 +msgid "Enforcing Borrowing Rules at Runtime with `RefCell`" +msgstr "" + +#: src/ch15-05-interior-mutability.md:21 +msgid "" +"Unlike `Rc`, the `RefCell` type represents single ownership over the " +"data it holds. So, what makes `RefCell` different from a type like " +"`Box`? Recall the borrowing rules you learned in Chapter 4:" +msgstr "" + +#: src/ch15-05-interior-mutability.md:25 +msgid "" +"At any given time, you can have _either_ (but not both) one mutable " +"reference or any number of immutable references." +msgstr "" + +#: src/ch15-05-interior-mutability.md:29 +msgid "" +"With references and `Box`, the borrowing rules’ invariants are enforced " +"at compile time. With `RefCell`, these invariants are enforced _at " +"runtime_. With references, if you break these rules, you’ll get a compiler " +"error. With `RefCell`, if you break these rules, your program will panic " +"and exit." +msgstr "" + +#: src/ch15-05-interior-mutability.md:34 +msgid "" +"The advantages of checking the borrowing rules at compile time are that " +"errors will be caught sooner in the development process, and there is no " +"impact on runtime performance because all the analysis is completed " +"beforehand. For those reasons, checking the borrowing rules at compile time " +"is the best choice in the majority of cases, which is why this is Rust’s " +"default." +msgstr "" + +#: src/ch15-05-interior-mutability.md:40 +msgid "" +"The advantage of checking the borrowing rules at runtime instead is that " +"certain memory-safe scenarios are then allowed, where they would’ve been " +"disallowed by the compile-time checks. Static analysis, like the Rust " +"compiler, is inherently conservative. Some properties of code are impossible " +"to detect by analyzing the code: the most famous example is the Halting " +"Problem, which is beyond the scope of this book but is an interesting topic " +"to research." +msgstr "" + +#: src/ch15-05-interior-mutability.md:47 +msgid "" +"Because some analysis is impossible, if the Rust compiler can’t be sure the " +"code complies with the ownership rules, it might reject a correct program; " +"in this way, it’s conservative. If Rust accepted an incorrect program, users " +"wouldn’t be able to trust in the guarantees Rust makes. However, if Rust " +"rejects a correct program, the programmer will be inconvenienced, but " +"nothing catastrophic can occur. The `RefCell` type is useful when you’re " +"sure your code follows the borrowing rules but the compiler is unable to " +"understand and guarantee that." +msgstr "" + +#: src/ch15-05-interior-mutability.md:56 +msgid "" +"Similar to `Rc`, `RefCell` is only for use in single-threaded " +"scenarios and will give you a compile-time error if you try using it in a " +"multithreaded context. We’ll talk about how to get the functionality of " +"`RefCell` in a multithreaded program in Chapter 16." +msgstr "" + +#: src/ch15-05-interior-mutability.md:61 +msgid "" +"Here is a recap of the reasons to choose `Box`, `Rc`, or `RefCell`:" +msgstr "" + +#: src/ch15-05-interior-mutability.md:63 +msgid "" +"`Rc` enables multiple owners of the same data; `Box` and `RefCell` " +"have single owners." +msgstr "" + +#: src/ch15-05-interior-mutability.md:65 +msgid "" +"`Box` allows immutable or mutable borrows checked at compile time; " +"`Rc` allows only immutable borrows checked at compile time; `RefCell` " +"allows immutable or mutable borrows checked at runtime." +msgstr "" + +#: src/ch15-05-interior-mutability.md:68 +msgid "" +"Because `RefCell` allows mutable borrows checked at runtime, you can " +"mutate the value inside the `RefCell` even when the `RefCell` is " +"immutable." +msgstr "" + +#: src/ch15-05-interior-mutability.md:72 +msgid "" +"Mutating the value inside an immutable value is the _interior mutability_ " +"pattern. Let’s look at a situation in which interior mutability is useful " +"and examine how it’s possible." +msgstr "" + +#: src/ch15-05-interior-mutability.md:76 +msgid "Interior Mutability: A Mutable Borrow to an Immutable Value" +msgstr "" + +#: src/ch15-05-interior-mutability.md:78 +msgid "" +"A consequence of the borrowing rules is that when you have an immutable " +"value, you can’t borrow it mutably. For example, this code won’t compile:" +msgstr "" + +#: src/ch15-05-interior-mutability.md:88 +msgid "If you tried to compile this code, you’d get the following error:" +msgstr "" + +#: src/ch15-05-interior-mutability.md:90 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling borrowing v0.1.0 (file:///projects/borrowing)\n" +"error[E0596]: cannot borrow `x` as mutable, as it is not declared as " +"mutable\n" +" --> src/main.rs:3:13\n" +" |\n" +"3 | let y = &mut x;\n" +" | ^^^^^^ cannot borrow as mutable\n" +" |\n" +"help: consider changing this to be mutable\n" +" |\n" +"2 | let mut x = 5;\n" +" | +++\n" +"\n" +"For more information about this error, try `rustc --explain E0596`.\n" +"error: could not compile `borrowing` (bin \"borrowing\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch15-05-interior-mutability.md:108 +msgid "" +"However, there are situations in which it would be useful for a value to " +"mutate itself in its methods but appear immutable to other code. Code " +"outside the value’s methods would not be able to mutate the value. Using " +"`RefCell` is one way to get the ability to have interior mutability, but " +"`RefCell` doesn’t get around the borrowing rules completely: the borrow " +"checker in the compiler allows this interior mutability, and the borrowing " +"rules are checked at runtime instead. If you violate the rules, you’ll get a " +"`panic!` instead of a compiler error." +msgstr "" + +#: src/ch15-05-interior-mutability.md:117 +msgid "" +"Let’s work through a practical example where we can use `RefCell` to " +"mutate an immutable value and see why that is useful." +msgstr "" + +#: src/ch15-05-interior-mutability.md:120 +msgid "A Use Case for Interior Mutability: Mock Objects" +msgstr "" + +#: src/ch15-05-interior-mutability.md:122 +msgid "" +"Sometimes during testing a programmer will use a type in place of another " +"type, in order to observe particular behavior and assert it’s implemented " +"correctly. This placeholder type is called a _test double_. Think of it in " +"the sense of a “stunt double” in filmmaking, where a person steps in and " +"substitutes for an actor to do a particular tricky scene. Test doubles stand " +"in for other types when we’re running tests. _Mock objects_ are specific " +"types of test doubles that record what happens during a test so you can " +"assert that the correct actions took place." +msgstr "" + +#: src/ch15-05-interior-mutability.md:131 +msgid "" +"Rust doesn’t have objects in the same sense as other languages have objects, " +"and Rust doesn’t have mock object functionality built into the standard " +"library as some other languages do. However, you can definitely create a " +"struct that will serve the same purposes as a mock object." +msgstr "" + +#: src/ch15-05-interior-mutability.md:136 +msgid "" +"Here’s the scenario we’ll test: we’ll create a library that tracks a value " +"against a maximum value and sends messages based on how close to the maximum " +"value the current value is. This library could be used to keep track of a " +"user’s quota for the number of API calls they’re allowed to make, for " +"example." +msgstr "" + +#: src/ch15-05-interior-mutability.md:141 +msgid "" +"Our library will only provide the functionality of tracking how close to the " +"maximum a value is and what the messages should be at what times. " +"Applications that use our library will be expected to provide the mechanism " +"for sending the messages: the application could put a message in the " +"application, send an email, send a text message, or something else. The " +"library doesn’t need to know that detail. All it needs is something that " +"implements a trait we’ll provide called `Messenger`. Listing 15-20 shows the " +"library code:" +msgstr "" + +#: src/ch15-05-interior-mutability.md:180 +#: src/ch15-05-interior-mutability.md:244 +#: src/ch15-05-interior-mutability.md:376 +#: src/ch15-05-interior-mutability.md:497 +msgid "\"Error: You are over your quota!\"" +msgstr "" + +#: src/ch15-05-interior-mutability.md:183 +#: src/ch15-05-interior-mutability.md:247 +#: src/ch15-05-interior-mutability.md:379 +#: src/ch15-05-interior-mutability.md:500 +msgid "\"Urgent warning: You've used up over 90% of your quota!\"" +msgstr "" + +#: src/ch15-05-interior-mutability.md:186 +#: src/ch15-05-interior-mutability.md:250 +#: src/ch15-05-interior-mutability.md:382 +#: src/ch15-05-interior-mutability.md:503 +msgid "\"Warning: You've used up over 75% of your quota!\"" +msgstr "" + +#: src/ch15-05-interior-mutability.md:192 +msgid "" +"Listing 15-20: A library to keep track of how close " +"a value is to a maximum value and warn when the value is at certain levels" +msgstr "" + +#: src/ch15-05-interior-mutability.md:195 +msgid "" +"One important part of this code is that the `Messenger` trait has one method " +"called `send` that takes an immutable reference to `self` and the text of " +"the message. This trait is the interface our mock object needs to implement " +"so that the mock can be used in the same way a real object is. The other " +"important part is that we want to test the behavior of the `set_value` " +"method on the `LimitTracker`. We can change what we pass in for the `value` " +"parameter, but `set_value` doesn’t return anything for us to make assertions " +"on. We want to be able to say that if we create a `LimitTracker` with " +"something that implements the `Messenger` trait and a particular value for " +"`max`, when we pass different numbers for `value`, the messenger is told to " +"send the appropriate messages." +msgstr "" + +#: src/ch15-05-interior-mutability.md:206 +msgid "" +"We need a mock object that, instead of sending an email or text message when " +"we call `send`, will only keep track of the messages it’s told to send. We " +"can create a new instance of the mock object, create a `LimitTracker` that " +"uses the mock object, call the `set_value` method on `LimitTracker`, and " +"then check that the mock object has the messages we expect. Listing 15-21 " +"shows an attempt to implement a mock object to do just that, but the borrow " +"checker won’t allow it:" +msgstr "" + +#: src/ch15-05-interior-mutability.md:289 +msgid "" +"Listing 15-21: An attempt to implement a " +"`MockMessenger` that isn’t allowed by the borrow checker" +msgstr "" + +#: src/ch15-05-interior-mutability.md:292 +msgid "" +"This test code defines a `MockMessenger` struct that has a `sent_messages` " +"field with a `Vec` of `String` values to keep track of the messages it’s " +"told to send. We also define an associated function `new` to make it " +"convenient to create new `MockMessenger` values that start with an empty " +"list of messages. We then implement the `Messenger` trait for " +"`MockMessenger` so we can give a `MockMessenger` to a `LimitTracker`. In the " +"definition of the `send` method, we take the message passed in as a " +"parameter and store it in the `MockMessenger` list of `sent_messages`." +msgstr "" + +#: src/ch15-05-interior-mutability.md:301 +msgid "" +"In the test, we’re testing what happens when the `LimitTracker` is told to " +"set `value` to something that is more than 75 percent of the `max` value. " +"First, we create a new `MockMessenger`, which will start with an empty list " +"of messages. Then we create a new `LimitTracker` and give it a reference to " +"the new `MockMessenger` and a `max` value of 100. We call the `set_value` " +"method on the `LimitTracker` with a value of 80, which is more than 75 " +"percent of 100. Then we assert that the list of messages that the " +"`MockMessenger` is keeping track of should now have one message in it." +msgstr "" + +#: src/ch15-05-interior-mutability.md:310 +msgid "However, there’s one problem with this test, as shown here:" +msgstr "" + +#: src/ch15-05-interior-mutability.md:312 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling limit-tracker v0.1.0 (file:///projects/limit-tracker)\n" +"error[E0596]: cannot borrow `self.sent_messages` as mutable, as it is behind " +"a `&` reference\n" +" --> src/lib.rs:58:13\n" +" |\n" +"58 | self.sent_messages.push(String::from(message));\n" +" | ^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data " +"it refers to cannot be borrowed as mutable\n" +" |\n" +"help: consider changing this to be a mutable reference in the `impl` method " +"and the `trait` definition\n" +" |\n" +"2 ~ fn send(&mut self, msg: &str);\n" +"3 | }\n" +" ...\n" +"56 | impl Messenger for MockMessenger {\n" +"57 ~ fn send(&mut self, message: &str) {\n" +" |\n" +"\n" +"For more information about this error, try `rustc --explain E0596`.\n" +"error: could not compile `limit-tracker` (lib test) due to 1 previous error\n" +"```" +msgstr "" + +#: src/ch15-05-interior-mutability.md:334 +msgid "" +"We can’t modify the `MockMessenger` to keep track of the messages, because " +"the `send` method takes an immutable reference to `self`. We also can’t take " +"the suggestion from the error text to use `&mut self` instead, because then " +"the signature of `send` wouldn’t match the signature in the `Messenger` " +"trait definition (feel free to try and see what error message you get)." +msgstr "" + +#: src/ch15-05-interior-mutability.md:340 +msgid "" +"This is a situation in which interior mutability can help! We’ll store the " +"`sent_messages` within a `RefCell`, and then the `send` method will be " +"able to modify `sent_messages` to store the messages we’ve seen. Listing " +"15-22 shows what that looks like:" +msgstr "" + +#: src/ch15-05-interior-mutability.md:423 +msgid "" +"Listing 15-22: Using `RefCell` to mutate an inner " +"value while the outer value is considered immutable" +msgstr "" + +#: src/ch15-05-interior-mutability.md:426 +msgid "" +"The `sent_messages` field is now of type `RefCell>` instead of " +"`Vec`. In the `new` function, we create a new `RefCell>` " +"instance around the empty vector." +msgstr "" + +#: src/ch15-05-interior-mutability.md:430 +msgid "" +"For the implementation of the `send` method, the first parameter is still an " +"immutable borrow of `self`, which matches the trait definition. We call " +"`borrow_mut` on the `RefCell>` in `self.sent_messages` to get a " +"mutable reference to the value inside the `RefCell>`, which is " +"the vector. Then we can call `push` on the mutable reference to the vector " +"to keep track of the messages sent during the test." +msgstr "" + +#: src/ch15-05-interior-mutability.md:437 +msgid "" +"The last change we have to make is in the assertion: to see how many items " +"are in the inner vector, we call `borrow` on the `RefCell>` to " +"get an immutable reference to the vector." +msgstr "" + +#: src/ch15-05-interior-mutability.md:441 +msgid "" +"Now that you’ve seen how to use `RefCell`, let’s dig into how it works!" +msgstr "" + +#: src/ch15-05-interior-mutability.md:443 +msgid "Keeping Track of Borrows at Runtime with `RefCell`" +msgstr "" + +#: src/ch15-05-interior-mutability.md:445 +msgid "" +"When creating immutable and mutable references, we use the `&` and `&mut` " +"syntax, respectively. With `RefCell`, we use the `borrow` and " +"`borrow_mut` methods, which are part of the safe API that belongs to " +"`RefCell`. The `borrow` method returns the smart pointer type `Ref`, " +"and `borrow_mut` returns the smart pointer type `RefMut`. Both types " +"implement `Deref`, so we can treat them like regular references." +msgstr "" + +#: src/ch15-05-interior-mutability.md:452 +msgid "" +"The `RefCell` keeps track of how many `Ref` and `RefMut` smart " +"pointers are currently active. Every time we call `borrow`, the `RefCell` " +"increases its count of how many immutable borrows are active. When a " +"`Ref` value goes out of scope, the count of immutable borrows goes down " +"by one. Just like the compile-time borrowing rules, `RefCell` lets us " +"have many immutable borrows or one mutable borrow at any point in time." +msgstr "" + +#: src/ch15-05-interior-mutability.md:459 +msgid "" +"If we try to violate these rules, rather than getting a compiler error as we " +"would with references, the implementation of `RefCell` will panic at " +"runtime. Listing 15-23 shows a modification of the implementation of `send` " +"in Listing 15-22. We’re deliberately trying to create two mutable borrows " +"active for the same scope to illustrate that `RefCell` prevents us from " +"doing this at runtime." +msgstr "" + +#: src/ch15-05-interior-mutability.md:547 +msgid "" +"Listing 15-23: Creating two mutable references in " +"the same scope to see that `RefCell` will panic" +msgstr "" + +#: src/ch15-05-interior-mutability.md:550 +msgid "" +"We create a variable `one_borrow` for the `RefMut` smart pointer returned " +"from `borrow_mut`. Then we create another mutable borrow in the same way in " +"the variable `two_borrow`. This makes two mutable references in the same " +"scope, which isn’t allowed. When we run the tests for our library, the code " +"in Listing 15-23 will compile without any errors, but the test will fail:" +msgstr "" + +#: src/ch15-05-interior-mutability.md:556 +msgid "" +"```console\n" +"$ cargo test\n" +" Compiling limit-tracker v0.1.0 (file:///projects/limit-tracker)\n" +" Finished `test` profile [unoptimized + debuginfo] target(s) in 0.91s\n" +" Running unittests src/lib.rs (target/debug/deps/limit_tracker-" +"e599811fa246dbde)\n" +"\n" +"running 1 test\n" +"test tests::it_sends_an_over_75_percent_warning_message ... FAILED\n" +"\n" +"failures:\n" +"\n" +"---- tests::it_sends_an_over_75_percent_warning_message stdout ----\n" +"thread 'tests::it_sends_an_over_75_percent_warning_message' panicked at src/" +"lib.rs:60:53:\n" +"already borrowed: BorrowMutError\n" +"note: run with `RUST_BACKTRACE=1` environment variable to display a " +"backtrace\n" +"\n" +"\n" +"failures:\n" +" tests::it_sends_an_over_75_percent_warning_message\n" +"\n" +"test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered " +"out; finished in 0.00s\n" +"\n" +"error: test failed, to rerun pass `--lib`\n" +"```" +msgstr "" + +#: src/ch15-05-interior-mutability.md:581 +msgid "" +"Notice that the code panicked with the message `already borrowed: " +"BorrowMutError`. This is how `RefCell` handles violations of the " +"borrowing rules at runtime." +msgstr "" + +#: src/ch15-05-interior-mutability.md:585 +msgid "" +"Choosing to catch borrowing errors at runtime rather than compile time, as " +"we’ve done here, means you’d potentially be finding mistakes in your code " +"later in the development process: possibly not until your code was deployed " +"to production. Also, your code would incur a small runtime performance " +"penalty as a result of keeping track of the borrows at runtime rather than " +"compile time. However, using `RefCell` makes it possible to write a mock " +"object that can modify itself to keep track of the messages it has seen " +"while you’re using it in a context where only immutable values are allowed. " +"You can use `RefCell` despite its trade-offs to get more functionality " +"than regular references provide." +msgstr "" + +#: src/ch15-05-interior-mutability.md:596 +msgid "" +"Having Multiple Owners of Mutable Data by Combining `Rc` and `RefCell`" +msgstr "" + +#: src/ch15-05-interior-mutability.md:598 +msgid "" +"A common way to use `RefCell` is in combination with `Rc`. Recall that " +"`Rc` lets you have multiple owners of some data, but it only gives " +"immutable access to that data. If you have an `Rc` that holds a " +"`RefCell`, you can get a value that can have multiple owners _and_ that " +"you can mutate!" +msgstr "" + +#: src/ch15-05-interior-mutability.md:603 +msgid "" +"For example, recall the cons list example in Listing 15-18 where we used " +"`Rc` to allow multiple lists to share ownership of another list. Because " +"`Rc` holds only immutable values, we can’t change any of the values in " +"the list once we’ve created them. Let’s add in `RefCell` to gain the " +"ability to change the values in the lists. Listing 15-24 shows that by using " +"a `RefCell` in the `Cons` definition, we can modify the value stored in " +"all the lists:" +msgstr "" + +#: src/ch15-05-interior-mutability.md:634 +msgid "\"a after = {a:?}\"" +msgstr "" + +#: src/ch15-05-interior-mutability.md:635 +msgid "\"b after = {b:?}\"" +msgstr "" + +#: src/ch15-05-interior-mutability.md:636 +msgid "\"c after = {c:?}\"" +msgstr "" + +#: src/ch15-05-interior-mutability.md:640 +msgid "" +"Listing 15-24: Using `Rc>` to create a " +"`List` that we can mutate" +msgstr "" + +#: src/ch15-05-interior-mutability.md:643 +msgid "" +"We create a value that is an instance of `Rc>` and store it in " +"a variable named `value` so we can access it directly later. Then we create " +"a `List` in `a` with a `Cons` variant that holds `value`. We need to clone " +"`value` so both `a` and `value` have ownership of the inner `5` value rather " +"than transferring ownership from `value` to `a` or having `a` borrow from " +"`value`." +msgstr "" + +#: src/ch15-05-interior-mutability.md:650 +msgid "" +"We wrap the list `a` in an `Rc` so when we create lists `b` and `c`, they " +"can both refer to `a`, which is what we did in Listing 15-18." +msgstr "" + +#: src/ch15-05-interior-mutability.md:653 +msgid "" +"After we’ve created the lists in `a`, `b`, and `c`, we want to add 10 to the " +"value in `value`. We do this by calling `borrow_mut` on `value`, which uses " +"the automatic dereferencing feature we discussed in Chapter 5 (see the " +"section [“Where’s the `->` Operator?”](ch05-03-method-syntax.html#wheres-" +"the---operator)) to dereference the `Rc` to the inner " +"`RefCell` value. The `borrow_mut` method returns a `RefMut` smart " +"pointer, and we use the dereference operator on it and change the inner " +"value." +msgstr "" + +#: src/ch15-05-interior-mutability.md:661 +msgid "" +"When we print `a`, `b`, and `c`, we can see that they all have the modified " +"value of 15 rather than 5:" +msgstr "" + +#: src/ch15-05-interior-mutability.md:664 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling cons-list v0.1.0 (file:///projects/cons-list)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.63s\n" +" Running `target/debug/cons-list`\n" +"a after = Cons(RefCell { value: 15 }, Nil)\n" +"b after = Cons(RefCell { value: 3 }, Cons(RefCell { value: 15 }, Nil))\n" +"c after = Cons(RefCell { value: 4 }, Cons(RefCell { value: 15 }, Nil))\n" +"```" +msgstr "" + +#: src/ch15-05-interior-mutability.md:674 +msgid "" +"This technique is pretty neat! By using `RefCell`, we have an outwardly " +"immutable `List` value. But we can use the methods on `RefCell` that " +"provide access to its interior mutability so we can modify our data when we " +"need to. The runtime checks of the borrowing rules protect us from data " +"races, and it’s sometimes worth trading a bit of speed for this flexibility " +"in our data structures. Note that `RefCell` does not work for " +"multithreaded code! `Mutex` is the thread-safe version of `RefCell` " +"and we’ll discuss `Mutex` in Chapter 16." +msgstr "" + +#: src/ch15-06-reference-cycles.md:3 +msgid "" +"Rust’s memory safety guarantees make it difficult, but not impossible, to " +"accidentally create memory that is never cleaned up (known as a _memory " +"leak_). Preventing memory leaks entirely is not one of Rust’s guarantees, " +"meaning memory leaks are memory safe in Rust. We can see that Rust allows " +"memory leaks by using `Rc` and `RefCell`: it’s possible to create " +"references where items refer to each other in a cycle. This creates memory " +"leaks because the reference count of each item in the cycle will never reach " +"0, and the values will never be dropped." +msgstr "" + +#: src/ch15-06-reference-cycles.md:12 +msgid "Creating a Reference Cycle" +msgstr "" + +#: src/ch15-06-reference-cycles.md:14 +msgid "" +"Let’s look at how a reference cycle might happen and how to prevent it, " +"starting with the definition of the `List` enum and a `tail` method in " +"Listing 15-25:" +msgstr "" + +#: src/ch15-06-reference-cycles.md:43 +msgid "" +"Listing 15-25: A cons list definition that holds a " +"`RefCell` so we can modify what a `Cons` variant is referring to" +msgstr "" + +#: src/ch15-06-reference-cycles.md:46 +msgid "" +"We’re using another variation of the `List` definition from Listing 15-5. " +"The second element in the `Cons` variant is now `RefCell>`, meaning " +"that instead of having the ability to modify the `i32` value as we did in " +"Listing 15-24, we want to modify the `List` value a `Cons` variant is " +"pointing to. We’re also adding a `tail` method to make it convenient for us " +"to access the second item if we have a `Cons` variant." +msgstr "" + +#: src/ch15-06-reference-cycles.md:53 +msgid "" +"In Listing 15-26, we’re adding a `main` function that uses the definitions " +"in Listing 15-25. This code creates a list in `a` and a list in `b` that " +"points to the list in `a`. Then it modifies the list in `a` to point to `b`, " +"creating a reference cycle. There are `println!` statements along the way to " +"show what the reference counts are at various points in this process." +msgstr "" + +#: src/ch15-06-reference-cycles.md:84 +msgid "\"a initial rc count = {}\"" +msgstr "" + +#: src/ch15-06-reference-cycles.md:85 +msgid "\"a next item = {:?}\"" +msgstr "" + +#: src/ch15-06-reference-cycles.md:89 +msgid "\"a rc count after b creation = {}\"" +msgstr "" + +#: src/ch15-06-reference-cycles.md:90 +msgid "\"b initial rc count = {}\"" +msgstr "" + +#: src/ch15-06-reference-cycles.md:91 +msgid "\"b next item = {:?}\"" +msgstr "" + +#: src/ch15-06-reference-cycles.md:97 +msgid "\"b rc count after changing a = {}\"" +msgstr "" + +#: src/ch15-06-reference-cycles.md:98 +msgid "\"a rc count after changing a = {}\"" +msgstr "" + +#: src/ch15-06-reference-cycles.md:100 +msgid "" +"// Uncomment the next line to see that we have a cycle;\n" +" // it will overflow the stack\n" +" // println!(\"a next item = {:?}\", a.tail());\n" +msgstr "" + +#: src/ch15-06-reference-cycles.md:106 +msgid "" +"Listing 15-26: Creating a reference cycle of two " +"`List` values pointing to each other" +msgstr "" + +#: src/ch15-06-reference-cycles.md:109 +msgid "" +"We create an `Rc` instance holding a `List` value in the variable `a` " +"with an initial list of `5, Nil`. We then create an `Rc` instance " +"holding another `List` value in the variable `b` that contains the value 10 " +"and points to the list in `a`." +msgstr "" + +#: src/ch15-06-reference-cycles.md:114 +msgid "" +"We modify `a` so it points to `b` instead of `Nil`, creating a cycle. We do " +"that by using the `tail` method to get a reference to the " +"`RefCell>` in `a`, which we put in the variable `link`. Then we use " +"the `borrow_mut` method on the `RefCell>` to change the value " +"inside from an `Rc` that holds a `Nil` value to the `Rc` in `b`." +msgstr "" + +#: src/ch15-06-reference-cycles.md:120 +msgid "" +"When we run this code, keeping the last `println!` commented out for the " +"moment, we’ll get this output:" +msgstr "" + +#: src/ch15-06-reference-cycles.md:123 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling cons-list v0.1.0 (file:///projects/cons-list)\n" +" Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.53s\n" +" Running `target/debug/cons-list`\n" +"a initial rc count = 1\n" +"a next item = Some(RefCell { value: Nil })\n" +"a rc count after b creation = 2\n" +"b initial rc count = 1\n" +"b next item = Some(RefCell { value: Cons(5, RefCell { value: Nil }) })\n" +"b rc count after changing a = 2\n" +"a rc count after changing a = 2\n" +"```" +msgstr "" + +#: src/ch15-06-reference-cycles.md:137 +msgid "" +"The reference count of the `Rc` instances in both `a` and `b` are 2 " +"after we change the list in `a` to point to `b`. At the end of `main`, Rust " +"drops the variable `b`, which decreases the reference count of the `b` " +"`Rc` instance from 2 to 1. The memory that `Rc` has on the heap " +"won’t be dropped at this point, because its reference count is 1, not 0. " +"Then Rust drops `a`, which decreases the reference count of the `a` " +"`Rc` instance from 2 to 1 as well. This instance’s memory can’t be " +"dropped either, because the other `Rc` instance still refers to it. " +"The memory allocated to the list will remain uncollected forever. To " +"visualize this reference cycle, we’ve created a diagram in Figure 15-4." +msgstr "" + +#: src/ch15-06-reference-cycles.md:150 +msgid "" +"Figure 15-4: A reference cycle of lists `a` and `b` " +"pointing to each other" +msgstr "" + +#: src/ch15-06-reference-cycles.md:153 +msgid "" +"If you uncomment the last `println!` and run the program, Rust will try to " +"print this cycle with `a` pointing to `b` pointing to `a` and so forth until " +"it overflows the stack." +msgstr "" + +#: src/ch15-06-reference-cycles.md:157 +msgid "" +"Compared to a real-world program, the consequences of creating a reference " +"cycle in this example aren’t very dire: right after we create the reference " +"cycle, the program ends. However, if a more complex program allocated lots " +"of memory in a cycle and held onto it for a long time, the program would use " +"more memory than it needed and might overwhelm the system, causing it to run " +"out of available memory." +msgstr "" + +#: src/ch15-06-reference-cycles.md:164 +msgid "" +"Creating reference cycles is not easily done, but it’s not impossible " +"either. If you have `RefCell` values that contain `Rc` values or " +"similar nested combinations of types with interior mutability and reference " +"counting, you must ensure that you don’t create cycles; you can’t rely on " +"Rust to catch them. Creating a reference cycle would be a logic bug in your " +"program that you should use automated tests, code reviews, and other " +"software development practices to minimize." +msgstr "" + +#: src/ch15-06-reference-cycles.md:172 +msgid "" +"Another solution for avoiding reference cycles is reorganizing your data " +"structures so that some references express ownership and some references " +"don’t. As a result, you can have cycles made up of some ownership " +"relationships and some non-ownership relationships, and only the ownership " +"relationships affect whether or not a value can be dropped. In Listing " +"15-25, we always want `Cons` variants to own their list, so reorganizing the " +"data structure isn’t possible. Let’s look at an example using graphs made up " +"of parent nodes and child nodes to see when non-ownership relationships are " +"an appropriate way to prevent reference cycles." +msgstr "" + +#: src/ch15-06-reference-cycles.md:182 +msgid "Preventing Reference Cycles: Turning an `Rc` into a `Weak`" +msgstr "" + +#: src/ch15-06-reference-cycles.md:184 +msgid "" +"So far, we’ve demonstrated that calling `Rc::clone` increases the " +"`strong_count` of an `Rc` instance, and an `Rc` instance is only " +"cleaned up if its `strong_count` is 0. You can also create a _weak " +"reference_ to the value within an `Rc` instance by calling `Rc::" +"downgrade` and passing a reference to the `Rc`. Strong references are how " +"you can share ownership of an `Rc` instance. Weak references don’t " +"express an ownership relationship, and their count doesn’t affect when an " +"`Rc` instance is cleaned up. They won’t cause a reference cycle because " +"any cycle involving some weak references will be broken once the strong " +"reference count of values involved is 0." +msgstr "" + +#: src/ch15-06-reference-cycles.md:194 +msgid "" +"When you call `Rc::downgrade`, you get a smart pointer of type `Weak`. " +"Instead of increasing the `strong_count` in the `Rc` instance by 1, " +"calling `Rc::downgrade` increases the `weak_count` by 1. The `Rc` type " +"uses `weak_count` to keep track of how many `Weak` references exist, " +"similar to `strong_count`. The difference is the `weak_count` doesn’t need " +"to be 0 for the `Rc` instance to be cleaned up." +msgstr "" + +#: src/ch15-06-reference-cycles.md:201 +msgid "" +"Because the value that `Weak` references might have been dropped, to do " +"anything with the value that a `Weak` is pointing to, you must make sure " +"the value still exists. Do this by calling the `upgrade` method on a " +"`Weak` instance, which will return an `Option>`. You’ll get a " +"result of `Some` if the `Rc` value has not been dropped yet and a result " +"of `None` if the `Rc` value has been dropped. Because `upgrade` returns " +"an `Option>`, Rust will ensure that the `Some` case and the `None` " +"case are handled, and there won’t be an invalid pointer." +msgstr "" + +#: src/ch15-06-reference-cycles.md:210 +msgid "" +"As an example, rather than using a list whose items know only about the next " +"item, we’ll create a tree whose items know about their children items _and_ " +"their parent items." +msgstr "" + +#: src/ch15-06-reference-cycles.md:214 +msgid "Creating a Tree Data Structure: a `Node` with Child Nodes" +msgstr "" + +#: src/ch15-06-reference-cycles.md:216 +msgid "" +"To start, we’ll build a tree with nodes that know about their child nodes. " +"We’ll create a struct named `Node` that holds its own `i32` value as well as " +"references to its children `Node` values:" +msgstr "" + +#: src/ch15-06-reference-cycles.md:245 +msgid "" +"We want a `Node` to own its children, and we want to share that ownership " +"with variables so we can access each `Node` in the tree directly. To do " +"this, we define the `Vec` items to be values of type `Rc`. We also " +"want to modify which nodes are children of another node, so we have a " +"`RefCell` in `children` around the `Vec>`." +msgstr "" + +#: src/ch15-06-reference-cycles.md:251 +msgid "" +"Next, we’ll use our struct definition and create one `Node` instance named " +"`leaf` with the value 3 and no children, and another instance named `branch` " +"with the value 5 and `leaf` as one of its children, as shown in Listing " +"15-27:" +msgstr "" + +#: src/ch15-06-reference-cycles.md:280 +msgid "" +"Listing 15-27: Creating a `leaf` node with no " +"children and a `branch` node with `leaf` as one of its children" +msgstr "" + +#: src/ch15-06-reference-cycles.md:283 +msgid "" +"We clone the `Rc` in `leaf` and store that in `branch`, meaning the " +"`Node` in `leaf` now has two owners: `leaf` and `branch`. We can get from " +"`branch` to `leaf` through `branch.children`, but there’s no way to get from " +"`leaf` to `branch`. The reason is that `leaf` has no reference to `branch` " +"and doesn’t know they’re related. We want `leaf` to know that `branch` is " +"its parent. We’ll do that next." +msgstr "" + +#: src/ch15-06-reference-cycles.md:290 +msgid "Adding a Reference from a Child to Its Parent" +msgstr "" + +#: src/ch15-06-reference-cycles.md:292 +msgid "" +"To make the child node aware of its parent, we need to add a `parent` field " +"to our `Node` struct definition. The trouble is in deciding what the type of " +"`parent` should be. We know it can’t contain an `Rc`, because that would " +"create a reference cycle with `leaf.parent` pointing to `branch` and `branch." +"children` pointing to `leaf`, which would cause their `strong_count` values " +"to never be 0." +msgstr "" + +#: src/ch15-06-reference-cycles.md:299 +msgid "" +"Thinking about the relationships another way, a parent node should own its " +"children: if a parent node is dropped, its child nodes should be dropped as " +"well. However, a child should not own its parent: if we drop a child node, " +"the parent should still exist. This is a case for weak references!" +msgstr "" + +#: src/ch15-06-reference-cycles.md:304 +msgid "" +"So instead of `Rc`, we’ll make the type of `parent` use `Weak`, " +"specifically a `RefCell>`. Now our `Node` struct definition looks " +"like this:" +msgstr "" + +#: src/ch15-06-reference-cycles.md:328 src/ch15-06-reference-cycles.md:338 +#: src/ch15-06-reference-cycles.md:366 src/ch15-06-reference-cycles.md:376 +#: src/ch15-06-reference-cycles.md:475 +msgid "\"leaf parent = {:?}\"" +msgstr "" + +#: src/ch15-06-reference-cycles.md:342 +msgid "" +"A node will be able to refer to its parent node but doesn’t own its parent. " +"In Listing 15-28, we update `main` to use this new definition so the `leaf` " +"node will have a way to refer to its parent, `branch`:" +msgstr "" + +#: src/ch15-06-reference-cycles.md:380 +msgid "" +"Listing 15-28: A `leaf` node with a weak reference " +"to its parent node `branch`" +msgstr "" + +#: src/ch15-06-reference-cycles.md:383 +msgid "" +"Creating the `leaf` node looks similar to Listing 15-27 with the exception " +"of the `parent` field: `leaf` starts out without a parent, so we create a " +"new, empty `Weak` reference instance." +msgstr "" + +#: src/ch15-06-reference-cycles.md:387 +msgid "" +"At this point, when we try to get a reference to the parent of `leaf` by " +"using the `upgrade` method, we get a `None` value. We see this in the output " +"from the first `println!` statement:" +msgstr "" + +#: src/ch15-06-reference-cycles.md:395 +msgid "" +"When we create the `branch` node, it will also have a new `Weak` " +"reference in the `parent` field, because `branch` doesn’t have a parent " +"node. We still have `leaf` as one of the children of `branch`. Once we have " +"the `Node` instance in `branch`, we can modify `leaf` to give it a " +"`Weak` reference to its parent. We use the `borrow_mut` method on the " +"`RefCell>` in the `parent` field of `leaf`, and then we use the " +"`Rc::downgrade` function to create a `Weak` reference to `branch` from " +"the `Rc` in `branch.`" +msgstr "" + +#: src/ch15-06-reference-cycles.md:404 +msgid "" +"When we print the parent of `leaf` again, this time we’ll get a `Some` " +"variant holding `branch`: now `leaf` can access its parent! When we print " +"`leaf`, we also avoid the cycle that eventually ended in a stack overflow " +"like we had in Listing 15-26; the `Weak` references are printed as " +"`(Weak)`:" +msgstr "" + +#: src/ch15-06-reference-cycles.md:415 +msgid "" +"The lack of infinite output indicates that this code didn’t create a " +"reference cycle. We can also tell this by looking at the values we get from " +"calling `Rc::strong_count` and `Rc::weak_count`." +msgstr "" + +#: src/ch15-06-reference-cycles.md:419 +msgid "Visualizing Changes to `strong_count` and `weak_count`" +msgstr "" + +#: src/ch15-06-reference-cycles.md:421 +msgid "" +"Let’s look at how the `strong_count` and `weak_count` values of the " +"`Rc` instances change by creating a new inner scope and moving the " +"creation of `branch` into that scope. By doing so, we can see what happens " +"when `branch` is created and then dropped when it goes out of scope. The " +"modifications are shown in Listing 15-29:" +msgstr "" + +#: src/ch15-06-reference-cycles.md:448 src/ch15-06-reference-cycles.md:469 +#: src/ch15-06-reference-cycles.md:477 +msgid "\"leaf strong = {}, weak = {}\"" +msgstr "" + +#: src/ch15-06-reference-cycles.md:463 +msgid "\"branch strong = {}, weak = {}\"" +msgstr "" + +#: src/ch15-06-reference-cycles.md:484 +msgid "" +"Listing 15-29: Creating `branch` in an inner scope " +"and examining strong and weak reference counts" +msgstr "" + +#: src/ch15-06-reference-cycles.md:487 +msgid "" +"After `leaf` is created, its `Rc` has a strong count of 1 and a weak " +"count of 0. In the inner scope, we create `branch` and associate it with " +"`leaf`, at which point when we print the counts, the `Rc` in `branch` " +"will have a strong count of 1 and a weak count of 1 (for `leaf.parent` " +"pointing to `branch` with a `Weak`). When we print the counts in " +"`leaf`, we’ll see it will have a strong count of 2, because `branch` now has " +"a clone of the `Rc` of `leaf` stored in `branch.children`, but will " +"still have a weak count of 0." +msgstr "" + +#: src/ch15-06-reference-cycles.md:496 +msgid "" +"When the inner scope ends, `branch` goes out of scope and the strong count " +"of the `Rc` decreases to 0, so its `Node` is dropped. The weak count " +"of 1 from `leaf.parent` has no bearing on whether or not `Node` is dropped, " +"so we don’t get any memory leaks!" +msgstr "" + +#: src/ch15-06-reference-cycles.md:501 +msgid "" +"If we try to access the parent of `leaf` after the end of the scope, we’ll " +"get `None` again. At the end of the program, the `Rc` in `leaf` has a " +"strong count of 1 and a weak count of 0, because the variable `leaf` is now " +"the only reference to the `Rc` again." +msgstr "" + +#: src/ch15-06-reference-cycles.md:506 +msgid "" +"All of the logic that manages the counts and value dropping is built into " +"`Rc` and `Weak` and their implementations of the `Drop` trait. By " +"specifying that the relationship from a child to its parent should be a " +"`Weak` reference in the definition of `Node`, you’re able to have parent " +"nodes point to child nodes and vice versa without creating a reference cycle " +"and memory leaks." +msgstr "" + +#: src/ch15-06-reference-cycles.md:515 +msgid "" +"This chapter covered how to use smart pointers to make different guarantees " +"and trade-offs from those Rust makes by default with regular references. The " +"`Box` type has a known size and points to data allocated on the heap. The " +"`Rc` type keeps track of the number of references to data on the heap so " +"that data can have multiple owners. The `RefCell` type with its interior " +"mutability gives us a type that we can use when we need an immutable type " +"but need to change an inner value of that type; it also enforces the " +"borrowing rules at runtime instead of at compile time." +msgstr "" + +#: src/ch15-06-reference-cycles.md:524 +msgid "" +"Also discussed were the `Deref` and `Drop` traits, which enable a lot of the " +"functionality of smart pointers. We explored reference cycles that can cause " +"memory leaks and how to prevent them using `Weak`." +msgstr "" + +#: src/ch15-06-reference-cycles.md:528 +msgid "" +"If this chapter has piqued your interest and you want to implement your own " +"smart pointers, check out [“The Rustonomicon”](../nomicon/index.html) for " +"more useful information." +msgstr "" + +#: src/ch15-06-reference-cycles.md:532 +msgid "" +"Next, we’ll talk about concurrency in Rust. You’ll even learn about a few " +"new smart pointers." +msgstr "" + +#: src/ch16-00-concurrency.md:3 +msgid "" +"Handling concurrent programming safely and efficiently is another of Rust’s " +"major goals. _Concurrent programming_, where different parts of a program " +"execute independently, and _parallel programming_, where different parts of " +"a program execute at the same time, are becoming increasingly important as " +"more computers take advantage of their multiple processors. Historically, " +"programming in these contexts has been difficult and error prone: Rust hopes " +"to change that." +msgstr "" + +#: src/ch16-00-concurrency.md:11 +msgid "" +"Initially, the Rust team thought that ensuring memory safety and preventing " +"concurrency problems were two separate challenges to be solved with " +"different methods. Over time, the team discovered that the ownership and " +"type systems are a powerful set of tools to help manage memory safety _and_ " +"concurrency problems! By leveraging ownership and type checking, many " +"concurrency errors are compile-time errors in Rust rather than runtime " +"errors. Therefore, rather than making you spend lots of time trying to " +"reproduce the exact circumstances under which a runtime concurrency bug " +"occurs, incorrect code will refuse to compile and present an error " +"explaining the problem. As a result, you can fix your code while you’re " +"working on it rather than potentially after it has been shipped to " +"production. We’ve nicknamed this aspect of Rust _fearless_ _concurrency_. " +"Fearless concurrency allows you to write code that is free of subtle bugs " +"and is easy to refactor without introducing new bugs." +msgstr "" + +#: src/ch16-00-concurrency.md:25 +msgid "" +"Note: For simplicity’s sake, we’ll refer to many of the problems as " +"_concurrent_ rather than being more precise by saying _concurrent and/or " +"parallel_. If this book were about concurrency and/or parallelism, we’d be " +"more specific. For this chapter, please mentally substitute _concurrent and/" +"or parallel_ whenever we use _concurrent_." +msgstr "" + +#: src/ch16-00-concurrency.md:31 +msgid "" +"Many languages are dogmatic about the solutions they offer for handling " +"concurrent problems. For example, Erlang has elegant functionality for " +"message-passing concurrency but has only obscure ways to share state between " +"threads. Supporting only a subset of possible solutions is a reasonable " +"strategy for higher-level languages, because a higher-level language " +"promises benefits from giving up some control to gain abstractions. However, " +"lower-level languages are expected to provide the solution with the best " +"performance in any given situation and have fewer abstractions over the " +"hardware. Therefore, Rust offers a variety of tools for modeling problems in " +"whatever way is appropriate for your situation and requirements." +msgstr "" + +#: src/ch16-00-concurrency.md:42 +msgid "Here are the topics we’ll cover in this chapter:" +msgstr "" + +#: src/ch16-00-concurrency.md:44 +msgid "How to create threads to run multiple pieces of code at the same time" +msgstr "" + +#: src/ch16-00-concurrency.md:45 +msgid "" +"_Message-passing_ concurrency, where channels send messages between threads" +msgstr "" + +#: src/ch16-00-concurrency.md:46 +msgid "" +"_Shared-state_ concurrency, where multiple threads have access to some piece " +"of data" +msgstr "" + +#: src/ch16-00-concurrency.md:48 +msgid "" +"The `Sync` and `Send` traits, which extend Rust’s concurrency guarantees to " +"user-defined types as well as types provided by the standard library" +msgstr "" + +#: src/ch16-01-threads.md:3 +msgid "" +"In most current operating systems, an executed program’s code is run in a " +"_process_, and the operating system will manage multiple processes at once. " +"Within a program, you can also have independent parts that run " +"simultaneously. The features that run these independent parts are called " +"_threads_. For example, a web server could have multiple threads so that it " +"could respond to more than one request at the same time." +msgstr "" + +#: src/ch16-01-threads.md:10 +msgid "" +"Splitting the computation in your program into multiple threads to run " +"multiple tasks at the same time can improve performance, but it also adds " +"complexity. Because threads can run simultaneously, there’s no inherent " +"guarantee about the order in which parts of your code on different threads " +"will run. This can lead to problems, such as:" +msgstr "" + +#: src/ch16-01-threads.md:16 +msgid "" +"Race conditions, where threads are accessing data or resources in an " +"inconsistent order" +msgstr "" + +#: src/ch16-01-threads.md:18 +msgid "" +"Deadlocks, where two threads are waiting for each other, preventing both " +"threads from continuing" +msgstr "" + +#: src/ch16-01-threads.md:20 +msgid "" +"Bugs that happen only in certain situations and are hard to reproduce and " +"fix reliably" +msgstr "" + +#: src/ch16-01-threads.md:23 +msgid "" +"Rust attempts to mitigate the negative effects of using threads, but " +"programming in a multithreaded context still takes careful thought and " +"requires a code structure that is different from that in programs running in " +"a single thread." +msgstr "" + +#: src/ch16-01-threads.md:28 +msgid "" +"Programming languages implement threads in a few different ways, and many " +"operating systems provide an API the language can call for creating new " +"threads. The Rust standard library uses a _1:1_ model of thread " +"implementation, whereby a program uses one operating system thread per one " +"language thread. There are crates that implement other models of threading " +"that make different tradeoffs to the 1:1 model." +msgstr "" + +#: src/ch16-01-threads.md:35 +msgid "Creating a New Thread with `spawn`" +msgstr "" + +#: src/ch16-01-threads.md:37 +msgid "" +"To create a new thread, we call the `thread::spawn` function and pass it a " +"closure (we talked about closures in Chapter 13) containing the code we want " +"to run in the new thread. The example in Listing 16-1 prints some text from " +"a main thread and other text from a new thread:" +msgstr "" + +#: src/ch16-01-threads.md:51 src/ch16-01-threads.md:122 +#: src/ch16-01-threads.md:180 +msgid "\"hi number {i} from the spawned thread!\"" +msgstr "" + +#: src/ch16-01-threads.md:57 src/ch16-01-threads.md:128 +#: src/ch16-01-threads.md:188 +msgid "\"hi number {i} from the main thread!\"" +msgstr "" + +#: src/ch16-01-threads.md:63 +msgid "" +"Listing 16-1: Creating a new thread to print one " +"thing while the main thread prints something else" +msgstr "" + +#: src/ch16-01-threads.md:66 +msgid "" +"Note that when the main thread of a Rust program completes, all spawned " +"threads are shut down, whether or not they have finished running. The output " +"from this program might be a little different every time, but it will look " +"similar to the following:" +msgstr "" + +#: src/ch16-01-threads.md:87 +msgid "" +"The calls to `thread::sleep` force a thread to stop its execution for a " +"short duration, allowing a different thread to run. The threads will " +"probably take turns, but that isn’t guaranteed: it depends on how your " +"operating system schedules the threads. In this run, the main thread printed " +"first, even though the print statement from the spawned thread appears first " +"in the code. And even though we told the spawned thread to print until `i` " +"is 9, it only got to 5 before the main thread shut down." +msgstr "" + +#: src/ch16-01-threads.md:95 +msgid "" +"If you run this code and only see output from the main thread, or don’t see " +"any overlap, try increasing the numbers in the ranges to create more " +"opportunities for the operating system to switch between the threads." +msgstr "" + +#: src/ch16-01-threads.md:99 +msgid "Waiting for All Threads to Finish Using `join` Handles" +msgstr "" + +#: src/ch16-01-threads.md:101 +msgid "" +"The code in Listing 16-1 not only stops the spawned thread prematurely most " +"of the time due to the main thread ending, but because there is no guarantee " +"on the order in which threads run, we also can’t guarantee that the spawned " +"thread will get to run at all!" +msgstr "" + +#: src/ch16-01-threads.md:106 +msgid "" +"We can fix the problem of the spawned thread not running or ending " +"prematurely by saving the return value of `thread::spawn` in a variable. The " +"return type of `thread::spawn` is `JoinHandle`. A `JoinHandle` is an owned " +"value that, when we call the `join` method on it, will wait for its thread " +"to finish. Listing 16-2 shows how to use the `JoinHandle` of the thread we " +"created in Listing 16-1 and call `join` to make sure the spawned thread " +"finishes before `main` exits:" +msgstr "" + +#: src/ch16-01-threads.md:136 +msgid "" +"Listing 16-2: Saving a `JoinHandle` from `thread::" +"spawn` to guarantee the thread is run to completion" +msgstr "" + +#: src/ch16-01-threads.md:139 +msgid "" +"Calling `join` on the handle blocks the thread currently running until the " +"thread represented by the handle terminates. _Blocking_ a thread means that " +"thread is prevented from performing work or exiting. Because we’ve put the " +"call to `join` after the main thread’s `for` loop, running Listing 16-2 " +"should produce output similar to this:" +msgstr "" + +#: src/ch16-01-threads.md:165 +msgid "" +"The two threads continue alternating, but the main thread waits because of " +"the call to `handle.join()` and does not end until the spawned thread is " +"finished." +msgstr "" + +#: src/ch16-01-threads.md:168 +msgid "" +"But let’s see what happens when we instead move `handle.join()` before the " +"`for` loop in `main`, like this:" +msgstr "" + +#: src/ch16-01-threads.md:194 +msgid "" +"The main thread will wait for the spawned thread to finish and then run its " +"`for` loop, so the output won’t be interleaved anymore, as shown here:" +msgstr "" + +#: src/ch16-01-threads.md:217 +msgid "" +"Small details, such as where `join` is called, can affect whether or not " +"your threads run at the same time." +msgstr "" + +#: src/ch16-01-threads.md:220 +msgid "Using `move` Closures with Threads" +msgstr "" + +#: src/ch16-01-threads.md:222 +msgid "" +"We'll often use the `move` keyword with closures passed to `thread::spawn` " +"because the closure will then take ownership of the values it uses from the " +"environment, thus transferring ownership of those values from one thread to " +"another. In the [“Capturing References or Moving Ownership”](ch13-01-" +"closures.html#capturing-references-or-moving-ownership) section of Chapter 13, we discussed `move` in the context of closures. " +"Now, we’ll concentrate more on the interaction between `move` and `thread::" +"spawn`." +msgstr "" + +#: src/ch16-01-threads.md:229 +msgid "" +"Notice in Listing 16-1 that the closure we pass to `thread::spawn` takes no " +"arguments: we’re not using any data from the main thread in the spawned " +"thread’s code. To use data from the main thread in the spawned thread, the " +"spawned thread’s closure must capture the values it needs. Listing 16-3 " +"shows an attempt to create a vector in the main thread and use it in the " +"spawned thread. However, this won’t yet work, as you’ll see in a moment." +msgstr "" + +#: src/ch16-01-threads.md:245 src/ch16-01-threads.md:305 +#: src/ch16-01-threads.md:352 +msgid "\"Here's a vector: {v:?}\"" +msgstr "" + +#: src/ch16-01-threads.md:252 +msgid "" +"Listing 16-3: Attempting to use a vector created by " +"the main thread in another thread" +msgstr "" + +#: src/ch16-01-threads.md:255 +msgid "" +"The closure uses `v`, so it will capture `v` and make it part of the " +"closure’s environment. Because `thread::spawn` runs this closure in a new " +"thread, we should be able to access `v` inside that new thread. But when we " +"compile this example, we get the following error:" +msgstr "" + +#: src/ch16-01-threads.md:260 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling threads v0.1.0 (file:///projects/threads)\n" +"error[E0373]: closure may outlive the current function, but it borrows `v`, " +"which is owned by the current function\n" +" --> src/main.rs:6:32\n" +" |\n" +"6 | let handle = thread::spawn(|| {\n" +" | ^^ may outlive borrowed value `v`\n" +"7 | println!(\"Here's a vector: {v:?}\");\n" +" | - `v` is borrowed here\n" +" |\n" +"note: function requires argument type to outlive `'static`\n" +" --> src/main.rs:6:18\n" +" |\n" +"6 | let handle = thread::spawn(|| {\n" +" | __________________^\n" +"7 | | println!(\"Here's a vector: {v:?}\");\n" +"8 | | });\n" +" | |______^\n" +"help: to force the closure to take ownership of `v` (and any other " +"referenced variables), use the `move` keyword\n" +" |\n" +"6 | let handle = thread::spawn(move || {\n" +" | ++++\n" +"\n" +"For more information about this error, try `rustc --explain E0373`.\n" +"error: could not compile `threads` (bin \"threads\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch16-01-threads.md:288 +msgid "" +"Rust _infers_ how to capture `v`, and because `println!` only needs a " +"reference to `v`, the closure tries to borrow `v`. However, there’s a " +"problem: Rust can’t tell how long the spawned thread will run, so it doesn’t " +"know if the reference to `v` will always be valid." +msgstr "" + +#: src/ch16-01-threads.md:293 +msgid "" +"Listing 16-4 provides a scenario that’s more likely to have a reference to " +"`v` that won’t be valid:" +msgstr "" + +#: src/ch16-01-threads.md:308 +msgid "// oh no!\n" +msgstr "" + +#: src/ch16-01-threads.md:314 +msgid "" +"Listing 16-4: A thread with a closure that attempts " +"to capture a reference to `v` from a main thread that drops `v`" +msgstr "" + +#: src/ch16-01-threads.md:317 +msgid "" +"If Rust allowed us to run this code, there’s a possibility the spawned " +"thread would be immediately put in the background without running at all. " +"The spawned thread has a reference to `v` inside, but the main thread " +"immediately drops `v`, using the `drop` function we discussed in Chapter 15. " +"Then, when the spawned thread starts to execute, `v` is no longer valid, so " +"a reference to it is also invalid. Oh no!" +msgstr "" + +#: src/ch16-01-threads.md:324 +msgid "" +"To fix the compiler error in Listing 16-3, we can use the error message’s " +"advice:" +msgstr "" + +#: src/ch16-01-threads.md:338 +msgid "" +"By adding the `move` keyword before the closure, we force the closure to " +"take ownership of the values it’s using rather than allowing Rust to infer " +"that it should borrow the values. The modification to Listing 16-3 shown in " +"Listing 16-5 will compile and run as we intend:" +msgstr "" + +#: src/ch16-01-threads.md:359 +msgid "" +"Listing 16-5: Using the `move` keyword to force a " +"closure to take ownership of the values it uses" +msgstr "" + +#: src/ch16-01-threads.md:362 +msgid "" +"We might be tempted to try the same thing to fix the code in Listing 16-4 " +"where the main thread called `drop` by using a `move` closure. However, this " +"fix will not work because what Listing 16-4 is trying to do is disallowed " +"for a different reason. If we added `move` to the closure, we would move `v` " +"into the closure’s environment, and we could no longer call `drop` on it in " +"the main thread. We would get this compiler error instead:" +msgstr "" + +#: src/ch16-01-threads.md:369 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling threads v0.1.0 (file:///projects/threads)\n" +"error[E0382]: use of moved value: `v`\n" +" --> src/main.rs:10:10\n" +" |\n" +"4 | let v = vec![1, 2, 3];\n" +" | - move occurs because `v` has type `Vec`, which does not " +"implement the `Copy` trait\n" +"5 |\n" +"6 | let handle = thread::spawn(move || {\n" +" | ------- value moved into closure here\n" +"7 | println!(\"Here's a vector: {v:?}\");\n" +" | - variable moved due to use in " +"closure\n" +"...\n" +"10 | drop(v); // oh no!\n" +" | ^ value used here after move\n" +"\n" +"For more information about this error, try `rustc --explain E0382`.\n" +"error: could not compile `threads` (bin \"threads\") due to 1 previous " +"error\n" +"```" +msgstr "" + +#: src/ch16-01-threads.md:390 +msgid "" +"Rust’s ownership rules have saved us again! We got an error from the code in " +"Listing 16-3 because Rust was being conservative and only borrowing `v` for " +"the thread, which meant the main thread could theoretically invalidate the " +"spawned thread’s reference. By telling Rust to move ownership of `v` to the " +"spawned thread, we’re guaranteeing Rust that the main thread won’t use `v` " +"anymore. If we change Listing 16-4 in the same way, we’re then violating the " +"ownership rules when we try to use `v` in the main thread. The `move` " +"keyword overrides Rust’s conservative default of borrowing; it doesn’t let " +"us violate the ownership rules." +msgstr "" + +#: src/ch16-01-threads.md:400 +msgid "" +"With a basic understanding of threads and the thread API, let’s look at what " +"we can _do_ with threads." +msgstr "" + +#: src/ch16-02-message-passing.md:3 +msgid "" +"One increasingly popular approach to ensuring safe concurrency is _message " +"passing_, where threads or actors communicate by sending each other messages " +"containing data. Here’s the idea in a slogan from [the Go language " +"documentation](https://golang.org/doc/effective_go.html#concurrency): “Do " +"not communicate by sharing memory; instead, share memory by communicating.”" +msgstr "" + +#: src/ch16-02-message-passing.md:9 +msgid "" +"To accomplish message-sending concurrency, Rust's standard library provides " +"an implementation of _channels_. A channel is a general programming concept " +"by which data is sent from one thread to another." +msgstr "" + +#: src/ch16-02-message-passing.md:13 +msgid "" +"You can imagine a channel in programming as being like a directional channel " +"of water, such as a stream or a river. If you put something like a rubber " +"duck into a river, it will travel downstream to the end of the waterway." +msgstr "" + +#: src/ch16-02-message-passing.md:17 +msgid "" +"A channel has two halves: a transmitter and a receiver. The transmitter half " +"is the upstream location where you put rubber ducks into the river, and the " +"receiver half is where the rubber duck ends up downstream. One part of your " +"code calls methods on the transmitter with the data you want to send, and " +"another part checks the receiving end for arriving messages. A channel is " +"said to be _closed_ if either the transmitter or receiver half is dropped." +msgstr "" + +#: src/ch16-02-message-passing.md:24 +msgid "" +"Here, we’ll work up to a program that has one thread to generate values and " +"send them down a channel, and another thread that will receive the values " +"and print them out. We’ll be sending simple values between threads using a " +"channel to illustrate the feature. Once you’re familiar with the technique, " +"you could use channels for any threads that need to communicate between each " +"other, such as a chat system or a system where many threads perform parts of " +"a calculation and send the parts to one thread that aggregates the results." +msgstr "" + +#: src/ch16-02-message-passing.md:32 +msgid "" +"First, in Listing 16-6, we’ll create a channel but not do anything with it. " +"Note that this won’t compile yet because Rust can’t tell what type of values " +"we want to send over the channel." +msgstr "" + +#: src/ch16-02-message-passing.md:46 +msgid "" +"Listing 16-6: Creating a channel and assigning the " +"two halves to `tx` and `rx`" +msgstr "" + +#: src/ch16-02-message-passing.md:49 +msgid "" +"We create a new channel using the `mpsc::channel` function; `mpsc` stands " +"for _multiple producer, single consumer_. In short, the way Rust’s standard " +"library implements channels means a channel can have multiple _sending_ ends " +"that produce values but only one _receiving_ end that consumes those values. " +"Imagine multiple streams flowing together into one big river: everything " +"sent down any of the streams will end up in one river at the end. We’ll " +"start with a single producer for now, but we’ll add multiple producers when " +"we get this example working." +msgstr "" + +#: src/ch16-02-message-passing.md:58 +msgid "" +"The `mpsc::channel` function returns a tuple, the first element of which is " +"the sending end—the transmitter—and the second element is the receiving end—" +"the receiver. The abbreviations `tx` and `rx` are traditionally used in many " +"fields for _transmitter_ and _receiver_ respectively, so we name our " +"variables as such to indicate each end. We’re using a `let` statement with a " +"pattern that destructures the tuples; we’ll discuss the use of patterns in " +"`let` statements and destructuring in Chapter 18. For now, know that using a " +"`let` statement this way is a convenient approach to extract the pieces of " +"the tuple returned by `mpsc::channel`." +msgstr "" + +#: src/ch16-02-message-passing.md:68 +msgid "" +"Let’s move the transmitting end into a spawned thread and have it send one " +"string so the spawned thread is communicating with the main thread, as shown " +"in Listing 16-7. This is like putting a rubber duck in the river upstream or " +"sending a chat message from one thread to another." +msgstr "" + +#: src/ch16-02-message-passing.md:83 src/ch16-02-message-passing.md:116 +#: src/ch16-02-message-passing.md:179 src/ch16-02-message-passing.md:243 +#: src/ch16-02-message-passing.md:313 src/ch19-04-advanced-types.md:92 +#: src/ch19-04-advanced-types.md:115 +msgid "\"hi\"" +msgstr "" + +#: src/ch16-02-message-passing.md:89 +msgid "" +"Listing 16-7: Moving `tx` to a spawned thread and " +"sending “hi”" +msgstr "" + +#: src/ch16-02-message-passing.md:92 +msgid "" +"Again, we’re using `thread::spawn` to create a new thread and then using " +"`move` to move `tx` into the closure so the spawned thread owns `tx`. The " +"spawned thread needs to own the transmitter to be able to send messages " +"through the channel. The transmitter has a `send` method that takes the " +"value we want to send. The `send` method returns a `Result` type, so " +"if the receiver has already been dropped and there’s nowhere to send a " +"value, the send operation will return an error. In this example, we’re " +"calling `unwrap` to panic in case of an error. But in a real application, we " +"would handle it properly: return to Chapter 9 to review strategies for " +"proper error handling." +msgstr "" + +#: src/ch16-02-message-passing.md:102 +msgid "" +"In Listing 16-8, we’ll get the value from the receiver in the main thread. " +"This is like retrieving the rubber duck from the water at the end of the " +"river or receiving a chat message." +msgstr "" + +#: src/ch16-02-message-passing.md:121 src/ch16-02-message-passing.md:185 +#: src/ch16-02-message-passing.md:256 src/ch16-02-message-passing.md:340 +msgid "\"Got: {received}\"" +msgstr "" + +#: src/ch16-02-message-passing.md:125 +msgid "" +"Listing 16-8: Receiving the value “hi” in the main " +"thread and printing it" +msgstr "" + +#: src/ch16-02-message-passing.md:128 +msgid "" +"The receiver has two useful methods: `recv` and `try_recv`. We’re using " +"`recv`, short for _receive_, which will block the main thread’s execution " +"and wait until a value is sent down the channel. Once a value is sent, " +"`recv` will return it in a `Result`. When the transmitter closes, " +"`recv` will return an error to signal that no more values will be coming." +msgstr "" + +#: src/ch16-02-message-passing.md:134 +msgid "" +"The `try_recv` method doesn’t block, but will instead return a `Result` immediately: an `Ok` value holding a message if one is available and an " +"`Err` value if there aren’t any messages this time. Using `try_recv` is " +"useful if this thread has other work to do while waiting for messages: we " +"could write a loop that calls `try_recv` every so often, handles a message " +"if one is available, and otherwise does other work for a little while until " +"checking again." +msgstr "" + +#: src/ch16-02-message-passing.md:142 +msgid "" +"We’ve used `recv` in this example for simplicity; we don’t have any other " +"work for the main thread to do other than wait for messages, so blocking the " +"main thread is appropriate." +msgstr "" + +#: src/ch16-02-message-passing.md:146 +msgid "" +"When we run the code in Listing 16-8, we’ll see the value printed from the " +"main thread:" +msgstr "" + +#: src/ch16-02-message-passing.md:157 +msgid "Perfect!" +msgstr "" + +#: src/ch16-02-message-passing.md:159 +msgid "Channels and Ownership Transference" +msgstr "" + +#: src/ch16-02-message-passing.md:161 +msgid "" +"The ownership rules play a vital role in message sending because they help " +"you write safe, concurrent code. Preventing errors in concurrent programming " +"is the advantage of thinking about ownership throughout your Rust programs. " +"Let’s do an experiment to show how channels and ownership work together to " +"prevent problems: we’ll try to use a `val` value in the spawned thread " +"_after_ we’ve sent it down the channel. Try compiling the code in Listing " +"16-9 to see why this code isn’t allowed:" +msgstr "" + +#: src/ch16-02-message-passing.md:181 +msgid "\"val is {val}\"" +msgstr "" + +#: src/ch16-02-message-passing.md:189 +msgid "" +"Listing 16-9: Attempting to use `val` after we’ve " +"sent it down the channel" +msgstr "" + +#: src/ch16-02-message-passing.md:192 +msgid "" +"Here, we try to print `val` after we’ve sent it down the channel via `tx." +"send`. Allowing this would be a bad idea: once the value has been sent to " +"another thread, that thread could modify or drop it before we try to use the " +"value again. Potentially, the other thread’s modifications could cause " +"errors or unexpected results due to inconsistent or nonexistent data. " +"However, Rust gives us an error if we try to compile the code in Listing " +"16-9:" +msgstr "" + +#: src/ch16-02-message-passing.md:199 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling message-passing v0.1.0 (file:///projects/message-passing)\n" +"error[E0382]: borrow of moved value: `val`\n" +" --> src/main.rs:10:26\n" +" |\n" +"8 | let val = String::from(\"hi\");\n" +" | --- move occurs because `val` has type `String`, which does " +"not implement the `Copy` trait\n" +"9 | tx.send(val).unwrap();\n" +" | --- value moved here\n" +"10 | println!(\"val is {val}\");\n" +" | ^^^^^ value borrowed here after move\n" +" |\n" +" = note: this error originates in the macro `$crate::format_args_nl` which " +"comes from the expansion of the macro `println` (in Nightly builds, run with " +"-Z macro-backtrace for more info)\n" +"\n" +"For more information about this error, try `rustc --explain E0382`.\n" +"error: could not compile `message-passing` (bin \"message-passing\") due to " +"1 previous error\n" +"```" +msgstr "" + +#: src/ch16-02-message-passing.md:218 +msgid "" +"Our concurrency mistake has caused a compile time error. The `send` function " +"takes ownership of its parameter, and when the value is moved, the receiver " +"takes ownership of it. This stops us from accidentally using the value again " +"after sending it; the ownership system checks that everything is okay." +msgstr "" + +#: src/ch16-02-message-passing.md:223 +msgid "Sending Multiple Values and Seeing the Receiver Waiting" +msgstr "" + +#: src/ch16-02-message-passing.md:225 +msgid "" +"The code in Listing 16-8 compiled and ran, but it didn’t clearly show us " +"that two separate threads were talking to each other over the channel. In " +"Listing 16-10 we’ve made some modifications that will prove the code in " +"Listing 16-8 is running concurrently: the spawned thread will now send " +"multiple messages and pause for a second between each message." +msgstr "" + +#: src/ch16-02-message-passing.md:244 src/ch16-02-message-passing.md:314 +msgid "\"from\"" +msgstr "" + +#: src/ch16-02-message-passing.md:245 src/ch16-02-message-passing.md:315 +msgid "\"the\"" +msgstr "" + +#: src/ch16-02-message-passing.md:246 src/ch16-02-message-passing.md:316 +msgid "\"thread\"" +msgstr "" + +#: src/ch16-02-message-passing.md:261 +msgid "" +"Listing 16-10: Sending multiple messages and pausing " +"between each" +msgstr "" + +#: src/ch16-02-message-passing.md:264 +msgid "" +"This time, the spawned thread has a vector of strings that we want to send " +"to the main thread. We iterate over them, sending each individually, and " +"pause between each by calling the `thread::sleep` function with a `Duration` " +"value of 1 second." +msgstr "" + +#: src/ch16-02-message-passing.md:269 +msgid "" +"In the main thread, we’re not calling the `recv` function explicitly " +"anymore: instead, we’re treating `rx` as an iterator. For each value " +"received, we’re printing it. When the channel is closed, iteration will end." +msgstr "" + +#: src/ch16-02-message-passing.md:273 +msgid "" +"When running the code in Listing 16-10, you should see the following output " +"with a 1-second pause in between each line:" +msgstr "" + +#: src/ch16-02-message-passing.md:287 +msgid "" +"Because we don’t have any code that pauses or delays in the `for` loop in " +"the main thread, we can tell that the main thread is waiting to receive " +"values from the spawned thread." +msgstr "" + +#: src/ch16-02-message-passing.md:291 +msgid "Creating Multiple Producers by Cloning the Transmitter" +msgstr "" + +#: src/ch16-02-message-passing.md:293 +msgid "" +"Earlier we mentioned that `mpsc` was an acronym for _multiple producer, " +"single consumer_. Let’s put `mpsc` to use and expand the code in Listing " +"16-10 to create multiple threads that all send values to the same receiver. " +"We can do so by cloning the transmitter, as shown in Listing 16-11:" +msgstr "" + +#: src/ch16-02-message-passing.md:327 +msgid "\"more\"" +msgstr "" + +#: src/ch16-02-message-passing.md:328 +msgid "\"messages\"" +msgstr "" + +#: src/ch16-02-message-passing.md:329 +msgid "\"for\"" +msgstr "" + +#: src/ch16-02-message-passing.md:330 +msgid "\"you\"" +msgstr "" + +#: src/ch16-02-message-passing.md:347 +msgid "" +"Listing 16-11: Sending multiple messages from " +"multiple producers" +msgstr "" + +#: src/ch16-02-message-passing.md:350 +msgid "" +"This time, before we create the first spawned thread, we call `clone` on the " +"transmitter. This will give us a new transmitter we can pass to the first " +"spawned thread. We pass the original transmitter to a second spawned thread. " +"This gives us two threads, each sending different messages to the one " +"receiver." +msgstr "" + +#: src/ch16-02-message-passing.md:355 +msgid "When you run the code, your output should look something like this:" +msgstr "" + +#: src/ch16-02-message-passing.md:372 +msgid "" +"You might see the values in another order, depending on your system. This is " +"what makes concurrency interesting as well as difficult. If you experiment " +"with `thread::sleep`, giving it various values in the different threads, " +"each run will be more nondeterministic and create different output each time." +msgstr "" + +#: src/ch16-02-message-passing.md:377 +msgid "" +"Now that we’ve looked at how channels work, let’s look at a different method " +"of concurrency." +msgstr "" + +#: src/ch16-03-shared-state.md:3 +msgid "" +"Message passing is a fine way of handling concurrency, but it’s not the only " +"one. Another method would be for multiple threads to access the same shared " +"data. Consider this part of the slogan from the Go language documentation " +"again: “do not communicate by sharing memory.”" +msgstr "" + +#: src/ch16-03-shared-state.md:8 +msgid "" +"What would communicating by sharing memory look like? In addition, why would " +"message-passing enthusiasts caution not to use memory sharing?" +msgstr "" + +#: src/ch16-03-shared-state.md:11 +msgid "" +"In a way, channels in any programming language are similar to single " +"ownership, because once you transfer a value down a channel, you should no " +"longer use that value. Shared memory concurrency is like multiple ownership: " +"multiple threads can access the same memory location at the same time. As " +"you saw in Chapter 15, where smart pointers made multiple ownership " +"possible, multiple ownership can add complexity because these different " +"owners need managing. Rust’s type system and ownership rules greatly assist " +"in getting this management correct. For an example, let’s look at mutexes, " +"one of the more common concurrency primitives for shared memory." +msgstr "" + +#: src/ch16-03-shared-state.md:21 +msgid "Using Mutexes to Allow Access to Data from One Thread at a Time" +msgstr "" + +#: src/ch16-03-shared-state.md:23 +msgid "" +"_Mutex_ is an abbreviation for _mutual exclusion_, as in, a mutex allows " +"only one thread to access some data at any given time. To access the data in " +"a mutex, a thread must first signal that it wants access by asking to " +"acquire the mutex’s _lock_. The lock is a data structure that is part of the " +"mutex that keeps track of who currently has exclusive access to the data. " +"Therefore, the mutex is described as _guarding_ the data it holds via the " +"locking system." +msgstr "" + +#: src/ch16-03-shared-state.md:30 +msgid "" +"Mutexes have a reputation for being difficult to use because you have to " +"remember two rules:" +msgstr "" + +#: src/ch16-03-shared-state.md:33 +msgid "You must attempt to acquire the lock before using the data." +msgstr "" + +#: src/ch16-03-shared-state.md:34 +msgid "" +"When you’re done with the data that the mutex guards, you must unlock the " +"data so other threads can acquire the lock." +msgstr "" + +#: src/ch16-03-shared-state.md:37 +msgid "" +"For a real-world metaphor for a mutex, imagine a panel discussion at a " +"conference with only one microphone. Before a panelist can speak, they have " +"to ask or signal that they want to use the microphone. When they get the " +"microphone, they can talk for as long as they want to and then hand the " +"microphone to the next panelist who requests to speak. If a panelist forgets " +"to hand the microphone off when they’re finished with it, no one else is " +"able to speak. If management of the shared microphone goes wrong, the panel " +"won’t work as planned!" +msgstr "" + +#: src/ch16-03-shared-state.md:46 +msgid "" +"Management of mutexes can be incredibly tricky to get right, which is why so " +"many people are enthusiastic about channels. However, thanks to Rust’s type " +"system and ownership rules, you can’t get locking and unlocking wrong." +msgstr "" + +#: src/ch16-03-shared-state.md:50 +msgid "The API of `Mutex`" +msgstr "" + +#: src/ch16-03-shared-state.md:52 +msgid "" +"As an example of how to use a mutex, let’s start by using a mutex in a " +"single-threaded context, as shown in Listing 16-12:" +msgstr "" + +#: src/ch16-03-shared-state.md:68 +msgid "\"m = {m:?}\"" +msgstr "" + +#: src/ch16-03-shared-state.md:72 +msgid "" +"Listing 16-12: Exploring the API of `Mutex` in a " +"single-threaded context for simplicity" +msgstr "" + +#: src/ch16-03-shared-state.md:75 +msgid "" +"As with many types, we create a `Mutex` using the associated function " +"`new`. To access the data inside the mutex, we use the `lock` method to " +"acquire the lock. This call will block the current thread so it can’t do any " +"work until it’s our turn to have the lock." +msgstr "" + +#: src/ch16-03-shared-state.md:80 +msgid "" +"The call to `lock` would fail if another thread holding the lock panicked. " +"In that case, no one would ever be able to get the lock, so we’ve chosen to " +"`unwrap` and have this thread panic if we’re in that situation." +msgstr "" + +#: src/ch16-03-shared-state.md:84 +msgid "" +"After we’ve acquired the lock, we can treat the return value, named `num` in " +"this case, as a mutable reference to the data inside. The type system " +"ensures that we acquire a lock before using the value in `m`. The type of " +"`m` is `Mutex`, not `i32`, so we _must_ call `lock` to be able to use " +"the `i32` value. We can’t forget; the type system won’t let us access the " +"inner `i32` otherwise." +msgstr "" + +#: src/ch16-03-shared-state.md:91 +msgid "" +"As you might suspect, `Mutex` is a smart pointer. More accurately, the " +"call to `lock` _returns_ a smart pointer called `MutexGuard`, wrapped in a " +"`LockResult` that we handled with the call to `unwrap`. The `MutexGuard` " +"smart pointer implements `Deref` to point at our inner data; the smart " +"pointer also has a `Drop` implementation that releases the lock " +"automatically when a `MutexGuard` goes out of scope, which happens at the " +"end of the inner scope. As a result, we don’t risk forgetting to release the " +"lock and blocking the mutex from being used by other threads, because the " +"lock release happens automatically." +msgstr "" + +#: src/ch16-03-shared-state.md:101 +msgid "" +"After dropping the lock, we can print the mutex value and see that we were " +"able to change the inner `i32` to 6." +msgstr "" + +#: src/ch16-03-shared-state.md:104 +msgid "Sharing a `Mutex` Between Multiple Threads" +msgstr "" + +#: src/ch16-03-shared-state.md:106 +msgid "" +"Now, let’s try to share a value between multiple threads using `Mutex`. " +"We’ll spin up 10 threads and have them each increment a counter value by 1, " +"so the counter goes from 0 to 10. The next example in Listing 16-13 will " +"have a compiler error, and we’ll use that error to learn more about using " +"`Mutex` and how Rust helps us use it correctly." +msgstr "" + +#: src/ch16-03-shared-state.md:135 src/ch16-03-shared-state.md:223 +#: src/ch16-03-shared-state.md:325 +msgid "\"Result: {}\"" +msgstr "" + +#: src/ch16-03-shared-state.md:139 +msgid "" +"Listing 16-13: Ten threads each increment a counter " +"guarded by a `Mutex`" +msgstr "" + +#: src/ch16-03-shared-state.md:142 +msgid "" +"We create a `counter` variable to hold an `i32` inside a `Mutex`, as we " +"did in Listing 16-12. Next, we create 10 threads by iterating over a range " +"of numbers. We use `thread::spawn` and give all the threads the same " +"closure: one that moves the counter into the thread, acquires a lock on the " +"`Mutex` by calling the `lock` method, and then adds 1 to the value in the " +"mutex. When a thread finishes running its closure, `num` will go out of " +"scope and release the lock so another thread can acquire it." +msgstr "" + +#: src/ch16-03-shared-state.md:150 +msgid "" +"In the main thread, we collect all the join handles. Then, as we did in " +"Listing 16-2, we call `join` on each handle to make sure all the threads " +"finish. At that point, the main thread will acquire the lock and print the " +"result of this program." +msgstr "" + +#: src/ch16-03-shared-state.md:155 +msgid "We hinted that this example wouldn’t compile. Now let’s find out why!" +msgstr "" + +#: src/ch16-03-shared-state.md:157 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling shared-state v0.1.0 (file:///projects/shared-state)\n" +"error[E0382]: borrow of moved value: `counter`\n" +" --> src/main.rs:21:29\n" +" |\n" +"5 | let counter = Mutex::new(0);\n" +" | ------- move occurs because `counter` has type `Mutex`, " +"which does not implement the `Copy` trait\n" +"...\n" +"8 | for _ in 0..10 {\n" +" | -------------- inside of this loop\n" +"9 | let handle = thread::spawn(move || {\n" +" | ------- value moved into closure " +"here, in previous iteration of loop\n" +"...\n" +"21 | println!(\"Result: {}\", *counter.lock().unwrap());\n" +" | ^^^^^^^ value borrowed here after move\n" +" |\n" +"help: consider moving the expression out of the loop so it is only moved " +"once\n" +" |\n" +"8 ~ let mut value = counter.lock();\n" +"9 ~ for _ in 0..10 {\n" +"10 | let handle = thread::spawn(move || {\n" +"11 ~ let mut num = value.unwrap();\n" +" |\n" +"\n" +"For more information about this error, try `rustc --explain E0382`.\n" +"error: could not compile `shared-state` (bin \"shared-state\") due to 1 " +"previous error\n" +"```" +msgstr "" + +#: src/ch16-03-shared-state.md:186 +msgid "" +"The error message states that the `counter` value was moved in the previous " +"iteration of the loop. Rust is telling us that we can’t move the ownership " +"of `counter` into multiple threads. Let’s fix the compiler error with a " +"multiple-ownership method we discussed in Chapter 15." +msgstr "" + +#: src/ch16-03-shared-state.md:191 +msgid "Multiple Ownership with Multiple Threads" +msgstr "" + +#: src/ch16-03-shared-state.md:193 +msgid "" +"In Chapter 15, we gave a value multiple owners by using the smart pointer " +"`Rc` to create a reference counted value. Let’s do the same here and see " +"what happens. We’ll wrap the `Mutex` in `Rc` in Listing 16-14 and " +"clone the `Rc` before moving ownership to the thread." +msgstr "" + +#: src/ch16-03-shared-state.md:227 +msgid "" +"Listing 16-14: Attempting to use `Rc` to allow " +"multiple threads to own the `Mutex`" +msgstr "" + +#: src/ch16-03-shared-state.md:230 +msgid "" +"Once again, we compile and get... different errors! The compiler is teaching " +"us a lot." +msgstr "" + +#: src/ch16-03-shared-state.md:233 +msgid "" +"```console\n" +"$ cargo run\n" +" Compiling shared-state v0.1.0 (file:///projects/shared-state)\n" +"error[E0277]: `Rc>` cannot be sent between threads safely\n" +" --> src/main.rs:11:36\n" +" |\n" +"11 | let handle = thread::spawn(move || {\n" +" | ------------- ^------\n" +" | | |\n" +" | ______________________|_____________within this `{closure@src/main." +"rs:11:36: 11:43}`\n" +" | | |\n" +" | | required by a bound introduced by this call\n" +"12 | | let mut num = counter.lock().unwrap();\n" +"13 | |\n" +"14 | | *num += 1;\n" +"15 | | });\n" +" | |_________^ `Rc>` cannot be sent between threads safely\n" +" |\n" +" = help: within `{closure@src/main.rs:11:36: 11:43}`, the trait `Send` is " +"not implemented for `Rc>`, which is required by `{closure@src/" +"main.rs:11:36: 11:43}: Send`\n" +"note: required because it's used within this closure\n" +" --> src/main.rs:11:36\n" +" |\n" +"11 | let handle = thread::spawn(move || {\n" +" | ^^^^^^^\n" +"note: required by a bound in `spawn`\n" +" --> /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/thread/" +"mod.rs:691:1\n" +"\n" +"For more information about this error, try `rustc --explain E0277`.\n" +"error: could not compile `shared-state` (bin \"shared-state\") due to 1 " +"previous error\n" +"```" +msgstr "" + +#: src/ch16-03-shared-state.md:264 +msgid "" +"Wow, that error message is very wordy! Here’s the important part to focus " +"on: `` `Rc>` cannot be sent between threads safely ``. The " +"compiler is also telling us the reason why: ``the trait `Send` is not " +"implemented for `Rc>` ``. We’ll talk about `Send` in the next " +"section: it’s one of the traits that ensures the types we use with threads " +"are meant for use in concurrent situations." +msgstr "" + +#: src/ch16-03-shared-state.md:271 +msgid "" +"Unfortunately, `Rc` is not safe to share across threads. When `Rc` " +"manages the reference count, it adds to the count for each call to `clone` " +"and subtracts from the count when each clone is dropped. But it doesn’t use " +"any concurrency primitives to make sure that changes to the count can’t be " +"interrupted by another thread. This could lead to wrong counts—subtle bugs " +"that could in turn lead to memory leaks or a value being dropped before " +"we’re done with it. What we need is a type exactly like `Rc` but one that " +"makes changes to the reference count in a thread-safe way." +msgstr "" + +#: src/ch16-03-shared-state.md:280 +msgid "Atomic Reference Counting with `Arc`" +msgstr "" + +#: src/ch16-03-shared-state.md:282 +msgid "" +"Fortunately, `Arc` _is_ a type like `Rc` that is safe to use in " +"concurrent situations. The _a_ stands for _atomic_, meaning it’s an " +"_atomically reference counted_ type. Atomics are an additional kind of " +"concurrency primitive that we won’t cover in detail here: see the standard " +"library documentation for [`std::sync::atomic`](../std/sync/atomic/index." +"html) for more details. At this point, you just need to know " +"that atomics work like primitive types but are safe to share across threads." +msgstr "" + +#: src/ch16-03-shared-state.md:290 +msgid "" +"You might then wonder why all primitive types aren’t atomic and why standard " +"library types aren’t implemented to use `Arc` by default. The reason is " +"that thread safety comes with a performance penalty that you only want to " +"pay when you really need to. If you’re just performing operations on values " +"within a single thread, your code can run faster if it doesn’t have to " +"enforce the guarantees atomics provide." +msgstr "" + +#: src/ch16-03-shared-state.md:297 +msgid "" +"Let’s return to our example: `Arc` and `Rc` have the same API, so we " +"fix our program by changing the `use` line, the call to `new`, and the call " +"to `clone`. The code in Listing 16-15 will finally compile and run:" +msgstr "" + +#: src/ch16-03-shared-state.md:329 +msgid "" +"Listing 16-15: Using an `Arc` to wrap the " +"`Mutex` to be able to share ownership across multiple threads" +msgstr "" + +#: src/ch16-03-shared-state.md:342 +msgid "" +"We did it! We counted from 0 to 10, which may not seem very impressive, but " +"it did teach us a lot about `Mutex` and thread safety. You could also use " +"this program’s structure to do more complicated operations than just " +"incrementing a counter. Using this strategy, you can divide a calculation " +"into independent parts, split those parts across threads, and then use a " +"`Mutex` to have each thread update the final result with its part." +msgstr "" + +#: src/ch16-03-shared-state.md:349 +msgid "" +"Note that if you are doing simple numerical operations, there are types " +"simpler than `Mutex` types provided by the [`std::sync::atomic` module of " +"the standard library](../std/sync/atomic/index.html). These " +"types provide safe, concurrent, atomic access to primitive types. We chose " +"to use `Mutex` with a primitive type for this example so we could " +"concentrate on how `Mutex` works." +msgstr "" + +#: src/ch16-03-shared-state.md:355 +msgid "Similarities Between `RefCell`/`Rc` and `Mutex`/`Arc`" +msgstr "" + +#: src/ch16-03-shared-state.md:357 +msgid "" +"You might have noticed that `counter` is immutable but we could get a " +"mutable reference to the value inside it; this means `Mutex` provides " +"interior mutability, as the `Cell` family does. In the same way we used " +"`RefCell` in Chapter 15 to allow us to mutate contents inside an `Rc`, " +"we use `Mutex` to mutate contents inside an `Arc`." +msgstr "" + +#: src/ch16-03-shared-state.md:363 +msgid "" +"Another detail to note is that Rust can’t protect you from all kinds of " +"logic errors when you use `Mutex`. Recall in Chapter 15 that using " +"`Rc` came with the risk of creating reference cycles, where two `Rc` " +"values refer to each other, causing memory leaks. Similarly, `Mutex` " +"comes with the risk of creating _deadlocks_. These occur when an operation " +"needs to lock two resources and two threads have each acquired one of the " +"locks, causing them to wait for each other forever. If you’re interested in " +"deadlocks, try creating a Rust program that has a deadlock; then research " +"deadlock mitigation strategies for mutexes in any language and have a go at " +"implementing them in Rust. The standard library API documentation for " +"`Mutex` and `MutexGuard` offers useful information." +msgstr "" + +#: src/ch16-03-shared-state.md:375 +msgid "" +"We’ll round out this chapter by talking about the `Send` and `Sync` traits " +"and how we can use them with custom types." +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:3 +msgid "" +"Interestingly, the Rust language has _very_ few concurrency features. Almost " +"every concurrency feature we’ve talked about so far in this chapter has been " +"part of the standard library, not the language. Your options for handling " +"concurrency are not limited to the language or the standard library; you can " +"write your own concurrency features or use those written by others." +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:9 +msgid "" +"However, two concurrency concepts are embedded in the language: the `std::" +"marker` traits `Sync` and `Send`." +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:12 +msgid "Allowing Transference of Ownership Between Threads with `Send`" +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:14 +msgid "" +"The `Send` marker trait indicates that ownership of values of the type " +"implementing `Send` can be transferred between threads. Almost every Rust " +"type is `Send`, but there are some exceptions, including `Rc`: this " +"cannot be `Send` because if you cloned an `Rc` value and tried to " +"transfer ownership of the clone to another thread, both threads might update " +"the reference count at the same time. For this reason, `Rc` is " +"implemented for use in single-threaded situations where you don’t want to " +"pay the thread-safe performance penalty." +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:23 +msgid "" +"Therefore, Rust’s type system and trait bounds ensure that you can never " +"accidentally send an `Rc` value across threads unsafely. When we tried to " +"do this in Listing 16-14, we got the error `the trait Send is not " +"implemented for Rc>`. When we switched to `Arc`, which is " +"`Send`, the code compiled." +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:29 +msgid "" +"Any type composed entirely of `Send` types is automatically marked as `Send` " +"as well. Almost all primitive types are `Send`, aside from raw pointers, " +"which we’ll discuss in Chapter 19." +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:33 +msgid "Allowing Access from Multiple Threads with `Sync`" +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:35 +msgid "" +"The `Sync` marker trait indicates that it is safe for the type implementing " +"`Sync` to be referenced from multiple threads. In other words, any type `T` " +"is `Sync` if `&T` (an immutable reference to `T`) is `Send`, meaning the " +"reference can be sent safely to another thread. Similar to `Send`, primitive " +"types are `Sync`, and types composed entirely of types that are `Sync` are " +"also `Sync`." +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:41 +msgid "" +"The smart pointer `Rc` is also not `Sync` for the same reasons that it’s " +"not `Send`. The `RefCell` type (which we talked about in Chapter 15) and " +"the family of related `Cell` types are not `Sync`. The implementation of " +"borrow checking that `RefCell` does at runtime is not thread-safe. The " +"smart pointer `Mutex` is `Sync` and can be used to share access with " +"multiple threads as you saw in the [“Sharing a `Mutex` Between Multiple " +"Threads”](ch16-03-shared-state.html#sharing-a-mutext-between-multiple-" +"threads) section." +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:49 +msgid "Implementing `Send` and `Sync` Manually Is Unsafe" +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:51 +msgid "" +"Because types that are made up of `Send` and `Sync` traits are automatically " +"also `Send` and `Sync`, we don’t have to implement those traits manually. As " +"marker traits, they don’t even have any methods to implement. They’re just " +"useful for enforcing invariants related to concurrency." +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:56 +msgid "" +"Manually implementing these traits involves implementing unsafe Rust code. " +"We’ll talk about using unsafe Rust code in Chapter 19; for now, the " +"important information is that building new concurrent types not made up of " +"`Send` and `Sync` parts requires careful thought to uphold the safety " +"guarantees. [“The Rustonomicon”](../nomicon/index.html) has more information " +"about these guarantees and how to uphold them." +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:65 +msgid "" +"This isn’t the last you’ll see of concurrency in this book: the project in " +"Chapter 20 will use the concepts in this chapter in a more realistic " +"situation than the smaller examples discussed here." +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:69 +msgid "" +"As mentioned earlier, because very little of how Rust handles concurrency is " +"part of the language, many concurrency solutions are implemented as crates. " +"These evolve more quickly than the standard library, so be sure to search " +"online for the current, state-of-the-art crates to use in multithreaded " +"situations." +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:75 +msgid "" +"The Rust standard library provides channels for message passing and smart " +"pointer types, such as `Mutex` and `Arc`, that are safe to use in " +"concurrent contexts. The type system and the borrow checker ensure that the " +"code using these solutions won’t end up with data races or invalid " +"references. Once you get your code to compile, you can rest assured that it " +"will happily run on multiple threads without the kinds of hard-to-track-down " +"bugs common in other languages. Concurrent programming is no longer a " +"concept to be afraid of: go forth and make your programs concurrent, " +"fearlessly!" +msgstr "" + +#: src/ch16-04-extensible-concurrency-sync-and-send.md:84 +msgid "" +"Next, we’ll talk about idiomatic ways to model problems and structure " +"solutions as your Rust programs get bigger. In addition, we’ll discuss how " +"Rust’s idioms relate to those you might be familiar with from object-" +"oriented programming." +msgstr "" + +#: src/ch17-00-oop.md:1 +msgid "Object-Oriented Programming Features of Rust" +msgstr "" + +#: src/ch17-00-oop.md:3 +msgid "" +"Object-oriented programming (OOP) is a way of modeling programs. Objects as " +"a programmatic concept were introduced in the programming language Simula in " +"the 1960s. Those objects influenced Alan Kay’s programming architecture in " +"which objects pass messages to each other. To describe this architecture, he " +"coined the term _object-oriented programming_ in 1967. Many competing " +"definitions describe what OOP is, and by some of these definitions Rust is " +"object-oriented, but by others it is not. In this chapter, we’ll explore " +"certain characteristics that are commonly considered object-oriented and how " +"those characteristics translate to idiomatic Rust. We’ll then show you how " +"to implement an object-oriented design pattern in Rust and discuss the trade-" +"offs of doing so versus implementing a solution using some of Rust’s " +"strengths instead." +msgstr "" + +#: src/ch17-01-what-is-oo.md:3 +msgid "" +"There is no consensus in the programming community about what features a " +"language must have to be considered object-oriented. Rust is influenced by " +"many programming paradigms, including OOP; for example, we explored the " +"features that came from functional programming in Chapter 13. Arguably, OOP " +"languages share certain common characteristics, namely objects, " +"encapsulation, and inheritance. Let’s look at what each of those " +"characteristics means and whether Rust supports it." +msgstr "" + +#: src/ch17-01-what-is-oo.md:11 +msgid "Objects Contain Data and Behavior" +msgstr "" + +#: src/ch17-01-what-is-oo.md:13 +msgid "" +"The book _Design Patterns: Elements of Reusable Object-Oriented Software_ by " +"Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (Addison-Wesley " +"Professional, 1994), colloquially referred to as _The Gang of Four_ book, is " +"a catalog of object-oriented design patterns. It defines OOP this way:" +msgstr "" + +#: src/ch17-01-what-is-oo.md:18 +msgid "" +"Object-oriented programs are made up of objects. An _object_ packages both " +"data and the procedures that operate on that data. The procedures are " +"typically called _methods_ or _operations_." +msgstr "" + +#: src/ch17-01-what-is-oo.md:22 +msgid "" +"Using this definition, Rust is object-oriented: structs and enums have data, " +"and `impl` blocks provide methods on structs and enums. Even though structs " +"and enums with methods aren’t _called_ objects, they provide the same " +"functionality, according to the Gang of Four’s definition of objects." +msgstr "" + +#: src/ch17-01-what-is-oo.md:27 +msgid "Encapsulation that Hides Implementation Details" +msgstr "" + +#: src/ch17-01-what-is-oo.md:29 +msgid "" +"Another aspect commonly associated with OOP is the idea of _encapsulation_, " +"which means that the implementation details of an object aren’t accessible " +"to code using that object. Therefore, the only way to interact with an " +"object is through its public API; code using the object shouldn’t be able to " +"reach into the object’s internals and change data or behavior directly. This " +"enables the programmer to change and refactor an object’s internals without " +"needing to change the code that uses the object." +msgstr "" + +#: src/ch17-01-what-is-oo.md:37 +msgid "" +"We discussed how to control encapsulation in Chapter 7: we can use the `pub` " +"keyword to decide which modules, types, functions, and methods in our code " +"should be public, and by default everything else is private. For example, we " +"can define a struct `AveragedCollection` that has a field containing a " +"vector of `i32` values. The struct can also have a field that contains the " +"average of the values in the vector, meaning the average doesn’t have to be " +"computed on demand whenever anyone needs it. In other words, " +"`AveragedCollection` will cache the calculated average for us. Listing 17-1 " +"has the definition of the `AveragedCollection` struct:" +msgstr "" + +#: src/ch17-01-what-is-oo.md:56 +msgid "" +"Listing 17-1: An `AveragedCollection` struct that " +"maintains a list of integers and the average of the items in the collection" +msgstr "" + +#: src/ch17-01-what-is-oo.md:60 +msgid "" +"The struct is marked `pub` so that other code can use it, but the fields " +"within the struct remain private. This is important in this case because we " +"want to ensure that whenever a value is added or removed from the list, the " +"average is also updated. We do this by implementing `add`, `remove`, and " +"`average` methods on the struct, as shown in Listing 17-2:" +msgstr "" + +#: src/ch17-01-what-is-oo.md:102 +msgid "" +"Listing 17-2: Implementations of the public methods " +"`add`, `remove`, and `average` on `AveragedCollection`" +msgstr "" + +#: src/ch17-01-what-is-oo.md:105 +msgid "" +"The public methods `add`, `remove`, and `average` are the only ways to " +"access or modify data in an instance of `AveragedCollection`. When an item " +"is added to `list` using the `add` method or removed using the `remove` " +"method, the implementations of each call the private `update_average` method " +"that handles updating the `average` field as well." +msgstr "" + +#: src/ch17-01-what-is-oo.md:111 +msgid "" +"We leave the `list` and `average` fields private so there is no way for " +"external code to add or remove items to or from the `list` field directly; " +"otherwise, the `average` field might become out of sync when the `list` " +"changes. The `average` method returns the value in the `average` field, " +"allowing external code to read the `average` but not modify it." +msgstr "" + +#: src/ch17-01-what-is-oo.md:117 +msgid "" +"Because we’ve encapsulated the implementation details of the struct " +"`AveragedCollection`, we can easily change aspects, such as the data " +"structure, in the future. For instance, we could use a `HashSet` " +"instead of a `Vec` for the `list` field. As long as the signatures of " +"the `add`, `remove`, and `average` public methods stay the same, code using " +"`AveragedCollection` wouldn’t need to change in order to compile. If we made " +"`list` public instead, this wouldn’t necessarily be the case: `HashSet` " +"and `Vec` have different methods for adding and removing items, so the " +"external code would likely have to change if it were modifying `list` " +"directly." +msgstr "" + +#: src/ch17-01-what-is-oo.md:127 +msgid "" +"If encapsulation is a required aspect for a language to be considered object-" +"oriented, then Rust meets that requirement. The option to use `pub` or not " +"for different parts of code enables encapsulation of implementation details." +msgstr "" + +#: src/ch17-01-what-is-oo.md:131 +msgid "Inheritance as a Type System and as Code Sharing" +msgstr "" + +#: src/ch17-01-what-is-oo.md:133 +msgid "" +"_Inheritance_ is a mechanism whereby an object can inherit elements from " +"another object’s definition, thus gaining the parent object’s data and " +"behavior without you having to define them again." +msgstr "" + +#: src/ch17-01-what-is-oo.md:137 +msgid "" +"If a language must have inheritance to be an object-oriented language, then " +"Rust is not one. There is no way to define a struct that inherits the parent " +"struct’s fields and method implementations without using a macro." +msgstr "" + +#: src/ch17-01-what-is-oo.md:141 +msgid "" +"However, if you’re used to having inheritance in your programming toolbox, " +"you can use other solutions in Rust, depending on your reason for reaching " +"for inheritance in the first place." +msgstr "" + +#: src/ch17-01-what-is-oo.md:145 +msgid "" +"You would choose inheritance for two main reasons. One is for reuse of code: " +"you can implement particular behavior for one type, and inheritance enables " +"you to reuse that implementation for a different type. You can do this in a " +"limited way in Rust code using default trait method implementations, which " +"you saw in Listing 10-14 when we added a default implementation of the " +"`summarize` method on the `Summary` trait. Any type implementing the " +"`Summary` trait would have the `summarize` method available on it without " +"any further code. This is similar to a parent class having an implementation " +"of a method and an inheriting child class also having the implementation of " +"the method. We can also override the default implementation of the " +"`summarize` method when we implement the `Summary` trait, which is similar " +"to a child class overriding the implementation of a method inherited from a " +"parent class." +msgstr "" + +#: src/ch17-01-what-is-oo.md:158 +msgid "" +"The other reason to use inheritance relates to the type system: to enable a " +"child type to be used in the same places as the parent type. This is also " +"called _polymorphism_, which means that you can substitute multiple objects " +"for each other at runtime if they share certain characteristics." +msgstr "" + +#: src/ch17-01-what-is-oo.md:163 +msgid "Polymorphism" +msgstr "" + +#: src/ch17-01-what-is-oo.md:165 +msgid "" +"To many people, polymorphism is synonymous with inheritance. But it’s " +"actually a more general concept that refers to code that can work with data " +"of multiple types. For inheritance, those types are generally subclasses." +msgstr "" + +#: src/ch17-01-what-is-oo.md:169 +msgid "" +"Rust instead uses generics to abstract over different possible types and " +"trait bounds to impose constraints on what those types must provide. This is " +"sometimes called _bounded parametric polymorphism_." +msgstr "" + +#: src/ch17-01-what-is-oo.md:173 +msgid "" +"Inheritance has recently fallen out of favor as a programming design " +"solution in many programming languages because it’s often at risk of sharing " +"more code than necessary. Subclasses shouldn’t always share all " +"characteristics of their parent class but will do so with inheritance. This " +"can make a program’s design less flexible. It also introduces the " +"possibility of calling methods on subclasses that don’t make sense or that " +"cause errors because the methods don’t apply to the subclass. In addition, " +"some languages will only allow single inheritance (meaning a subclass can " +"only inherit from one class), further restricting the flexibility of a " +"program’s design." +msgstr "" + +#: src/ch17-01-what-is-oo.md:183 +msgid "" +"For these reasons, Rust takes the different approach of using trait objects " +"instead of inheritance. Let’s look at how trait objects enable polymorphism " +"in Rust." +msgstr "" + +#: src/ch17-02-trait-objects.md:3 +msgid "" +"In Chapter 8, we mentioned that one limitation of vectors is that they can " +"store elements of only one type. We created a workaround in Listing 8-9 " +"where we defined a `SpreadsheetCell` enum that had variants to hold " +"integers, floats, and text. This meant we could store different types of " +"data in each cell and still have a vector that represented a row of cells. " +"This is a perfectly good solution when our interchangeable items are a fixed " +"set of types that we know when our code is compiled." +msgstr "" + +#: src/ch17-02-trait-objects.md:11 +msgid "" +"However, sometimes we want our library user to be able to extend the set of " +"types that are valid in a particular situation. To show how we might achieve " +"this, we’ll create an example graphical user interface (GUI) tool that " +"iterates through a list of items, calling a `draw` method on each one to " +"draw it to the screen—a common technique for GUI tools. We’ll create a " +"library crate called `gui` that contains the structure of a GUI library. " +"This crate might include some types for people to use, such as `Button` or " +"`TextField`. In addition, `gui` users will want to create their own types " +"that can be drawn: for instance, one programmer might add an `Image` and " +"another might add a `SelectBox`." +msgstr "" + +#: src/ch17-02-trait-objects.md:22 +msgid "" +"We won’t implement a fully fledged GUI library for this example but will " +"show how the pieces would fit together. At the time of writing the library, " +"we can’t know and define all the types other programmers might want to " +"create. But we do know that `gui` needs to keep track of many values of " +"different types, and it needs to call a `draw` method on each of these " +"differently typed values. It doesn’t need to know exactly what will happen " +"when we call the `draw` method, just that the value will have that method " +"available for us to call." +msgstr "" + +#: src/ch17-02-trait-objects.md:30 +msgid "" +"To do this in a language with inheritance, we might define a class named " +"`Component` that has a method named `draw` on it. The other classes, such as " +"`Button`, `Image`, and `SelectBox`, would inherit from `Component` and thus " +"inherit the `draw` method. They could each override the `draw` method to " +"define their custom behavior, but the framework could treat all of the types " +"as if they were `Component` instances and call `draw` on them. But because " +"Rust doesn’t have inheritance, we need another way to structure the `gui` " +"library to allow users to extend it with new types." +msgstr "" + +#: src/ch17-02-trait-objects.md:39 +msgid "Defining a Trait for Common Behavior" +msgstr "" + +#: src/ch17-02-trait-objects.md:41 +msgid "" +"To implement the behavior we want `gui` to have, we’ll define a trait named " +"`Draw` that will have one method named `draw`. Then we can define a vector " +"that takes a _trait object_. A trait object points to both an instance of a " +"type implementing our specified trait and a table used to look up trait " +"methods on that type at runtime. We create a trait object by specifying some " +"sort of pointer, such as a `&` reference or a `Box` smart pointer, then " +"the `dyn` keyword, and then specifying the relevant trait. (We’ll talk about " +"the reason trait objects must use a pointer in Chapter 19 in the section " +"[“Dynamically Sized Types and the `Sized` Trait.”](ch19-04-advanced-types." +"html#dynamically-sized-types-and-the-sized-trait)) We can use " +"trait objects in place of a generic or concrete type. Wherever we use a " +"trait object, Rust’s type system will ensure at compile time that any value " +"used in that context will implement the trait object’s trait. Consequently, " +"we don’t need to know all the possible types at compile time." +msgstr "" + +#: src/ch17-02-trait-objects.md:55 +msgid "" +"We’ve mentioned that, in Rust, we refrain from calling structs and enums " +"“objects” to distinguish them from other languages’ objects. In a struct or " +"enum, the data in the struct fields and the behavior in `impl` blocks are " +"separated, whereas in other languages, the data and behavior combined into " +"one concept is often labeled an object. However, trait objects _are_ more " +"like objects in other languages in the sense that they combine data and " +"behavior. But trait objects differ from traditional objects in that we can’t " +"add data to a trait object. Trait objects aren’t as generally useful as " +"objects in other languages: their specific purpose is to allow abstraction " +"across common behavior." +msgstr "" + +#: src/ch17-02-trait-objects.md:66 +msgid "" +"Listing 17-3 shows how to define a trait named `Draw` with one method named " +"`draw`:" +msgstr "" + +#: src/ch17-02-trait-objects.md:77 +msgid "" +"Listing 17-3: Definition of the `Draw` trait" +msgstr "" + +#: src/ch17-02-trait-objects.md:79 +msgid "" +"This syntax should look familiar from our discussions on how to define " +"traits in Chapter 10. Next comes some new syntax: Listing 17-4 defines a " +"struct named `Screen` that holds a vector named `components`. This vector is " +"of type `Box`, which is a trait object; it’s a stand-in for any " +"type inside a `Box` that implements the `Draw` trait." +msgstr "" + +#: src/ch17-02-trait-objects.md:97 +msgid "" +"Listing 17-4: Definition of the `Screen` struct with " +"a `components` field holding a vector of trait objects that implement the " +"`Draw` trait" +msgstr "" + +#: src/ch17-02-trait-objects.md:101 +msgid "" +"On the `Screen` struct, we’ll define a method named `run` that will call the " +"`draw` method on each of its `components`, as shown in Listing 17-5:" +msgstr "" + +#: src/ch17-02-trait-objects.md:124 +msgid "" +"Listing 17-5: A `run` method on `Screen` that calls " +"the `draw` method on each component" +msgstr "" + +#: src/ch17-02-trait-objects.md:127 +msgid "" +"This works differently from defining a struct that uses a generic type " +"parameter with trait bounds. A generic type parameter can only be " +"substituted with one concrete type at a time, whereas trait objects allow " +"for multiple concrete types to fill in for the trait object at runtime. For " +"example, we could have defined the `Screen` struct using a generic type and " +"a trait bound as in Listing 17-6:" +msgstr "" + +#: src/ch17-02-trait-objects.md:157 +msgid "" +"Listing 17-6: An alternate implementation of the " +"`Screen` struct and its `run` method using generics and trait bounds" +msgstr "" + +#: src/ch17-02-trait-objects.md:160 +msgid "" +"This restricts us to a `Screen` instance that has a list of components all " +"of type `Button` or all of type `TextField`. If you’ll only ever have " +"homogeneous collections, using generics and trait bounds is preferable " +"because the definitions will be monomorphized at compile time to use the " +"concrete types." +msgstr "" + +#: src/ch17-02-trait-objects.md:165 +msgid "" +"On the other hand, with the method using trait objects, one `Screen` " +"instance can hold a `Vec` that contains a `Box