diff --git a/po/de.po b/po/de.po index af8709ab..b436cfde 100644 --- a/po/de.po +++ b/po/de.po @@ -5,133 +5,133 @@ msgstr "" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" +"Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: src/SUMMARY.md:3 src/welcome.md:1 +#: src/SUMMARY.md:4 src/index.md:1 msgid "Welcome to Comprehensive Rust 🦀" msgstr "Willkommen bei Comprehensive Rust 🦀" -#: src/SUMMARY.md:4 src/running-the-course.md:1 +#: src/SUMMARY.md:5 src/running-the-course.md:1 msgid "Running the Course" msgstr "Ablauf des Kurses" -#: src/SUMMARY.md:5 src/running-the-course/course-structure.md:1 +#: src/SUMMARY.md:6 src/running-the-course/course-structure.md:1 msgid "Course Structure" msgstr "Kursstruktur" -#: src/SUMMARY.md:6 src/running-the-course/keyboard-shortcuts.md:1 +#: src/SUMMARY.md:7 src/running-the-course/keyboard-shortcuts.md:1 msgid "Keyboard Shortcuts" msgstr "Tastaturkürzel" -#: src/SUMMARY.md:7 src/running-the-course/translations.md:1 +#: src/SUMMARY.md:8 src/running-the-course/translations.md:1 msgid "Translations" msgstr "Übersetzungen" -#: src/SUMMARY.md:8 src/cargo.md:1 +#: src/SUMMARY.md:9 src/cargo.md:1 msgid "Using Cargo" msgstr "Cargo verwenden" -#: src/SUMMARY.md:9 +#: src/SUMMARY.md:10 msgid "Rust Ecosystem" msgstr "Rust Ökosystem" -#: src/SUMMARY.md:10 +#: src/SUMMARY.md:11 msgid "Code Samples" msgstr "Codebeispiele" -#: src/SUMMARY.md:11 +#: src/SUMMARY.md:12 msgid "Running Cargo Locally" msgstr "Cargo lokal ausführen" -#: src/SUMMARY.md:14 +#: src/SUMMARY.md:15 msgid "Day 1: Morning" msgstr "Tag 1: Morgens" -#: src/SUMMARY.md:18 src/SUMMARY.md:75 src/SUMMARY.md:128 src/SUMMARY.md:185 -#: src/SUMMARY.md:211 src/SUMMARY.md:259 +#: src/SUMMARY.md:19 src/SUMMARY.md:79 src/SUMMARY.md:134 src/SUMMARY.md:192 +#: src/SUMMARY.md:218 src/SUMMARY.md:268 msgid "Welcome" msgstr "Willkommen" -#: src/SUMMARY.md:19 src/welcome-day-1/what-is-rust.md:1 +#: src/SUMMARY.md:20 src/welcome-day-1/what-is-rust.md:1 msgid "What is Rust?" msgstr "Was ist Rust?" -#: src/SUMMARY.md:20 src/hello-world.md:1 +#: src/SUMMARY.md:21 src/hello-world.md:1 msgid "Hello World!" msgstr "Hallo Welt!" -#: src/SUMMARY.md:21 src/hello-world/small-example.md:1 +#: src/SUMMARY.md:22 src/hello-world/small-example.md:1 msgid "Small Example" msgstr "Ein kleines Beispiel" -#: src/SUMMARY.md:22 src/why-rust.md:1 +#: src/SUMMARY.md:23 src/why-rust.md:1 msgid "Why Rust?" msgstr "Warum Rust?" -#: src/SUMMARY.md:23 src/why-rust/compile-time.md:1 +#: src/SUMMARY.md:24 src/why-rust/compile-time.md:1 msgid "Compile Time Guarantees" msgstr "Kompilierzeitgarantien" -#: src/SUMMARY.md:24 src/why-rust/runtime.md:1 +#: src/SUMMARY.md:25 src/why-rust/runtime.md:1 msgid "Runtime Guarantees" msgstr "Laufzeitgarantien" -#: src/SUMMARY.md:25 src/why-rust/modern.md:1 +#: src/SUMMARY.md:26 src/why-rust/modern.md:1 msgid "Modern Features" msgstr "Moderne Merkmale" -#: src/SUMMARY.md:26 src/basic-syntax.md:1 +#: src/SUMMARY.md:27 src/basic-syntax.md:1 msgid "Basic Syntax" msgstr "Grundlegende Syntax" -#: src/SUMMARY.md:27 src/basic-syntax/scalar-types.md:1 +#: src/SUMMARY.md:28 src/basic-syntax/scalar-types.md:1 msgid "Scalar Types" msgstr "Skalare Typen" -#: src/SUMMARY.md:28 src/basic-syntax/compound-types.md:1 +#: src/SUMMARY.md:29 src/basic-syntax/compound-types.md:1 msgid "Compound Types" msgstr "Verbundtypen" -#: src/SUMMARY.md:29 src/basic-syntax/references.md:1 +#: src/SUMMARY.md:30 src/basic-syntax/references.md:1 msgid "References" msgstr "Referenzen" -#: src/SUMMARY.md:30 src/basic-syntax/references-dangling.md:1 +#: src/SUMMARY.md:31 src/basic-syntax/references-dangling.md:1 msgid "Dangling References" msgstr "Hängende Referenzen" -#: src/SUMMARY.md:31 src/basic-syntax/slices.md:1 +#: src/SUMMARY.md:32 src/basic-syntax/slices.md:1 msgid "Slices" msgstr "Anteilstypen" -#: src/SUMMARY.md:32 +#: src/SUMMARY.md:33 msgid "String vs str" msgstr "String vs. str" -#: src/SUMMARY.md:33 src/basic-syntax/functions.md:1 +#: src/SUMMARY.md:34 src/basic-syntax/functions.md:1 msgid "Functions" msgstr "Funktionen" -#: src/SUMMARY.md:34 src/basic-syntax/rustdoc.md:1 +#: src/SUMMARY.md:35 src/basic-syntax/rustdoc.md:1 msgid "Rustdoc" msgstr "Rustdoc" -#: src/SUMMARY.md:35 src/SUMMARY.md:82 src/basic-syntax/methods.md:1 +#: src/SUMMARY.md:36 src/SUMMARY.md:102 src/basic-syntax/methods.md:1 #: src/methods.md:1 msgid "Methods" msgstr "Methoden" -#: src/SUMMARY.md:36 +#: src/SUMMARY.md:37 msgid "Overloading" msgstr "Überladen" -#: src/SUMMARY.md:37 src/SUMMARY.md:66 src/SUMMARY.md:90 src/SUMMARY.md:119 -#: src/SUMMARY.md:148 src/SUMMARY.md:177 src/SUMMARY.md:204 src/SUMMARY.md:225 -#: src/SUMMARY.md:251 src/SUMMARY.md:273 src/SUMMARY.md:293 +#: src/SUMMARY.md:38 src/SUMMARY.md:71 src/SUMMARY.md:105 src/SUMMARY.md:125 +#: src/SUMMARY.md:154 src/SUMMARY.md:184 src/SUMMARY.md:211 src/SUMMARY.md:232 +#: src/SUMMARY.md:260 src/SUMMARY.md:282 src/SUMMARY.md:303 #: src/exercises/android/morning.md:1 src/exercises/bare-metal/morning.md:1 #: src/exercises/bare-metal/afternoon.md:1 #: src/exercises/concurrency/morning.md:1 @@ -139,929 +139,919 @@ msgstr "Überladen" msgid "Exercises" msgstr "Übungen" -#: src/SUMMARY.md:38 src/exercises/day-1/implicit-conversions.md:1 +#: src/SUMMARY.md:39 src/exercises/day-1/implicit-conversions.md:1 msgid "Implicit Conversions" msgstr "Implizite Konvertierungen" -#: src/SUMMARY.md:39 +#: src/SUMMARY.md:40 msgid "Arrays and for Loops" msgstr "Arrays und for-Schleifen" -#: src/SUMMARY.md:41 +#: src/SUMMARY.md:42 msgid "Day 1: Afternoon" msgstr "Tag 1: Nachmittags" -#: src/SUMMARY.md:43 src/basic-syntax/variables.md:1 +#: src/SUMMARY.md:44 src/SUMMARY.md:295 src/control-flow.md:1 +msgid "Control Flow" +msgstr "Kontrollfluss" + +#: src/SUMMARY.md:45 src/control-flow/blocks.md:1 +msgid "Blocks" +msgstr "Blöcke" + +#: src/SUMMARY.md:46 +msgid "if expressions" +msgstr "if-Ausdrücke" + +#: src/SUMMARY.md:47 +msgid "for expressions" +msgstr "for-Ausdrücke" + +#: src/SUMMARY.md:48 +msgid "while expressions" +msgstr "while-Ausdrücke" + +#: src/SUMMARY.md:49 +msgid "break & continue" +msgstr "break & continue" + +#: src/SUMMARY.md:50 +msgid "loop expressions" +msgstr "loop-Ausdrücke" + +#: src/SUMMARY.md:52 src/basic-syntax/variables.md:1 msgid "Variables" msgstr "Variablen" -#: src/SUMMARY.md:44 src/basic-syntax/type-inference.md:1 +#: src/SUMMARY.md:53 src/basic-syntax/type-inference.md:1 msgid "Type Inference" msgstr "Typinferenz" -#: src/SUMMARY.md:45 +#: src/SUMMARY.md:54 msgid "static & const" msgstr "static & const" -#: src/SUMMARY.md:46 src/basic-syntax/scopes-shadowing.md:1 +#: src/SUMMARY.md:55 src/basic-syntax/scopes-shadowing.md:1 msgid "Scopes and Shadowing" msgstr "Gültigkeitsbereiche und Verschattungen" -#: src/SUMMARY.md:47 src/memory-management.md:1 -msgid "Memory Management" -msgstr "Speicherverwaltung" - -#: src/SUMMARY.md:48 -msgid "Stack vs Heap" -msgstr "Stapelspeicher vs. Haldenspeicher" - -#: src/SUMMARY.md:49 src/memory-management/stack.md:1 -msgid "Stack Memory" -msgstr "Stapelspeicher" - -#: src/SUMMARY.md:50 src/memory-management/manual.md:1 -msgid "Manual Memory Management" -msgstr "Manuelle Speicherverwaltung" - -#: src/SUMMARY.md:51 src/memory-management/scope-based.md:1 -msgid "Scope-Based Memory Management" -msgstr "Gültigkeitsbereichbasierte Speicherverwaltung" - -#: src/SUMMARY.md:52 -msgid "Garbage Collection" -msgstr "Automatische Speicherbereinigung" - -#: src/SUMMARY.md:53 -msgid "Rust Memory Management" -msgstr "Rust Speicherverwaltung" - -#: src/SUMMARY.md:54 src/memory-management/comparison.md:1 -msgid "Comparison" -msgstr "Vergleich" - -#: src/SUMMARY.md:55 src/ownership.md:1 -msgid "Ownership" -msgstr "Eigentümerschaft" - -#: src/SUMMARY.md:56 src/ownership/move-semantics.md:1 -msgid "Move Semantics" -msgstr "Semantik des Verschiebens" - -#: src/SUMMARY.md:57 src/ownership/moved-strings-rust.md:1 -msgid "Moved Strings in Rust" -msgstr "Verschieben von String in Rust" - -#: src/SUMMARY.md:58 src/ownership/double-free-modern-cpp.md:1 -msgid "Double Frees in Modern C++" -msgstr "Doppel-Freigabe-Fehler in modernem C++" - -#: src/SUMMARY.md:59 src/ownership/moves-function-calls.md:1 -msgid "Moves in Function Calls" -msgstr "Verschieben in Funktionsaufrufen" - -#: src/SUMMARY.md:60 src/ownership/copy-clone.md:1 -msgid "Copying and Cloning" -msgstr "Kopieren und Klonen" - -#: src/SUMMARY.md:61 src/ownership/borrowing.md:1 -msgid "Borrowing" -msgstr "Ausleihen" - -#: src/SUMMARY.md:62 src/ownership/shared-unique-borrows.md:1 -msgid "Shared and Unique Borrows" -msgstr "Geteiltes und einmaliges Ausleihen" - -#: src/SUMMARY.md:63 src/ownership/lifetimes.md:1 -msgid "Lifetimes" -msgstr "Lebensdauern" - -#: src/SUMMARY.md:64 src/ownership/lifetimes-function-calls.md:1 -msgid "Lifetimes in Function Calls" -msgstr "Lebensdauern in Funktionsaufrufen" - -#: src/SUMMARY.md:65 src/ownership/lifetimes-data-structures.md:1 -msgid "Lifetimes in Data Structures" -msgstr "Lebensdauern in Datenstrukturen" - -#: src/SUMMARY.md:67 src/exercises/day-1/book-library.md:1 -#: src/exercises/day-1/solutions-afternoon.md:3 -msgid "Designing a Library" -msgstr "Entwerfen einer Bibliothek" - -#: src/SUMMARY.md:68 src/exercises/day-1/iterators-and-ownership.md:1 -msgid "Iterators and Ownership" -msgstr "Iteratoren und Eigentümerschaft" - -#: src/SUMMARY.md:71 -msgid "Day 2: Morning" -msgstr "Tag 2: Morgens" - -#: src/SUMMARY.md:76 src/structs.md:1 -msgid "Structs" -msgstr "Strukturen" - -#: src/SUMMARY.md:77 src/structs/tuple-structs.md:1 -msgid "Tuple Structs" -msgstr "Tupelstrukturen" - -#: src/SUMMARY.md:78 src/structs/field-shorthand.md:1 -msgid "Field Shorthand Syntax" -msgstr "Feld Abkürzungs Syntax" - -#: src/SUMMARY.md:79 src/enums.md:1 +#: src/SUMMARY.md:56 src/enums.md:1 msgid "Enums" msgstr "Aufzählungstypen" -#: src/SUMMARY.md:80 src/enums/variant-payloads.md:1 +#: src/SUMMARY.md:57 src/enums/variant-payloads.md:1 msgid "Variant Payloads" msgstr "Varianteninhalte" -#: src/SUMMARY.md:81 src/enums/sizes.md:1 +#: src/SUMMARY.md:58 src/enums/sizes.md:1 msgid "Enum Sizes" msgstr "Größen von Aufzählungstypen" -#: src/SUMMARY.md:83 src/methods/receiver.md:1 +#: src/SUMMARY.md:60 src/control-flow/novel.md:1 +#, fuzzy +msgid "Novel Control Flow" +msgstr "Kontrollfluss" + +#: src/SUMMARY.md:61 +msgid "if let expressions" +msgstr "if let-Ausdrücke" + +#: src/SUMMARY.md:62 +msgid "while let expressions" +msgstr "while let-Ausdrücke" + +#: src/SUMMARY.md:63 +msgid "match expressions" +msgstr "match-Ausdrücke" + +#: src/SUMMARY.md:65 src/pattern-matching.md:1 +msgid "Pattern Matching" +msgstr "Musterabgleich" + +#: src/SUMMARY.md:66 src/pattern-matching/destructuring-enums.md:1 +msgid "Destructuring Enums" +msgstr "Aufzählungstypen destrukturieren" + +#: src/SUMMARY.md:67 src/pattern-matching/destructuring-structs.md:1 +msgid "Destructuring Structs" +msgstr "Strukturen destrukturieren" + +#: src/SUMMARY.md:68 src/pattern-matching/destructuring-arrays.md:1 +msgid "Destructuring Arrays" +msgstr "Arrays destrukturieren" + +#: src/SUMMARY.md:69 src/pattern-matching/match-guards.md:1 +msgid "Match Guards" +msgstr "Abgleichsbedingungen" + +#: src/SUMMARY.md:72 src/exercises/day-1/luhn.md:1 +#: src/exercises/day-1/solutions-afternoon.md:3 +msgid "Luhn Algorithm" +msgstr "Luhn-Algorithmus" + +#: src/SUMMARY.md:73 +#, fuzzy +msgid "Pattern Matching (TBD)" +msgstr "Musterabgleich" + +#: src/SUMMARY.md:75 +msgid "Day 2: Morning" +msgstr "Tag 2: Morgens" + +#: src/SUMMARY.md:81 src/memory-management.md:1 +msgid "Memory Management" +msgstr "Speicherverwaltung" + +#: src/SUMMARY.md:82 +msgid "Stack vs Heap" +msgstr "Stapelspeicher vs. Haldenspeicher" + +#: src/SUMMARY.md:83 +msgid "Stack Memory" +msgstr "Stapelspeicher" + +#: src/SUMMARY.md:84 src/memory-management/manual.md:1 +msgid "Manual Memory Management" +msgstr "Manuelle Speicherverwaltung" + +#: src/SUMMARY.md:85 src/memory-management/scope-based.md:1 +msgid "Scope-Based Memory Management" +msgstr "Gültigkeitsbereichbasierte Speicherverwaltung" + +#: src/SUMMARY.md:86 +msgid "Garbage Collection" +msgstr "Automatische Speicherbereinigung" + +#: src/SUMMARY.md:87 +msgid "Rust Memory Management" +msgstr "Rust Speicherverwaltung" + +#: src/SUMMARY.md:88 src/ownership.md:1 +msgid "Ownership" +msgstr "Eigentümerschaft" + +#: src/SUMMARY.md:89 src/ownership/move-semantics.md:1 +msgid "Move Semantics" +msgstr "Semantik des Verschiebens" + +#: src/SUMMARY.md:90 src/ownership/moved-strings-rust.md:1 +msgid "Moved Strings in Rust" +msgstr "Verschieben von String in Rust" + +#: src/SUMMARY.md:91 +msgid "Double Frees in Modern C++" +msgstr "Doppel-Freigabe-Fehler in modernem C++" + +#: src/SUMMARY.md:92 src/ownership/moves-function-calls.md:1 +msgid "Moves in Function Calls" +msgstr "Verschieben in Funktionsaufrufen" + +#: src/SUMMARY.md:93 src/ownership/copy-clone.md:1 +msgid "Copying and Cloning" +msgstr "Kopieren und Klonen" + +#: src/SUMMARY.md:94 src/ownership/borrowing.md:1 +msgid "Borrowing" +msgstr "Ausleihen" + +#: src/SUMMARY.md:95 src/ownership/shared-unique-borrows.md:1 +msgid "Shared and Unique Borrows" +msgstr "Geteiltes und einmaliges Ausleihen" + +#: src/SUMMARY.md:96 src/ownership/lifetimes.md:1 +msgid "Lifetimes" +msgstr "Lebensdauern" + +#: src/SUMMARY.md:97 src/ownership/lifetimes-function-calls.md:1 +msgid "Lifetimes in Function Calls" +msgstr "Lebensdauern in Funktionsaufrufen" + +#: src/SUMMARY.md:98 src/ownership/lifetimes-data-structures.md:1 +msgid "Lifetimes in Data Structures" +msgstr "Lebensdauern in Datenstrukturen" + +#: src/SUMMARY.md:99 src/structs.md:1 +msgid "Structs" +msgstr "Strukturen" + +#: src/SUMMARY.md:100 src/structs/tuple-structs.md:1 +msgid "Tuple Structs" +msgstr "Tupelstrukturen" + +#: src/SUMMARY.md:101 src/structs/field-shorthand.md:1 +msgid "Field Shorthand Syntax" +msgstr "Feld Abkürzungs Syntax" + +#: src/SUMMARY.md:103 src/methods/receiver.md:1 msgid "Method Receiver" msgstr "Methodenempfänger" -#: src/SUMMARY.md:84 src/SUMMARY.md:159 src/SUMMARY.md:272 +#: src/SUMMARY.md:104 src/SUMMARY.md:166 src/SUMMARY.md:281 #: src/methods/example.md:1 src/concurrency/shared_state/example.md:1 msgid "Example" msgstr "Beispiel" -#: src/SUMMARY.md:85 src/pattern-matching.md:1 -msgid "Pattern Matching" -msgstr "Musterabgleich" +#: src/SUMMARY.md:106 src/exercises/day-2/book-library.md:1 +#, fuzzy +msgid "Storing Books" +msgstr "`&str`" -#: src/SUMMARY.md:86 src/pattern-matching/destructuring-enums.md:1 -msgid "Destructuring Enums" -msgstr "Aufzählungstypen destrukturieren" - -#: src/SUMMARY.md:87 src/pattern-matching/destructuring-structs.md:1 -msgid "Destructuring Structs" -msgstr "Strukturen destrukturieren" - -#: src/SUMMARY.md:88 src/pattern-matching/destructuring-arrays.md:1 -msgid "Destructuring Arrays" -msgstr "Arrays destrukturieren" - -#: src/SUMMARY.md:89 src/pattern-matching/match-guards.md:1 -msgid "Match Guards" -msgstr "Abgleichsbedingungen" - -#: src/SUMMARY.md:91 src/exercises/day-2/health-statistics.md:1 +#: src/SUMMARY.md:107 src/exercises/day-2/health-statistics.md:1 msgid "Health Statistics" msgstr "Gesundheitsstatistiken" -#: src/SUMMARY.md:92 src/exercises/day-2/solutions-morning.md:3 -msgid "Points and Polygons" -msgstr "Punkte und Polygone" - -#: src/SUMMARY.md:94 +#: src/SUMMARY.md:109 msgid "Day 2: Afternoon" msgstr "Tag 2: Nachmittags" -#: src/SUMMARY.md:96 src/SUMMARY.md:286 src/control-flow.md:1 -msgid "Control Flow" -msgstr "Kontrollfluss" - -#: src/SUMMARY.md:97 src/control-flow/blocks.md:1 -msgid "Blocks" -msgstr "Blöcke" - -#: src/SUMMARY.md:98 -msgid "if expressions" -msgstr "if-Ausdrücke" - -#: src/SUMMARY.md:99 -msgid "if let expressions" -msgstr "if let-Ausdrücke" - -#: src/SUMMARY.md:100 -msgid "while expressions" -msgstr "while-Ausdrücke" - -#: src/SUMMARY.md:101 -msgid "while let expressions" -msgstr "while let-Ausdrücke" - -#: src/SUMMARY.md:102 -msgid "for expressions" -msgstr "for-Ausdrücke" - -#: src/SUMMARY.md:103 -msgid "loop expressions" -msgstr "loop-Ausdrücke" - -#: src/SUMMARY.md:104 -msgid "match expressions" -msgstr "match-Ausdrücke" - -#: src/SUMMARY.md:105 -msgid "break & continue" -msgstr "break & continue" - -#: src/SUMMARY.md:106 src/std.md:1 +#: src/SUMMARY.md:111 src/std.md:1 msgid "Standard Library" msgstr "Standardbibliothek" -#: src/SUMMARY.md:107 +#: src/SUMMARY.md:112 msgid "Option and Result" msgstr "Option und Result" -#: src/SUMMARY.md:108 src/std/string.md:1 +#: src/SUMMARY.md:113 src/std/string.md:1 msgid "String" msgstr "String" -#: src/SUMMARY.md:109 +#: src/SUMMARY.md:114 msgid "Vec" msgstr "Vec" -#: src/SUMMARY.md:110 +#: src/SUMMARY.md:115 msgid "HashMap" msgstr "HashMap" -#: src/SUMMARY.md:111 +#: src/SUMMARY.md:116 msgid "Box" msgstr "Box" -#: src/SUMMARY.md:112 +#: src/SUMMARY.md:117 msgid "Recursive Data Types" msgstr "Rekursive Datentypen" -#: src/SUMMARY.md:113 src/std/box-niche.md:1 +#: src/SUMMARY.md:118 src/std/box-niche.md:1 msgid "Niche Optimization" msgstr "Nischenoptimierung" -#: src/SUMMARY.md:114 +#: src/SUMMARY.md:119 msgid "Rc" msgstr "Rc" -#: src/SUMMARY.md:115 src/modules.md:1 +#: src/SUMMARY.md:120 +msgid "Cell/RefCell" +msgstr "" + +#: src/SUMMARY.md:121 src/modules.md:1 msgid "Modules" msgstr "Module" -#: src/SUMMARY.md:116 src/modules/visibility.md:1 +#: src/SUMMARY.md:122 src/modules/visibility.md:1 msgid "Visibility" msgstr "Sichtbarkeit" -#: src/SUMMARY.md:117 src/modules/paths.md:1 +#: src/SUMMARY.md:123 src/modules/paths.md:1 msgid "Paths" msgstr "Pfade" -#: src/SUMMARY.md:118 src/modules/filesystem.md:1 +#: src/SUMMARY.md:124 src/modules/filesystem.md:1 msgid "Filesystem Hierarchy" msgstr "Dateisystemhierarchie" -#: src/SUMMARY.md:120 src/exercises/day-2/luhn.md:1 -#: src/exercises/day-2/solutions-afternoon.md:3 -msgid "Luhn Algorithm" -msgstr "Luhn-Algorithmus" +#: src/SUMMARY.md:126 src/exercises/day-2/iterators-and-ownership.md:1 +msgid "Iterators and Ownership" +msgstr "Iteratoren und Eigentümerschaft" -#: src/SUMMARY.md:121 src/exercises/day-2/strings-iterators.md:1 -#: src/exercises/day-2/solutions-afternoon.md:97 +#: src/SUMMARY.md:127 src/exercises/day-2/strings-iterators.md:1 +#: src/exercises/day-2/solutions-afternoon.md:3 msgid "Strings and Iterators" msgstr "Strings und Iteratoren" -#: src/SUMMARY.md:124 +#: src/SUMMARY.md:130 msgid "Day 3: Morning" msgstr "Tag 3: Morgens" -#: src/SUMMARY.md:129 src/generics.md:1 +#: src/SUMMARY.md:135 src/generics.md:1 msgid "Generics" msgstr "Generische Datentypen und Methoden" -#: src/SUMMARY.md:130 src/generics/data-types.md:1 +#: src/SUMMARY.md:136 src/generics/data-types.md:1 msgid "Generic Data Types" msgstr "Generische Datentypen" -#: src/SUMMARY.md:131 src/generics/methods.md:1 +#: src/SUMMARY.md:137 src/generics/methods.md:1 msgid "Generic Methods" msgstr "Generische Methoden" -#: src/SUMMARY.md:132 src/generics/monomorphization.md:1 +#: src/SUMMARY.md:138 src/generics/monomorphization.md:1 msgid "Monomorphization" msgstr "Monomorphisierung" -#: src/SUMMARY.md:133 src/traits.md:1 +#: src/SUMMARY.md:139 src/traits.md:1 msgid "Traits" msgstr "Merkmale" -#: src/SUMMARY.md:134 src/traits/trait-objects.md:1 +#: src/SUMMARY.md:140 src/traits/trait-objects.md:1 msgid "Trait Objects" msgstr "Merkmalsobjekte" -#: src/SUMMARY.md:135 src/traits/deriving-traits.md:1 +#: src/SUMMARY.md:141 src/traits/deriving-traits.md:1 msgid "Deriving Traits" msgstr "Ableitung von Merkmalen" -#: src/SUMMARY.md:136 src/traits/default-methods.md:1 +#: src/SUMMARY.md:142 src/traits/default-methods.md:1 msgid "Default Methods" msgstr "Standardmethoden" -#: src/SUMMARY.md:137 src/traits/trait-bounds.md:1 +#: src/SUMMARY.md:143 src/traits/trait-bounds.md:1 msgid "Trait Bounds" msgstr "Merkmalsgrenzen" -#: src/SUMMARY.md:138 +#: src/SUMMARY.md:144 msgid "impl Trait" msgstr "impl Merkmal" -#: src/SUMMARY.md:139 src/traits/important-traits.md:1 +#: src/SUMMARY.md:145 src/traits/important-traits.md:1 msgid "Important Traits" msgstr "Wichtige Merkmale" -#: src/SUMMARY.md:140 +#: src/SUMMARY.md:146 msgid "Iterator" msgstr "Iterator" -#: src/SUMMARY.md:141 src/traits/from-iterator.md:1 +#: src/SUMMARY.md:147 src/traits/from-iterator.md:1 msgid "FromIterator" msgstr "FromIterator" -#: src/SUMMARY.md:142 +#: src/SUMMARY.md:148 msgid "From and Into" msgstr "From und Into" -#: src/SUMMARY.md:143 +#: src/SUMMARY.md:149 msgid "Read and Write" msgstr "Read und Write" -#: src/SUMMARY.md:144 +#: src/SUMMARY.md:150 msgid "Drop" msgstr "Drop" -#: src/SUMMARY.md:145 +#: src/SUMMARY.md:151 msgid "Default" msgstr "Default Merkmal" -#: src/SUMMARY.md:146 +#: src/SUMMARY.md:152 msgid "Operators: Add, Mul, ..." msgstr "Operatoren: Add, Mul, ..." -#: src/SUMMARY.md:147 +#: src/SUMMARY.md:153 msgid "Closures: Fn, FnMut, FnOnce" msgstr "" -#: src/SUMMARY.md:149 src/exercises/day-3/simple-gui.md:1 +#: src/SUMMARY.md:155 src/exercises/day-3/simple-gui.md:1 #: src/exercises/day-3/solutions-morning.md:3 msgid "A Simple GUI Library" msgstr "Eine einfache GUI-Bibliothek" -#: src/SUMMARY.md:151 +#: src/SUMMARY.md:156 src/exercises/day-3/solutions-morning.md:145 +msgid "Points and Polygons" +msgstr "Punkte und Polygone" + +#: src/SUMMARY.md:158 msgid "Day 3: Afternoon" msgstr "Tag 3: Nachmittags" -#: src/SUMMARY.md:153 src/error-handling.md:1 +#: src/SUMMARY.md:160 src/error-handling.md:1 msgid "Error Handling" msgstr "Fehlerbehandlung" -#: src/SUMMARY.md:154 src/error-handling/panics.md:1 +#: src/SUMMARY.md:161 src/error-handling/panics.md:1 msgid "Panics" msgstr "Laufzeitabbrüche" -#: src/SUMMARY.md:155 +#: src/SUMMARY.md:162 msgid "Catching Stack Unwinding" msgstr "Abfangen der Auflösung des Stapelspeichers" -#: src/SUMMARY.md:156 +#: src/SUMMARY.md:163 msgid "Structured Error Handling" msgstr "Strukturierte Fehlerbehandlung" -#: src/SUMMARY.md:157 +#: src/SUMMARY.md:164 msgid "Propagating Errors with ?" msgstr "Weitergabe von Fehlern mit ?" -#: src/SUMMARY.md:158 src/error-handling/converting-error-types.md:1 +#: src/SUMMARY.md:165 src/error-handling/converting-error-types.md:1 #: src/error-handling/converting-error-types-example.md:1 msgid "Converting Error Types" msgstr "Fehlertypen konvertieren" -#: src/SUMMARY.md:160 src/error-handling/deriving-error-enums.md:1 +#: src/SUMMARY.md:167 src/error-handling/deriving-error-enums.md:1 msgid "Deriving Error Enums" msgstr "Ableiten von Fehleraufzählungen" -#: src/SUMMARY.md:161 src/error-handling/dynamic-errors.md:1 +#: src/SUMMARY.md:168 src/error-handling/dynamic-errors.md:1 msgid "Dynamic Error Types" msgstr "Dynamische Fehlertypen" -#: src/SUMMARY.md:162 src/error-handling/error-contexts.md:1 +#: src/SUMMARY.md:169 src/error-handling/error-contexts.md:1 msgid "Adding Context to Errors" msgstr "Kontext zu Fehlern hinzufügen" -#: src/SUMMARY.md:163 src/testing.md:1 +#: src/SUMMARY.md:170 src/testing.md:1 msgid "Testing" msgstr "Testen" -#: src/SUMMARY.md:164 src/testing/unit-tests.md:1 +#: src/SUMMARY.md:171 src/testing/unit-tests.md:1 msgid "Unit Tests" msgstr "Unit-Tests" -#: src/SUMMARY.md:165 src/testing/test-modules.md:1 +#: src/SUMMARY.md:172 src/testing/test-modules.md:1 msgid "Test Modules" msgstr "Testmodule" -#: src/SUMMARY.md:166 src/testing/doc-tests.md:1 +#: src/SUMMARY.md:173 src/testing/doc-tests.md:1 msgid "Documentation Tests" msgstr "Dokumentationstests" -#: src/SUMMARY.md:167 src/testing/integration-tests.md:1 +#: src/SUMMARY.md:174 src/testing/integration-tests.md:1 msgid "Integration Tests" msgstr "Integrationstests" -#: src/SUMMARY.md:168 src/bare-metal/useful-crates.md:1 +#: src/SUMMARY.md:175 src/bare-metal/useful-crates.md:1 msgid "Useful crates" msgstr "Nützliche Kisten (Crates)" -#: src/SUMMARY.md:169 src/unsafe.md:1 +#: src/SUMMARY.md:176 src/unsafe.md:1 msgid "Unsafe Rust" msgstr "Unsicheres Rust" -#: src/SUMMARY.md:170 src/unsafe/raw-pointers.md:1 +#: src/SUMMARY.md:177 src/unsafe/raw-pointers.md:1 msgid "Dereferencing Raw Pointers" msgstr "Roh-zeiger dereferenzieren" -#: src/SUMMARY.md:171 src/unsafe/mutable-static-variables.md:1 +#: src/SUMMARY.md:178 src/unsafe/mutable-static-variables.md:1 msgid "Mutable Static Variables" msgstr "Veränderbare statische Variablen" -#: src/SUMMARY.md:172 src/unsafe/unions.md:1 +#: src/SUMMARY.md:179 src/unsafe/unions.md:1 msgid "Unions" msgstr "Vereinigungen" -#: src/SUMMARY.md:173 src/unsafe/calling-unsafe-functions.md:1 +#: src/SUMMARY.md:180 src/unsafe/calling-unsafe-functions.md:1 msgid "Calling Unsafe Functions" msgstr "Unsichere Funktionen aufrufen" -#: src/SUMMARY.md:174 src/unsafe/writing-unsafe-functions.md:1 +#: src/SUMMARY.md:181 src/unsafe/writing-unsafe-functions.md:1 msgid "Writing Unsafe Functions" msgstr "Unsichere Funktionen schreiben" -#: src/SUMMARY.md:175 +#: src/SUMMARY.md:182 msgid "Extern Functions" msgstr "Externe Funktionen" -#: src/SUMMARY.md:176 src/unsafe/unsafe-traits.md:1 +#: src/SUMMARY.md:183 src/unsafe/unsafe-traits.md:1 msgid "Implementing Unsafe Traits" msgstr "Unsichere Merkmale implementieren" -#: src/SUMMARY.md:178 src/exercises/day-3/safe-ffi-wrapper.md:1 +#: src/SUMMARY.md:185 src/exercises/day-3/safe-ffi-wrapper.md:1 #: src/exercises/day-3/solutions-afternoon.md:3 msgid "Safe FFI Wrapper" msgstr "Sicherer FFI-Wrapper" -#: src/SUMMARY.md:181 src/SUMMARY.md:249 -#: src/running-the-course/course-structure.md:16 src/bare-metal/android.md:1 +#: src/SUMMARY.md:188 src/SUMMARY.md:258 src/bare-metal/android.md:1 msgid "Android" msgstr "Android" -#: src/SUMMARY.md:186 src/android/setup.md:1 +#: src/SUMMARY.md:193 src/android/setup.md:1 msgid "Setup" msgstr "Einrichtung" -#: src/SUMMARY.md:187 src/android/build-rules.md:1 +#: src/SUMMARY.md:194 src/android/build-rules.md:1 msgid "Build Rules" msgstr "Regeln beim Bauen" -#: src/SUMMARY.md:188 +#: src/SUMMARY.md:195 msgid "Binary" msgstr "Binärdatei" -#: src/SUMMARY.md:189 +#: src/SUMMARY.md:196 msgid "Library" msgstr "Bibliothek" -#: src/SUMMARY.md:190 src/android/aidl.md:1 +#: src/SUMMARY.md:197 src/android/aidl.md:1 msgid "AIDL" msgstr "AIDL" -#: src/SUMMARY.md:191 +#: src/SUMMARY.md:198 msgid "Interface" msgstr "Schnittstelle" -#: src/SUMMARY.md:192 +#: src/SUMMARY.md:199 msgid "Implementation" msgstr "Implementierung" -#: src/SUMMARY.md:193 +#: src/SUMMARY.md:200 msgid "Server" msgstr "Server" -#: src/SUMMARY.md:194 src/android/aidl/deploy.md:1 +#: src/SUMMARY.md:201 src/android/aidl/deploy.md:1 msgid "Deploy" msgstr "Einsetzen" -#: src/SUMMARY.md:195 +#: src/SUMMARY.md:202 msgid "Client" msgstr "Klient" -#: src/SUMMARY.md:196 src/android/aidl/changing.md:1 +#: src/SUMMARY.md:203 src/android/aidl/changing.md:1 msgid "Changing API" msgstr "API verändern" -#: src/SUMMARY.md:197 src/SUMMARY.md:240 src/android/logging.md:1 +#: src/SUMMARY.md:204 src/SUMMARY.md:248 src/android/logging.md:1 #: src/bare-metal/aps/logging.md:1 msgid "Logging" msgstr "Protokollierung" -#: src/SUMMARY.md:198 src/android/interoperability.md:1 +#: src/SUMMARY.md:205 src/android/interoperability.md:1 msgid "Interoperability" msgstr "Interoperabilität" -#: src/SUMMARY.md:199 +#: src/SUMMARY.md:206 msgid "With C" msgstr "Mit C" -#: src/SUMMARY.md:200 +#: src/SUMMARY.md:207 msgid "Calling C with Bindgen" msgstr "Aufruf von C-Funktionen mit Bindgen" -#: src/SUMMARY.md:201 +#: src/SUMMARY.md:208 msgid "Calling Rust from C" msgstr "Aufruf von Rust aus C" -#: src/SUMMARY.md:202 src/android/interoperability/cpp.md:1 +#: src/SUMMARY.md:209 src/android/interoperability/cpp.md:1 msgid "With C++" msgstr "Mit C++" -#: src/SUMMARY.md:203 +#: src/SUMMARY.md:210 msgid "With Java" msgstr "Mit Java" -#: src/SUMMARY.md:207 +#: src/SUMMARY.md:214 msgid "Bare Metal: Morning" msgstr "Hardwarenahes Rust: Morgens" -#: src/SUMMARY.md:212 +#: src/SUMMARY.md:219 msgid "no_std" msgstr "" -#: src/SUMMARY.md:213 +#: src/SUMMARY.md:220 msgid "A Minimal Example" msgstr "Kleines Beispiel" -#: src/SUMMARY.md:214 +#: src/SUMMARY.md:221 msgid "alloc" msgstr "" -#: src/SUMMARY.md:215 src/bare-metal/microcontrollers.md:1 +#: src/SUMMARY.md:222 src/bare-metal/microcontrollers.md:1 msgid "Microcontrollers" msgstr "Mikrokontroller" -#: src/SUMMARY.md:216 src/bare-metal/microcontrollers/mmio.md:1 +#: src/SUMMARY.md:223 src/bare-metal/microcontrollers/mmio.md:1 msgid "Raw MMIO" msgstr "MMIO" -#: src/SUMMARY.md:217 +#: src/SUMMARY.md:224 msgid "PACs" msgstr "" -#: src/SUMMARY.md:218 +#: src/SUMMARY.md:225 msgid "HAL Crates" msgstr "HAL Kisten" -#: src/SUMMARY.md:219 +#: src/SUMMARY.md:226 msgid "Board Support Crates" msgstr "Helfer Kisten" -#: src/SUMMARY.md:220 +#: src/SUMMARY.md:227 msgid "The Type State Pattern" msgstr "Das Typzustandsmuster" -#: src/SUMMARY.md:221 +#: src/SUMMARY.md:228 msgid "embedded-hal" msgstr "" -#: src/SUMMARY.md:222 +#: src/SUMMARY.md:229 msgid "probe-rs, cargo-embed" msgstr "" -#: src/SUMMARY.md:223 src/bare-metal/microcontrollers/debugging.md:1 +#: src/SUMMARY.md:230 src/bare-metal/microcontrollers/debugging.md:1 msgid "Debugging" msgstr "Debugging" -#: src/SUMMARY.md:224 src/SUMMARY.md:242 +#: src/SUMMARY.md:231 src/SUMMARY.md:251 msgid "Other Projects" msgstr "Andere Ressourcen" -#: src/SUMMARY.md:226 src/exercises/bare-metal/compass.md:1 +#: src/SUMMARY.md:233 src/exercises/bare-metal/compass.md:1 #: src/exercises/bare-metal/solutions-morning.md:3 msgid "Compass" msgstr "Kompass" -#: src/SUMMARY.md:228 +#: src/SUMMARY.md:235 msgid "Bare Metal: Afternoon" msgstr "Bare-Metal: Nachmittags" -#: src/SUMMARY.md:230 +#: src/SUMMARY.md:237 msgid "Application Processors" msgstr "Applikationsprozessoren" -#: src/SUMMARY.md:231 +#: src/SUMMARY.md:238 src/bare-metal/aps/entry-point.md:1 +msgid "Getting Ready to Rust" +msgstr "" + +#: src/SUMMARY.md:239 msgid "Inline Assembly" msgstr "" -#: src/SUMMARY.md:232 +#: src/SUMMARY.md:240 msgid "MMIO" msgstr "" -#: src/SUMMARY.md:233 +#: src/SUMMARY.md:241 msgid "Let's Write a UART Driver" msgstr "Schreiben eines UART Treibers" -#: src/SUMMARY.md:234 +#: src/SUMMARY.md:242 msgid "More Traits" msgstr "Noch mehr Merkmale" -#: src/SUMMARY.md:235 +#: src/SUMMARY.md:243 msgid "A Better UART Driver" msgstr "Ein besserer UART Treiber" -#: src/SUMMARY.md:236 src/bare-metal/aps/better-uart/bitflags.md:1 +#: src/SUMMARY.md:244 src/bare-metal/aps/better-uart/bitflags.md:1 msgid "Bitflags" msgstr "" -#: src/SUMMARY.md:237 +#: src/SUMMARY.md:245 msgid "Multiple Registers" msgstr "Mehrere Register" -#: src/SUMMARY.md:238 src/bare-metal/aps/better-uart/driver.md:1 +#: src/SUMMARY.md:246 src/bare-metal/aps/better-uart/driver.md:1 msgid "Driver" msgstr "Treiber" -#: src/SUMMARY.md:239 src/SUMMARY.md:241 +#: src/SUMMARY.md:247 src/SUMMARY.md:249 msgid "Using It" msgstr "Benutzung" -#: src/SUMMARY.md:243 +#: src/SUMMARY.md:250 src/bare-metal/aps/exceptions.md:1 +#, fuzzy +msgid "Exceptions" +msgstr "Funktionen" + +#: src/SUMMARY.md:252 msgid "Useful Crates" msgstr "Nützliche Kisten" -#: src/SUMMARY.md:244 +#: src/SUMMARY.md:253 msgid "zerocopy" msgstr "" -#: src/SUMMARY.md:245 +#: src/SUMMARY.md:254 msgid "aarch64-paging" msgstr "" -#: src/SUMMARY.md:246 +#: src/SUMMARY.md:255 msgid "buddy_system_allocator" msgstr "" -#: src/SUMMARY.md:247 +#: src/SUMMARY.md:256 msgid "tinyvec" msgstr "" -#: src/SUMMARY.md:248 +#: src/SUMMARY.md:257 msgid "spin" msgstr "" -#: src/SUMMARY.md:250 src/bare-metal/android/vmbase.md:1 +#: src/SUMMARY.md:259 src/bare-metal/android/vmbase.md:1 msgid "vmbase" msgstr "" -#: src/SUMMARY.md:252 +#: src/SUMMARY.md:261 msgid "RTC Driver" msgstr "RTC Treiber" -#: src/SUMMARY.md:255 +#: src/SUMMARY.md:264 msgid "Concurrency: Morning" msgstr "Nebenläufigkeit: Morgens" -#: src/SUMMARY.md:260 src/concurrency/threads.md:1 +#: src/SUMMARY.md:269 src/concurrency/threads.md:1 msgid "Threads" msgstr "Ausführungsstrang" -#: src/SUMMARY.md:261 src/concurrency/scoped-threads.md:1 +#: src/SUMMARY.md:270 src/concurrency/scoped-threads.md:1 msgid "Scoped Threads" msgstr "Ausführungsstrang mit Sichtbarkeitsbereich" -#: src/SUMMARY.md:262 src/concurrency/channels.md:1 +#: src/SUMMARY.md:271 src/concurrency/channels.md:1 msgid "Channels" msgstr "Kanäle" -#: src/SUMMARY.md:263 src/concurrency/channels/unbounded.md:1 +#: src/SUMMARY.md:272 src/concurrency/channels/unbounded.md:1 msgid "Unbounded Channels" msgstr "Unbegrenzte Kanäle" -#: src/SUMMARY.md:264 src/concurrency/channels/bounded.md:1 +#: src/SUMMARY.md:273 src/concurrency/channels/bounded.md:1 msgid "Bounded Channels" msgstr "Unbeschränkte Kanäle" -#: src/SUMMARY.md:265 +#: src/SUMMARY.md:274 msgid "Send and Sync" msgstr "Send und Sync" -#: src/SUMMARY.md:265 +#: src/SUMMARY.md:274 msgid "Send" msgstr "Send" -#: src/SUMMARY.md:265 +#: src/SUMMARY.md:274 msgid "Sync" msgstr "Sync" -#: src/SUMMARY.md:268 src/concurrency/send-sync/examples.md:1 +#: src/SUMMARY.md:277 src/concurrency/send-sync/examples.md:1 msgid "Examples" msgstr "Beispiele" -#: src/SUMMARY.md:269 src/concurrency/shared_state.md:1 +#: src/SUMMARY.md:278 src/concurrency/shared_state.md:1 msgid "Shared State" msgstr "Geteilter Zustand" -#: src/SUMMARY.md:270 +#: src/SUMMARY.md:279 msgid "Arc" msgstr "Arc" -#: src/SUMMARY.md:271 +#: src/SUMMARY.md:280 msgid "Mutex" msgstr "Mutex" -#: src/SUMMARY.md:274 src/SUMMARY.md:294 +#: src/SUMMARY.md:283 src/SUMMARY.md:304 #: src/exercises/concurrency/dining-philosophers.md:1 #: src/exercises/concurrency/solutions-morning.md:3 msgid "Dining Philosophers" msgstr "Philosophenproblem" -#: src/SUMMARY.md:275 src/exercises/concurrency/link-checker.md:1 +#: src/SUMMARY.md:284 src/exercises/concurrency/link-checker.md:1 msgid "Multi-threaded Link Checker" msgstr "Link Überprüfung mit mehreren Ausführungssträngen" -#: src/SUMMARY.md:277 +#: src/SUMMARY.md:286 msgid "Concurrency: Afternoon" msgstr "Nebenläufigkeit: Nachmittags" -#: src/SUMMARY.md:279 +#: src/SUMMARY.md:288 msgid "Async Basics" msgstr "Async Grundlagen" -#: src/SUMMARY.md:280 +#: src/SUMMARY.md:289 msgid "async/await" msgstr "" -#: src/SUMMARY.md:281 src/async/futures.md:1 +#: src/SUMMARY.md:290 src/async/futures.md:1 #, fuzzy msgid "Futures" msgstr "Schließungen" -#: src/SUMMARY.md:282 src/async/runtimes.md:1 +#: src/SUMMARY.md:291 src/async/runtimes.md:1 msgid "Runtimes" msgstr "Laufzeiten" -#: src/SUMMARY.md:283 src/async/runtimes/tokio.md:1 +#: src/SUMMARY.md:292 src/async/runtimes/tokio.md:1 msgid "Tokio" msgstr "" -#: src/SUMMARY.md:284 src/exercises/concurrency/link-checker.md:106 -#: src/exercises/concurrency/chat-app.md:140 src/async/tasks.md:1 +#: src/SUMMARY.md:293 src/exercises/concurrency/link-checker.md:126 +#: src/async/tasks.md:1 src/exercises/concurrency/chat-app.md:143 msgid "Tasks" msgstr "Aufgaben" -#: src/SUMMARY.md:285 src/async/channels.md:1 +#: src/SUMMARY.md:294 src/async/channels.md:1 msgid "Async Channels" msgstr "Async Kanäle" -#: src/SUMMARY.md:287 src/async/control-flow/join.md:1 +#: src/SUMMARY.md:296 src/async/control-flow/join.md:1 msgid "Join" msgstr "" -#: src/SUMMARY.md:288 src/async/control-flow/select.md:1 +#: src/SUMMARY.md:297 src/async/control-flow/select.md:1 #, fuzzy msgid "Select" msgstr "Aufstellen" -#: src/SUMMARY.md:289 +#: src/SUMMARY.md:298 msgid "Pitfalls" msgstr "Tücken" -#: src/SUMMARY.md:290 +#: src/SUMMARY.md:299 msgid "Blocking the Executor" msgstr "Blockieren des Ausführers" -#: src/SUMMARY.md:291 src/async/pitfalls/pin.md:1 +#: src/SUMMARY.md:300 src/async/pitfalls/pin.md:1 msgid "Pin" msgstr "" -#: src/SUMMARY.md:292 src/async/pitfalls/async-traits.md:1 +#: src/SUMMARY.md:301 src/async/pitfalls/async-traits.md:1 msgid "Async Traits" msgstr "Async Merkmale" -#: src/SUMMARY.md:295 src/exercises/concurrency/chat-app.md:1 -#: src/exercises/concurrency/solutions-afternoon.md:113 +#: src/SUMMARY.md:302 src/async/pitfalls/cancellation.md:1 +#, fuzzy +msgid "Cancellation" +msgstr "Installation" + +#: src/SUMMARY.md:305 src/exercises/concurrency/chat-app.md:1 +#: src/exercises/concurrency/solutions-afternoon.md:95 msgid "Broadcast Chat Application" msgstr "" -#: src/SUMMARY.md:298 +#: src/SUMMARY.md:308 msgid "Final Words" msgstr "Letzte Worte" -#: src/SUMMARY.md:302 src/thanks.md:1 +#: src/SUMMARY.md:312 src/thanks.md:1 msgid "Thanks!" msgstr "Danke!" -#: src/SUMMARY.md:303 +#: src/SUMMARY.md:313 msgid "Other Resources" msgstr "Andere Ressourcen" -#: src/SUMMARY.md:304 src/credits.md:1 +#: src/SUMMARY.md:314 src/credits.md:1 msgid "Credits" msgstr "Würdigungen" -#: src/SUMMARY.md:307 src/exercises/solutions.md:1 +#: src/SUMMARY.md:317 src/exercises/solutions.md:1 msgid "Solutions" msgstr "Lösungen" -#: src/SUMMARY.md:312 +#: src/SUMMARY.md:322 msgid "Day 1 Morning" msgstr "Tag 1 Morgens" -#: src/SUMMARY.md:313 +#: src/SUMMARY.md:323 msgid "Day 1 Afternoon" msgstr "Tag 1 Nachmittags" -#: src/SUMMARY.md:314 +#: src/SUMMARY.md:324 msgid "Day 2 Morning" msgstr "Tag 2 Morgens" -#: src/SUMMARY.md:315 +#: src/SUMMARY.md:325 msgid "Day 2 Afternoon" msgstr "Tag 2 Nachmittags" -#: src/SUMMARY.md:316 +#: src/SUMMARY.md:326 msgid "Day 3 Morning" msgstr "Tag 3 Morgens" -#: src/SUMMARY.md:317 +#: src/SUMMARY.md:327 msgid "Day 3 Afternoon" msgstr "Tag 3 Nachmittags" -#: src/SUMMARY.md:318 +#: src/SUMMARY.md:328 msgid "Bare Metal Rust Morning" msgstr "Hardwarenahes Rust: Morgens" -#: src/SUMMARY.md:319 src/exercises/bare-metal/solutions-afternoon.md:1 +#: src/SUMMARY.md:329 src/exercises/bare-metal/solutions-afternoon.md:1 msgid "Bare Metal Rust Afternoon" msgstr "Hadwarenahes Rust: Nachmittags" -#: src/SUMMARY.md:320 +#: src/SUMMARY.md:330 msgid "Concurrency Morning" msgstr "Nebenläufigkeit Morgens" -#: src/SUMMARY.md:321 +#: src/SUMMARY.md:331 msgid "Concurrency Afternoon" msgstr "Nebenläufigkeit Nachmittags" -#: src/welcome.md:3 -msgid "" -"[![Build workflow](https://img.shields.io/github/actions/workflow/status/" -"google/comprehensive-rust/build.yml?style=flat-square)](https://github.com/" -"google/comprehensive-rust/actions/workflows/build.yml?query=branch%3Amain)" -msgstr "" - -#: src/welcome.md:3 -msgid "Build workflow" -msgstr "" - -#: src/welcome.md:3 +#: src/index.md:3 msgid "" "[![Build workflow](https://img.shields.io/github/actions/workflow/status/" "google/comprehensive-rust/build.yml?style=flat-square)](https://github.com/" "google/comprehensive-rust/actions/workflows/build.yml?query=branch%3Amain) [!" "[GitHub contributors](https://img.shields.io/github/contributors/google/" "comprehensive-rust?style=flat-square)](https://github.com/google/" -"comprehensive-rust/graphs/contributors)" -msgstr "" - -#: src/welcome.md:4 -msgid "GitHub contributors" -msgstr "Github Beiträger" - -#: src/welcome.md:4 -msgid "" -"[![GitHub contributors](https://img.shields.io/github/contributors/google/" -"comprehensive-rust?style=flat-square)](https://github.com/google/" "comprehensive-rust/graphs/contributors) [![GitHub stars](https://img.shields." "io/github/stars/google/comprehensive-rust?style=flat-square)](https://github." "com/google/comprehensive-rust/stargazers)" msgstr "" -#: src/welcome.md:5 -msgid "GitHub stars" -msgstr "Github Sterne" - -#: src/welcome.md:5 +#: src/index.md:7 +#, fuzzy msgid "" -"[![GitHub stars](https://img.shields.io/github/stars/google/comprehensive-" -"rust?style=flat-square)](https://github.com/google/comprehensive-rust/" -"stargazers)" -msgstr "" - -#: src/welcome.md:7 -msgid "" -"This is a three day Rust course developed by the Android team. The course " -"covers the full spectrum of Rust, from basic syntax to advanced topics like " -"generics and error handling. It also includes Android-specific content on " -"the last day." +"This is a free Rust course developed by the Android team at Google. The " +"course covers the full spectrum of Rust, from basic syntax to advanced " +"topics like generics and error handling." msgstr "" "Dies ist ein dreitägiger Rust-Kurs, der vom Android-Team entwickelt wurde. " "Der Kurs umfasst das gesamte Spektrum von Rust, von grundlegender Syntax bis " @@ -1069,7 +1059,14 @@ msgstr "" "sowie Fehlerbehandlung. Am letzten Tag werden auch Android-spezifische " "Inhalte behandelt." -#: src/welcome.md:11 +#: src/index.md:11 +msgid "" +"The latest version of the course can be found at . If you are reading somewhere else, please check there " +"for updates." +msgstr "" + +#: src/index.md:15 msgid "" "The goal of the course is to teach you Rust. We assume you don't know " "anything about Rust and hope to:" @@ -1077,30 +1074,34 @@ msgstr "" "Das Ziel des Kurses ist es, Dir Rust beizubringen. Wie setzen keine " "Vorkenntnisse über Rust voraus, und hoffen das Folgende zu erreichen:" -#: src/welcome.md:14 +#: src/index.md:18 msgid "Give you a comprehensive understanding of the Rust syntax and language." msgstr "" "Dir ein umfassendes Verständnis der Rust-Syntax und -Sprache zu vermitteln." -#: src/welcome.md:15 +#: src/index.md:19 msgid "Enable you to modify existing programs and write new programs in Rust." msgstr "" "Es dir ermöglichen, bestehende Programme zu modifizieren und neue Programme " "in Rust zu schreiben." -#: src/welcome.md:16 +#: src/index.md:20 msgid "Show you common Rust idioms." msgstr "Dir gängige Rust-Idiome zu zeigen." -#: src/welcome.md:18 +#: src/index.md:22 +msgid "We call the first three course days Rust Fundamentals." +msgstr "" + +#: src/index.md:24 +#, fuzzy msgid "" -"The first three days show you the fundamentals of Rust. Following this, " -"you're invited to dive into one or more specialized topics:" +"Building on this, you're invited to dive into one or more specialized topics:" msgstr "" "In den ersten drei Tagen zeigen wir die Grundlagen von Rust. Danach, laden " "wir dich ein sich mit einem oder mehreren Spezialthemen zu befassen:" -#: src/welcome.md:21 +#: src/index.md:26 msgid "" "[Android](android.md): a half-day course on using Rust for Android platform " "development (AOSP). This includes interoperability with C, C++, and Java." @@ -1109,9 +1110,10 @@ msgstr "" "Android-Plattform Entwicklung (AOSP). Dazu gehört die Interoperabilität mit " "C, C++ und Java." -#: src/welcome.md:23 +#: src/index.md:28 +#, fuzzy msgid "" -"[Bare-metal](bare-metal.md): a full day class on using Rust for bare-metal " +"[Bare-metal](bare-metal.md): a whole-day class on using Rust for bare-metal " "(embedded) development. Both microcontrollers and application processors are " "covered." msgstr "" @@ -1119,9 +1121,10 @@ msgstr "" "Rust für Bare-Metal (eingebettete) Entwicklung. Sowohl Mikrocontroller als " "auch Anwendungsprozessoren bedeckt." -#: src/welcome.md:26 +#: src/index.md:31 +#, fuzzy msgid "" -"[Concurrency](concurrency.md): a full day class on concurrency in Rust. We " +"[Concurrency](concurrency.md): a whole-day class on concurrency in Rust. We " "cover both classical concurrency (preemptively scheduling using threads and " "mutexes) and async/await concurrency (cooperative multitasking using " "futures)." @@ -1131,11 +1134,11 @@ msgstr "" "Planung mithilfe von Threads als auch Mutexe) und Async/Await-Parallelität " "(kooperatives Multitasking mit Futures)." -#: src/welcome.md:32 +#: src/index.md:37 msgid "Non-Goals" msgstr "Nicht-Ziele" -#: src/welcome.md:34 +#: src/index.md:39 msgid "" "Rust is a large language and we won't be able to cover all of it in a few " "days. Some non-goals of this course are:" @@ -1143,9 +1146,10 @@ msgstr "" "Rust ist eine große Sprache und wir werden sie in ein paar Tagen nicht " "vollständig abdecken können. Einige Nicht-Ziele dieses Kurses sind:" -#: src/welcome.md:37 +#: src/index.md:42 +#, fuzzy msgid "" -"Learn how to develop macros, please see [Chapter 19.5 in the Rust Book]" +"Learning how to develop macros: please see [Chapter 19.5 in the Rust Book]" "(https://doc.rust-lang.org/book/ch19-06-macros.html) and [Rust by Example]" "(https://doc.rust-lang.org/rust-by-example/macros.html) instead." msgstr "" @@ -1153,14 +1157,15 @@ msgstr "" "(https://doc.rust-lang.org/book/ch19-06-macros.html) und [Rust im Beispiel]" "(https://doc.rust-lang.org/rust-by-example/macros.html)." -#: src/welcome.md:41 +#: src/index.md:46 msgid "Assumptions" msgstr "Annahmen" -#: src/welcome.md:43 +#: src/index.md:48 +#, fuzzy msgid "" "The course assumes that you already know how to program. Rust is a " -"statically typed language and we will sometimes make comparisons with C and " +"statically-typed language and we will sometimes make comparisons with C and " "C++ to better explain or contrast the Rust approach." msgstr "" "Der Kurs setzt voraus, dass du bereits Programmierkenntnisse besitzt. Rust " @@ -1168,15 +1173,16 @@ msgstr "" "C und C++ machen, um besser den Rust-Ansatz zu erklären oder " "gegenüberzustellen." -#: src/welcome.md:47 +#: src/index.md:52 +#, fuzzy msgid "" -"If you know how to program in a dynamically typed language such as Python or " +"If you know how to program in a dynamically-typed language such as Python or " "JavaScript, then you will be able to follow along just fine too." msgstr "" "Aber auch wenn du Vorwissen in einer dynamisch typisierten Sprache wie " "Python oder JavaScript hast, wirst du problemlos folgen können." -#: src/welcome.md:52 +#: src/index.md:57 msgid "" "This is an example of a _speaker note_. We will use these to add additional " "information to the slides. This could be key points which the instructor " @@ -1200,10 +1206,20 @@ msgstr "" "Google durchführen." #: src/running-the-course.md:8 +msgid "" +"We typically run classes from 10:00 am to 4:00 pm, with a 1 hour lunch break " +"in the middle. This leaves 2.5 hours for the morning class and 2.5 hours for " +"the afternoon class. Note that this is just a recommendation: you can also " +"spend 3 hour on the morning session to give people more time for exercises. " +"The downside of longer session is that people can become very tired after 6 " +"full hours of class in the afternoon." +msgstr "" + +#: src/running-the-course.md:16 msgid "Before you run the course, you will want to:" msgstr "Bevor du den Kurs vorstellst solltest du:" -#: src/running-the-course.md:10 +#: src/running-the-course.md:18 #, fuzzy msgid "" "Make yourself familiar with the course material. We've included speaker " @@ -1219,7 +1235,7 @@ msgstr "" "Pfeil neben \"Speaker Notes\"). Dadurch hast du eine übersichtliche " "Oberfläche wenn du den Kurs vorstellst." -#: src/running-the-course.md:16 +#: src/running-the-course.md:24 #, fuzzy msgid "" "Decide on the dates. Since the course takes at least three full days, we " @@ -1231,7 +1247,7 @@ msgstr "" "entweder ein Thema nach Schwierigkeitsgrad wählen, oder aber ein Thema was " "zu deiner Zuhörerschaft passt." -#: src/running-the-course.md:21 +#: src/running-the-course.md:29 #, fuzzy msgid "" "Find a room large enough for your in-person participants. We recommend a " @@ -1247,7 +1263,7 @@ msgstr "" "meinten, dass Pausen zwischen den Tagen sinnvoll seien um die Menge an " "Informationen zu verarbeiten." -#: src/running-the-course.md:29 +#: src/running-the-course.md:37 #, fuzzy msgid "" "On the day of your course, show up to the room a little early to set things " @@ -1264,7 +1280,7 @@ msgstr "" "Teilnehmer und dich hat. Ihr werdet nämlich eure Laptops benötigen. Um genau " "zu sein wirst du viel vorprogrammieren." -#: src/running-the-course.md:35 +#: src/running-the-course.md:43 #, fuzzy msgid "" "Let people solve the exercises by themselves or in small groups. We " @@ -1290,7 +1306,7 @@ msgstr "" "\n" "Bereite alles vor was du am Nachmittag des vierten Tages behandeln möchtest." -#: src/running-the-course.md:43 +#: src/running-the-course.md:51 msgid "" "That is all, good luck running the course! We hope it will be as much fun " "for you as it has been for us!" @@ -1298,7 +1314,7 @@ msgstr "" "Das ist alles, viel Glück bei der Durchführung des Kurses! Wir hoffen, dass " "es dir genauso viel Spaß machen wird wie uns!" -#: src/running-the-course.md:46 +#: src/running-the-course.md:54 msgid "" "Please [provide feedback](https://github.com/google/comprehensive-rust/" "discussions/86) afterwards so that we can keep improving the course. We " @@ -1314,30 +1330,39 @@ msgstr "" "comprehensive-rust/discussions/100)!" #: src/running-the-course/course-structure.md:5 -msgid "The course is fast paced and covers a lot of ground:" -msgstr "Der Kurs geht in schnellem Tempo voran und deckt viele Themen ab:" +#, fuzzy +msgid "Rust Fundamentals" +msgstr "Rust-Binärdateien" #: src/running-the-course/course-structure.md:7 -msgid "Day 1: Basic Rust, ownership and the borrow checker." +msgid "" +"The first three days make up [Rust Fundaments](../welcome-day-1.md). The " +"days are fast paced and we cover a lot of ground:" msgstr "" -"Tag 1: Rust Grundlagen, Eigentümerschaft (ownership) und der Ausleihenprüfer " -"(borrow checker)." -#: src/running-the-course/course-structure.md:8 -msgid "Day 2: Compound data types, pattern matching, the standard library." +#: src/running-the-course/course-structure.md:10 +msgid "Day 1: Basic Rust, syntax, control flow, creating and consuming values." +msgstr "" + +#: src/running-the-course/course-structure.md:11 +#, fuzzy +msgid "" +"Day 2: Memory management, ownership, compound data types, and the standard " +"library." msgstr "" "Tag 2: Zusammengesetzte Datentypen, Musterabgleich, die Standardbibliothek." -#: src/running-the-course/course-structure.md:9 -msgid "Day 3: Traits and generics, error handling, testing, unsafe Rust." +#: src/running-the-course/course-structure.md:12 +#, fuzzy +msgid "Day 3: Generics, traits, error handling, testing, and unsafe Rust." msgstr "" "Tag 3: Merkmale und Generika, Fehlerbehandlung, Testen, unsicheres Rust." -#: src/running-the-course/course-structure.md:11 +#: src/running-the-course/course-structure.md:14 msgid "Deep Dives" msgstr "Vertiefungen" -#: src/running-the-course/course-structure.md:13 +#: src/running-the-course/course-structure.md:16 msgid "" "In addition to the 3-day class on Rust Fundamentals, we cover some more " "specialized topics:" @@ -1345,17 +1370,23 @@ msgstr "" "Zusätzlich zu den Rust-Grundlagen behandeln wir noch einiges mehr " "Spezialthemen nach Tag 3:" -#: src/running-the-course/course-structure.md:18 +#: src/running-the-course/course-structure.md:19 +#, fuzzy +msgid "Rust in Android" +msgstr "Willkommen zu Tag 1" + +#: src/running-the-course/course-structure.md:21 +#, fuzzy msgid "" -"The [Android Deep Dive](../android.md) is a half-day course on using Rust " -"for Android platform development. This includes interoperability with C, C+" -"+, and Java." +"The [Rust in Android](../android.md) deep dive is a half-day course on using " +"Rust for Android platform development. This includes interoperability with " +"C, C++, and Java." msgstr "" "Der [Android Deep Dive](../android.md) ist ein halbtägiger Kurs zur " "Verwendung von Rust für Entwicklung der Android-Plattform. Dazu gehört die " "Interoperabilität mit C, C++ und Java." -#: src/running-the-course/course-structure.md:22 +#: src/running-the-course/course-structure.md:25 msgid "" "You will need an [AOSP checkout](https://source.android.com/docs/setup/" "download/downloading). Make a checkout of the [course repository](https://" @@ -1370,7 +1401,7 @@ msgstr "" "AOSP Arbeitskopie. Dadurch wird sichergestellt, dass das Android-" "Buildsystem die `Android.bp`\\-Dateien in `src/android/` sehen kann." -#: src/running-the-course/course-structure.md:27 +#: src/running-the-course/course-structure.md:30 msgid "" "Ensure that `adb sync` works with your emulator or real device and pre-build " "all Android examples using `src/android/build_all.sh`. Read the script to " @@ -1381,21 +1412,23 @@ msgstr "" "android/build_all.sh`. Schaue auch in das Skript rein und probiere aus, ob " "alle Befehle, die es ausführt auch von Hand ausgeführt funktionieren." -#: src/running-the-course/course-structure.md:34 -msgid "Bare-Metal" +#: src/running-the-course/course-structure.md:37 +#, fuzzy +msgid "Bare-Metal Rust" msgstr "Bare-Metal" -#: src/running-the-course/course-structure.md:36 +#: src/running-the-course/course-structure.md:39 +#, fuzzy msgid "" -"The [Bare-Metal Deep Dive](../bare-metal.md): a full day class on using Rust " -"for bare-metal (embedded) development. Both microcontrollers and application " -"processors are covered." +"The [Bare-Metal Rust](../bare-metal.md) deep dive is a full day class on " +"using Rust for bare-metal (embedded) development. Both microcontrollers and " +"application processors are covered." msgstr "" "Der [Bare-Metal Deep Dive](../bare-metal.md): ein ganztägiger Kurs über die " "Verwendung von Rust für Bare-Metal-Entwicklung (eingebettet). Sowohl " "Mikrocontroller als auch Anwendungen Prozessoren sind abgedeckt." -#: src/running-the-course/course-structure.md:40 +#: src/running-the-course/course-structure.md:43 msgid "" "For the microcontroller part, you will need to buy the [BBC micro:bit]" "(https://microbit.org/) v2 development board ahead of time. Everybody will " @@ -1407,19 +1440,21 @@ msgstr "" "von Paketen installieren, wie auf der [Willkommens Seite](../bare-metal.md) " "beschrieben." -#: src/running-the-course/course-structure.md:45 -msgid "Concurrency" -msgstr "Nebenläufigkeit" +#: src/running-the-course/course-structure.md:48 +#, fuzzy +msgid "Concurrency in Rust" +msgstr "Willkommen bei Comprehensive Rust 🦀" -#: src/running-the-course/course-structure.md:47 +#: src/running-the-course/course-structure.md:50 +#, fuzzy msgid "" -"The [Concurrency Deep Dive](../concurrency.md) is a full day class on " -"classical as well as `async`/`await` concurrency." +"The [Concurrency in Rust](../concurrency.md) deep dive is a full day class " +"on classical as well as `async`/`await` concurrency." msgstr "" "Der [Nebensläufgkeitsvertiefung](../concurrency.md) ist ein ganztägiger Kurs " "zur klassischen sowie „async“/„await“-Parallelität." -#: src/running-the-course/course-structure.md:50 +#: src/running-the-course/course-structure.md:53 msgid "" "You will need a fresh crate set up and the dependencies downloaded and ready " "to go. You can then copy/paste the examples into `src/main.rs` to experiment " @@ -1430,21 +1465,11 @@ msgstr "" "Du die Beispiele kopieren und in `src/main.rs` einfügen, um damit zu " "experimentieren:" -#: src/running-the-course/course-structure.md:54 -msgid "" -"```shell\n" -"cargo init concurrency\n" -"cd concurrency\n" -"cargo add tokio --features full\n" -"cargo run\n" -"```" -msgstr "" - -#: src/running-the-course/course-structure.md:61 +#: src/running-the-course/course-structure.md:64 msgid "Format" msgstr "Format" -#: src/running-the-course/course-structure.md:63 +#: src/running-the-course/course-structure.md:66 msgid "" "The course is meant to be very interactive and we recommend letting the " "questions drive the exploration of Rust!" @@ -1495,60 +1520,108 @@ msgid "" msgstr "Der Kurs wurde auch in andere Sprachen übersetzt:" #: src/running-the-course/translations.md:6 +#, fuzzy msgid "" "[Brazilian Portuguese](https://google.github.io/comprehensive-rust/pt-BR/) " -"by [@rastringer](https://github.com/rastringer) and [@hugojacob](https://" -"github.com/hugojacob)." +"by [@rastringer](https://github.com/rastringer), [@hugojacob](https://github." +"com/hugojacob), [@joaovicmendes](https://github.com/joaovicmendes), and " +"[@henrif75](https://github.com/henrif75)." msgstr "" "[Brasilianisches Portugiesisch](https://google.github.io/comprehensive-rust/" "pt-BR/) von [@rastringer](https://github.com/rastringer) und [@hugojacob]" "(https://github.com/hugojacob)." #: src/running-the-course/translations.md:7 +#, fuzzy msgid "" "[Korean](https://google.github.io/comprehensive-rust/ko/) by [@keispace]" -"(https://github.com/keispace), [@jiyongp](https://github.com/jiyongp) and " +"(https://github.com/keispace), [@jiyongp](https://github.com/jiyongp), and " "[@jooyunghan](https://github.com/jooyunghan)." msgstr "" "[Koreanisch](https://google.github.io/comprehensive-rust/ko/) von [@keispace]" "(https://github.com/keispace), [@jiyongp](https://github.com/jiyongp) und " "[@jooyunghan](https://github.com/jooyunghan)." -#: src/running-the-course/translations.md:9 +#: src/running-the-course/translations.md:8 +#, fuzzy +msgid "" +"[Spanish](https://google.github.io/comprehensive-rust/es/) by [@deavid]" +"(https://github.com/deavid)." +msgstr "" +"[Brasilianisches Portugiesisch](https://google.github.io/comprehensive-rust/" +"pt-BR/) von [@rastringer](https://github.com/rastringer) und [@hugojacob]" +"(https://github.com/hugojacob)." + +#: src/running-the-course/translations.md:10 msgid "" "Use the language picker in the top-right corner to switch between languages." msgstr "Benutze die Sprachenauswahl oben rechts, um die Sprache zu wechseln." -#: src/running-the-course/translations.md:11 +#: src/running-the-course/translations.md:12 msgid "Incomplete Translations" msgstr "Angefangene Übersetzungen" -#: src/running-the-course/translations.md:13 +#: src/running-the-course/translations.md:14 msgid "" "There is a large number of in-progress translations. We link to the most " "recently updated translations:" msgstr "" -#: src/running-the-course/translations.md:16 +#: src/running-the-course/translations.md:17 +#, fuzzy +msgid "" +"[Bengali](https://google.github.io/comprehensive-rust/bn/) by [@raselmandol]" +"(https://github.com/raselmandol)." +msgstr "" +"[Brasilianisches Portugiesisch](https://google.github.io/comprehensive-rust/" +"pt-BR/) von [@rastringer](https://github.com/rastringer) und [@hugojacob]" +"(https://github.com/hugojacob)." + +#: src/running-the-course/translations.md:18 +#, fuzzy +msgid "" +"[Chinese (Traditional)](https://google.github.io/comprehensive-rust/zh-TW/) " +"by [@hueich](https://github.com/hueich), [@victorhsieh](https://github.com/" +"victorhsieh), [@mingyc](https://github.com/mingyc), and [@johnathan79717]" +"(https://github.com/johnathan79717)." +msgstr "" +"[Koreanisch](https://google.github.io/comprehensive-rust/ko/) von [@keispace]" +"(https://github.com/keispace), [@jiyongp](https://github.com/jiyongp) und " +"[@jooyunghan](https://github.com/jooyunghan)." + +#: src/running-the-course/translations.md:19 +#, fuzzy +msgid "" +"[Chinese (Simplified)](https://google.github.io/comprehensive-rust/zh-CN/) " +"by [@suetfei](https://github.com/suetfei), [@wnghl](https://github.com/" +"wnghl), [@anlunx](https://github.com/anlunx), [@kongy](https://github.com/" +"kongy), [@noahdragon](https://github.com/noahdragon), and [@superwhd]" +"(https://github.com/superwhd)." +msgstr "" +"[Koreanisch](https://google.github.io/comprehensive-rust/ko/) von [@keispace]" +"(https://github.com/keispace), [@jiyongp](https://github.com/jiyongp) und " +"[@jooyunghan](https://github.com/jooyunghan)." + +#: src/running-the-course/translations.md:20 msgid "" "[French](https://google.github.io/comprehensive-rust/fr/) by [@KookaS]" "(https://github.com/KookaS) and [@vcaen](https://github.com/vcaen)." msgstr "" -#: src/running-the-course/translations.md:17 +#: src/running-the-course/translations.md:21 msgid "" "[German](https://google.github.io/comprehensive-rust/de/) by [@Throvn]" "(https://github.com/Throvn) and [@ronaldfw](https://github.com/ronaldfw)." msgstr "" -#: src/running-the-course/translations.md:18 +#: src/running-the-course/translations.md:22 msgid "" "[Japanese](https://google.github.io/comprehensive-rust/ja/) by [@CoinEZ-JPN]" "(https://github.com/CoinEZ) and [@momotaro1105](https://github.com/" "momotaro1105)." msgstr "" -#: src/running-the-course/translations.md:20 +#: src/running-the-course/translations.md:24 msgid "" "If you want to help with this effort, please see [our instructions](https://" "github.com/google/comprehensive-rust/blob/main/TRANSLATIONS.md) for how to " @@ -1579,77 +1652,42 @@ msgid "Installation" msgstr "Installation" #: src/cargo.md:10 -msgid "Rustup (Recommended)" -msgstr "Rustup (empfohlen)" +msgid "**Please follow the instructions on .**" +msgstr "" #: src/cargo.md:12 +#, fuzzy msgid "" -"You can follow the instructions to install cargo and rust compiler, among " -"other standard ecosystem tools with the [rustup](https://rust-analyzer." -"github.io/) tool, which is maintained by the Rust Foundation." -msgstr "" -"Du kannst den Anweisungen zur Installation von Cargo und des Rust-Compilers " -"sowie anderer Standard-Ökosystem-Tools mit dem Tool [rustup](https://rust-" -"analyzer.github.io/) folgen, das von der Rust Foundation verwaltet wird." - -#: src/cargo.md:14 -msgid "" -"Along with cargo and rustc, Rustup will install itself as a command line " -"utility that you can use to install/switch toolchains, setup cross " -"compilation, etc." +"This will give you the Cargo build tool (`cargo`) and the Rust compiler " +"(`rustc`). You will also get `rustup`, a command line utility that you can " +"use to install to different compiler versions." msgstr "" "Neben cargo und rustc installiert sich rustup selbst als " "Befehlszeilenprogramm, mit welchem du Toolchains installieren/wechseln, oder " "cross-Kompilierung einrichten kannst." -#: src/cargo.md:16 -msgid "Package Managers" -msgstr "Paketmanager" +#: src/cargo.md:14 +msgid "" +"After installing Rust, you should configure your editor or IDE to work with " +"Rust. Most editors do this by talking to [rust-analyzer](https://rust-" +"analyzer.github.io/), which provides auto-completion and jump-to-definition " +"functionality for [VS Code](https://code.visualstudio.com/), [Emacs](https://" +"rust-analyzer.github.io/manual.html#emacs), [Vim/Neovim](https://rust-" +"analyzer.github.io/manual.html#vimneovim), and many others. There is also a " +"different IDE available called [RustRover](https://www.jetbrains.com/rust/)." +msgstr "" #: src/cargo.md:18 -msgid "Debian" -msgstr "Debian" - -#: src/cargo.md:20 +#, fuzzy msgid "" -"On Debian/Ubuntu, you can install Cargo, the Rust source and the [Rust " -"formatter](https://github.com/rust-lang/rustfmt) with" +"On Debian/Ubuntu, you can also install Cargo, the Rust source and the [Rust " +"formatter](https://github.com/rust-lang/rustfmt) via `apt`. However, this " +"gets you an outdated rust version and may lead to unexpected behavior. The " +"command would be:" msgstr "" "Auf Debian/Ubuntu kannst du Cargo und den Rust Quellcode wie folgt " "installieren" -#: src/cargo.md:22 -msgid "" -"```shell\n" -"$ sudo apt install cargo rust-src rustfmt\n" -"```" -msgstr "" - -#: src/cargo.md:26 -msgid "" -"This will allow \\[rust-analyzer\\]\\[1\\] to jump to the definitions. We " -"suggest using [VS Code](https://code.visualstudio.com/) to edit the code " -"(but any LSP compatible editor works)." -msgstr "" -"Dadurch kann \\[rust-analyzer\\]\\[1\\] zu den Definitionen springen. Wir " -"empfehlen die Verwendung von [VS Code](https://code.visualstudio.com/), um " -"Code zu bearbeiten (aber jeder LSP-kompatible Editor funktioniert auch)." - -#: src/cargo.md:29 -msgid "" -"Some folks also like to use the [JetBrains](https://www.jetbrains.com/" -"clion/) family of IDEs, which do their own analysis but have their own " -"tradeoffs. If you prefer them, you can install the [Rust Plugin](https://www." -"jetbrains.com/rust/). Please take note that as of January 2023 debugging " -"only works on the CLion version of the JetBrains IDEA suite." -msgstr "" -"Einige Leute verwenden auch gerne die [JetBrains](https://www.jetbrains.com/" -"clion/)\\-Familie von IDEs, die eigene Code-Analysen durchführen, aber auch " -"eigene Einschränkungen haben. Wenn du diese IDEs bevorzugst, kannst du das " -"\\[Rust-Plugin\\] [5](https://www.jetbrains.com/rust/) installieren. Bitte " -"beachte, dass das Debuggen seit Januar 2023 nur auf der CLion-Version " -"funktioniert, welche Teil der JetBrains IDEA-Suite ist." - #: src/cargo/rust-ecosystem.md:1 msgid "The Rust Ecosystem" msgstr "Das Rust-Ökosystem" @@ -1674,9 +1712,9 @@ msgstr "" #, fuzzy msgid "" "`cargo`: the Rust dependency manager and build tool. Cargo knows how to " -"download dependencies hosted on and it will pass them to " -"`rustc` when building your project. Cargo also comes with a built-in test " -"runner which is used to execute unit tests." +"download dependencies, usually hosted on , and it will " +"pass them to `rustc` when building your project. Cargo also comes with a " +"built-in test runner which is used to execute unit tests." msgstr "" "`cargo`: der Rust-Abhängigkeitsmanager (Dependency manager) und das " "Bauwerkzeug (Build-Tool). Cargo weiß, wie die Abhängigkeiten heruntergeladen " @@ -1698,6 +1736,7 @@ msgstr "" #: src/why-rust/modern.md:21 src/basic-syntax/compound-types.md:30 #: src/basic-syntax/references.md:23 #: src/pattern-matching/destructuring-enums.md:35 +#: src/ownership/double-free-modern-cpp.md:55 #: src/error-handling/try-operator.md:48 #: src/error-handling/converting-error-types-example.md:50 #: src/concurrency/threads.md:30 src/async/async-await.md:25 @@ -1729,19 +1768,25 @@ msgstr "" #: src/cargo/rust-ecosystem.md:32 msgid "" +"Dependencies can also be resolved from alternative [registries](https://doc." +"rust-lang.org/cargo/reference/registries.html), git, folders, and more." +msgstr "" + +#: src/cargo/rust-ecosystem.md:34 +msgid "" "Rust also has [editions](https://doc.rust-lang.org/edition-guide/): the " "current edition is Rust 2021. Previous editions were Rust 2015 and Rust 2018." msgstr "" "Rust hat auch \\[Editionen\\]: Die aktuelle Edition ist Rust 2021. Vorherige " "Editionen waren Rust 2015 und Rust 2018." -#: src/cargo/rust-ecosystem.md:35 +#: src/cargo/rust-ecosystem.md:37 msgid "" "The editions are allowed to make backwards incompatible changes to the " "language." msgstr "Editionen dürfen rückwärtsinkompatible Änderungen vornehmen." -#: src/cargo/rust-ecosystem.md:38 +#: src/cargo/rust-ecosystem.md:40 msgid "" "To prevent breaking code, editions are opt-in: you select the edition for " "your crate via the `Cargo.toml` file." @@ -1749,7 +1794,7 @@ msgstr "" "Um zu verhindern, dass Code nicht kaputt geht, sind Editionen optional: Du " "wählst ihre Edition für deine Kiste (crate) in der Datei `Cargo.toml`" -#: src/cargo/rust-ecosystem.md:41 +#: src/cargo/rust-ecosystem.md:43 msgid "" "To avoid splitting the ecosystem, Rust compilers can mix code written for " "different editions." @@ -1757,7 +1802,7 @@ msgstr "" "Um eine Aufspaltung des Ökosystems zu vermeiden, können Rust-Compiler Code " "der für verschiedene Editionen geschrieben wurde vermischen." -#: src/cargo/rust-ecosystem.md:44 +#: src/cargo/rust-ecosystem.md:46 msgid "" "Mention that it is quite rare to ever use the compiler directly not through " "`cargo` (most users never do)." @@ -1765,7 +1810,7 @@ msgstr "" "Erwähne, dass es ziemlich selten vorkommt, dass der Compiler jemals direkt " "und nicht über `cargo` verwendet wird (die meisten Benutzer tun dies nie)." -#: src/cargo/rust-ecosystem.md:46 +#: src/cargo/rust-ecosystem.md:48 msgid "" "It might be worth alluding that Cargo itself is an extremely powerful and " "comprehensive tool. It is capable of many advanced features including but " @@ -1775,32 +1820,32 @@ msgstr "" "und umfassendes Tool ist. Es verfügt über viele erweiterte Funktionen, " "einschließlich, aber nicht beschränkt auf:" -#: src/cargo/rust-ecosystem.md:47 +#: src/cargo/rust-ecosystem.md:49 msgid "Project/package structure" msgstr "Projekt-/Paketstruktur" -#: src/cargo/rust-ecosystem.md:48 +#: src/cargo/rust-ecosystem.md:50 msgid "[workspaces](https://doc.rust-lang.org/cargo/reference/workspaces.html)" msgstr "\\[Arbeitsbereiche\\]" -#: src/cargo/rust-ecosystem.md:49 +#: src/cargo/rust-ecosystem.md:51 msgid "Dev Dependencies and Runtime Dependency management/caching" msgstr "" "Verwaltung/Caching von Entwicklungsabhängigkeiten und Laufzeitabhängigkeiten" -#: src/cargo/rust-ecosystem.md:50 +#: src/cargo/rust-ecosystem.md:52 msgid "" "[build scripting](https://doc.rust-lang.org/cargo/reference/build-scripts." "html)" msgstr "\\[Build-Skripting\\]" -#: src/cargo/rust-ecosystem.md:51 +#: src/cargo/rust-ecosystem.md:53 msgid "" "[global installation](https://doc.rust-lang.org/cargo/commands/cargo-install." "html)" msgstr "\\[globale Installation\\]" -#: src/cargo/rust-ecosystem.md:52 +#: src/cargo/rust-ecosystem.md:54 msgid "" "It is also extensible with sub command plugins as well (such as [cargo " "clippy](https://github.com/rust-lang/rust-clippy))." @@ -1808,7 +1853,7 @@ msgstr "" "Es ist auch mit Unterbefehls-Plugins erweiterbar (z. B. [cargo clippy]" "(https://github.com/rust-lang/rust-clippy))." -#: src/cargo/rust-ecosystem.md:53 +#: src/cargo/rust-ecosystem.md:55 msgid "" "Read more from the [official Cargo Book](https://doc.rust-lang.org/cargo/)" msgstr "Lese mehr aus dem \\[offiziellen Cargo Buch\\]" @@ -1906,17 +1951,13 @@ msgstr "" "hervorbringen. Zum Verfassungszeitpunkt hat die neueste stabile Rust-Version " "folgende Versionsnummer:" -#: src/cargo/running-locally.md:8 +#: src/cargo/running-locally.md:15 msgid "" -"```shell\n" -"% rustc --version\n" -"rustc 1.69.0 (84c898d65 2023-04-16)\n" -"% cargo --version\n" -"cargo 1.69.0 (6e9a83356 2023-04-12)\n" -"```" +"You can use any later version too since Rust maintains backwards " +"compatibility." msgstr "" -#: src/cargo/running-locally.md:15 +#: src/cargo/running-locally.md:17 msgid "" "With this in place, follow these steps to build a Rust binary from one of " "the examples in this training:" @@ -1924,59 +1965,27 @@ msgstr "" "Wenn dies vorhanden ist, befolge die folgenden Schritte, um eine Rust-" "Binärdatei aus einem Beispiel zu erstellen:" -#: src/cargo/running-locally.md:18 +#: src/cargo/running-locally.md:20 msgid "Click the \"Copy to clipboard\" button on the example you want to copy." msgstr "" "Klicke bei dem Beispiel, dass Du kopieren möchtest, auf die Schaltfläche „In " "die Zwischenablage kopieren“." -#: src/cargo/running-locally.md:20 +#: src/cargo/running-locally.md:22 msgid "" "Use `cargo new exercise` to create a new `exercise/` directory for your code:" msgstr "" "Verwende `cargo new exercise`, um ein neues `exercise/`\\-Verzeichnis für " "Deinen Code zu erstellen:" -#: src/cargo/running-locally.md:22 -msgid "" -"```shell\n" -"$ cargo new exercise\n" -" Created binary (application) `exercise` package\n" -"```" -msgstr "" -"```shell\n" -"$ cargo new exercise\n" -" Created binary (application) `exercise` package\n" -"```" - -#: src/cargo/running-locally.md:27 +#: src/cargo/running-locally.md:29 msgid "" "Navigate into `exercise/` and use `cargo run` to build and run your binary:" msgstr "" "Navigiere zu `exercise/` und verwende \\`cargo run, um eine Binärdatei zu " "erstellen und auszuführen:" -#: src/cargo/running-locally.md:29 -msgid "" -"```shell\n" -"$ cd exercise\n" -"$ cargo run\n" -" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n" -" Finished dev [unoptimized + debuginfo] target(s) in 0.75s\n" -" Running `target/debug/exercise`\n" -"Hello, world!\n" -"```" -msgstr "" -"```shell\n" -"$ cd exercise\n" -"$ cargo run\n" -" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n" -" Finished dev [unoptimized + debuginfo] target(s) in 0.75s\n" -" Running `target/debug/exercise`\n" -"Hello, world!\n" -"```" - -#: src/cargo/running-locally.md:38 +#: src/cargo/running-locally.md:40 msgid "" "Replace the boiler-plate code in `src/main.rs` with your own code. For " "example, using the example on the previous page, make `src/main.rs` look like" @@ -1985,7 +1994,7 @@ msgstr "" "beispielsweise das Beispiel auf der vorherigen Seite und lasse `src/main.rs` " "so aussehen:" -#: src/cargo/running-locally.md:41 +#: src/cargo/running-locally.md:43 msgid "" "```rust\n" "fn main() {\n" @@ -1999,30 +2008,12 @@ msgstr "" "}\n" "```" -#: src/cargo/running-locally.md:47 +#: src/cargo/running-locally.md:49 msgid "Use `cargo run` to build and run your updated binary:" msgstr "" "Verwende `cargo run`, um die neue Binärdatei zu erstellen und auszuführen:" -#: src/cargo/running-locally.md:49 -msgid "" -"```shell\n" -"$ cargo run\n" -" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n" -" Finished dev [unoptimized + debuginfo] target(s) in 0.24s\n" -" Running `target/debug/exercise`\n" -"Edit me!\n" -"```" -msgstr "" -"```shell\n" -"$ cargo run\n" -" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n" -" Finished dev [unoptimized + debuginfo] target(s) in 0.24s\n" -" Running `target/debug/exercise`\n" -"Edit me!\n" -"```" - -#: src/cargo/running-locally.md:57 +#: src/cargo/running-locally.md:59 msgid "" "Use `cargo check` to quickly check your project for errors, use `cargo " "build` to compile it without running it. You will find the output in `target/" @@ -2035,7 +2026,7 @@ msgstr "" "Verwende `cargo build --release`, um einen optimierten Release-Build in " "`target/release/` zu erstellen." -#: src/cargo/running-locally.md:62 +#: src/cargo/running-locally.md:64 msgid "" "You can add dependencies for your project by editing `Cargo.toml`. When you " "run `cargo` commands, it will automatically download and compile missing " @@ -2045,7 +2036,7 @@ msgstr "" "Du `Cargo.toml` bearbeitest. Wenn Du `cargo`\\-Befehle ausführst, werden " "fehlende Abhängigkeiten automatisch heruntergeladen und für Dich kompiliert." -#: src/cargo/running-locally.md:70 +#: src/cargo/running-locally.md:72 msgid "" "Try to encourage the class participants to install Cargo and use a local " "editor. It will make their life easier since they will have a normal " @@ -2060,8 +2051,9 @@ msgid "Welcome to Day 1" msgstr "Willkommen zu Tag 1" #: src/welcome-day-1.md:3 +#, fuzzy msgid "" -"This is the first day of Comprehensive Rust. We will cover a lot of ground " +"This is the first day of Rust Fundamentals. We will cover a lot of ground " "today:" msgstr "" "Dies ist der erste Tag von Comprehensive Rust. Heute werden wir viel " @@ -2078,19 +2070,13 @@ msgstr "" #: src/welcome-day-1.md:9 msgid "" -"Memory management: stack vs heap, manual memory management, scope-based " -"memory management, and garbage collection." +"Control flow constructs: `if`, `if let`, `while`, `while let`, `break`, and " +"`continue`." msgstr "" -"Speicherverwaltung: Stack vs. Heap, manuelle Speicherverwaltung, " -"bereichsbasierte Speicherverwaltung und Speicherbereinigung (garbage " -"collection)." #: src/welcome-day-1.md:12 -msgid "" -"Ownership: move semantics, copying and cloning, borrowing, and lifetimes." +msgid "Pattern matching: destructuring enums, structs, and arrays." msgstr "" -"Eigentum (ownership): Bewegungssemantik (move semantics), Kopieren und " -"Klonen (copy and cloning), Ausleihen (borrowing) und Lebensdauer (lifetimes)." #: src/welcome-day-1.md:16 msgid "Please remind the students that:" @@ -2245,7 +2231,9 @@ msgid "High level of control." msgstr "Hohes Maß an Kontrolle." #: src/welcome-day-1/what-is-rust.md:25 -msgid "Can be scaled down to very constrained devices like mobile phones." +#, fuzzy +msgid "" +"Can be scaled down to very constrained devices such as microcontrollers." msgstr "" "Kann auf sehr eingeschränkte Geräte wie Mobiltelefone herunterskaliert " "werden." @@ -2304,9 +2292,10 @@ msgstr "" "enthalten." #: src/hello-world.md:22 +#, fuzzy msgid "" "This slide tries to make the students comfortable with Rust code. They will " -"see a ton of it over the next four days so we start small with something " +"see a ton of it over the next three days so we start small with something " "familiar." msgstr "" "Diese Folie versucht, die Schüler mit Rust-Code vertraut zu machen. Sie " @@ -2314,10 +2303,10 @@ msgstr "" "und mit etwas Vertrautem an." #: src/hello-world.md:27 +#, fuzzy msgid "" "Rust is very much like other languages in the C/C++/Java tradition. It is " -"imperative (not functional) and it doesn't try to reinvent things unless " -"absolutely necessary." +"imperative and it doesn't try to reinvent things unless absolutely necessary." msgstr "" "Rust ist anderen Sprachen in der C/C++/Java-Tradition sehr ähnlich. Es ist " "Imperativ (nicht funktional) und es wird nicht versucht, Dinge neu zu " @@ -2348,6 +2337,14 @@ msgstr "" "Rust-Makros sind eigentlich nur [teilweise hygienisch](https://veykril." "github.io/tlborm/decl-macros/minutiae/hygiene.html)." +#: src/hello-world.md:40 +msgid "" +"Rust is multi-paradigm. For example, it has powerful [object-oriented " +"programming features](https://doc.rust-lang.org/book/ch17-00-oop.html), and, " +"while it is not a functional language, it includes a range of [functional " +"concepts](https://doc.rust-lang.org/book/ch13-00-functional-features.html)." +msgstr "" + #: src/hello-world/small-example.md:3 msgid "Here is a small example program in Rust:" msgstr "Hier ein kleines Beispielprogramm in Rust:" @@ -2424,6 +2421,12 @@ msgstr "" "Formatierungs-Minisprache enthält. Es ist wichtig, dass die Kursteilnehmer " "mit der Suche in der Standardbibliothek vertraut gemacht werden." +#: src/hello-world/small-example.md:44 +msgid "" +"In a shell `rustup doc std::fmt` will open a browser on the local std::fmt " +"documentation" +msgstr "" + #: src/why-rust.md:3 msgid "Some unique selling points of Rust:" msgstr "Einige Alleinstellungsmerkmale von Rust:" @@ -2574,15 +2577,19 @@ msgid "Array access is bounds checked." msgstr "Der Array-Zugriff wird auf Grenzen geprüft." #: src/why-rust/runtime.md:6 -msgid "Integer overflow is defined." +#, fuzzy +msgid "Integer overflow is defined (panic or wrap-around)." msgstr "Ganzzahlüberlauf ist definiert." #: src/why-rust/runtime.md:12 +#, fuzzy msgid "" -"Integer overflow is defined via a compile-time flag. The options are either " -"a panic (a controlled crash of the program) or wrap-around semantics. By " -"default, you get panics in debug mode (`cargo build`) and wrap-around in " -"release mode (`cargo build --release`)." +"Integer overflow is defined via the [`overflow-checks`](https://doc.rust-" +"lang.org/rustc/codegen-options/index.html#overflow-checks) compile-time " +"flag. If enabled, the program will panic (a controlled crash of the " +"program), otherwise you get wrap-around semantics. By default, you get " +"panics in debug mode (`cargo build`) and wrap-around in release mode (`cargo " +"build --release`)." msgstr "" "Ganzzahlüberlauf (integer overflow) wird über ein Flag zur Kompilierzeit " "definiert. Die Optionen sind entweder ein kontrollierter Abbruch des " @@ -2590,7 +2597,7 @@ msgstr "" "einen Abbruch (panic) im Debug-Modus (`cargo build`) und ein Wrap-Around im " "Release-Modus (`cargo build --release`)." -#: src/why-rust/runtime.md:17 +#: src/why-rust/runtime.md:18 msgid "" "Bounds checking cannot be disabled with a compiler flag. It can also not be " "disabled directly with the `unsafe` keyword. However, `unsafe` allows you to " @@ -2603,7 +2610,8 @@ msgstr "" "mit `unsafe` aufrufen was keine Grenzenprüfung durchführt." #: src/why-rust/modern.md:3 -msgid "Rust is built with all the experience gained in the last 40 years." +#, fuzzy +msgid "Rust is built with all the experience gained in the last decades." msgstr "Rust wurde mit vielen Erfahrungen aus den letzten 40 Jahren gebaut." #: src/why-rust/modern.md:5 @@ -2797,7 +2805,7 @@ msgstr "`i8`, `i16`, `i32`, `i64`, `i128`, `isize`" #: src/basic-syntax/scalar-types.md:5 #, fuzzy -msgid "`-10`, `0`, `1_000`, `123i64`" +msgid "`-10`, `0`, `1_000`, `123_i64`" msgstr "`-10`, `0`, `1_000`, `123i64`" #: src/basic-syntax/scalar-types.md:6 @@ -2812,7 +2820,7 @@ msgstr "`0`, `123`, `10u16`" #: src/basic-syntax/scalar-types.md:6 #, fuzzy -msgid "`0`, `123`, `10u16`" +msgid "`0`, `123`, `10_u16`" msgstr "Fließkommazahlen" #: src/basic-syntax/scalar-types.md:7 @@ -2827,7 +2835,7 @@ msgstr "`3.14`, `-10.0e20`, `2f32`" #: src/basic-syntax/scalar-types.md:7 #, fuzzy -msgid "`3.14`, `-10.0e20`, `2f32`" +msgid "`3.14`, `-10.0e20`, `2_f32`" msgstr "Zeichenketten (Strings)" #: src/basic-syntax/scalar-types.md:8 @@ -2887,11 +2895,13 @@ msgid "`isize` and `usize` are the width of a pointer," msgstr "`isize` und `usize` sind die Breite eines Zeigers," #: src/basic-syntax/scalar-types.md:16 -msgid "`char` is 32 bit wide," +#, fuzzy +msgid "`char` is 32 bits wide," msgstr "`char` ist 32 Bit breit," #: src/basic-syntax/scalar-types.md:17 -msgid "`bool` is 8 bit wide." +#, fuzzy +msgid "`bool` is 8 bits wide." msgstr "`bool` ist 8 Bit breit." #: src/basic-syntax/scalar-types.md:21 @@ -2945,6 +2955,13 @@ msgstr "" "}\n" "```" +#: src/basic-syntax/scalar-types.md:43 +msgid "" +"All underscores in numbers can be left out, they are for legibility only. So " +"`1_000` can be written as `1000` (or `10_00`), and `123_i64` can be written " +"as `123i64`." +msgstr "" + #: src/basic-syntax/compound-types.md:5 msgid "Arrays" msgstr "Arrays" @@ -3004,11 +3021,12 @@ msgid "Arrays:" msgstr "Arrays:" #: src/basic-syntax/compound-types.md:34 +#, fuzzy msgid "" -"Arrays have elements of the same type, `T`, and length, `N`, which is a " -"compile-time constant. Note that the length of the array is _part of its " -"type_, which means that `[u8; 3]` and `[u8; 4]` are considered two different " -"types." +"A value of the array type `[T; N]` holds `N` (a compile-time constant) " +"elements of the same type `T`. Note that the length of the array is _part of " +"its type_, which means that `[u8; 3]` and `[u8; 4]` are considered two " +"different types." msgstr "" "Arrays haben Elemente desselben Typs `T` und der Länge `N`, was eine " "Konstante zur Kompilierungszeit ist. Beachten Sie, dass die Länge des Arrays " @@ -3187,24 +3205,26 @@ msgstr "" msgid "" "```rust,editable\n" "fn main() {\n" -" let a: [i32; 6] = [10, 20, 30, 40, 50, 60];\n" +" let mut a: [i32; 6] = [10, 20, 30, 40, 50, 60];\n" " println!(\"a: {a:?}\");\n" "\n" " let s: &[i32] = &a[2..4];\n" +"\n" " println!(\"s: {s:?}\");\n" "}\n" "```" msgstr "" -#: src/basic-syntax/slices.md:15 +#: src/basic-syntax/slices.md:16 msgid "Slices borrow data from the sliced type." msgstr "Anteilstypen (slices) borgen (borrow) Daten vom Sliced-Typ." -#: src/basic-syntax/slices.md:16 -msgid "Question: What happens if you modify `a[3]`?" +#: src/basic-syntax/slices.md:17 +#, fuzzy +msgid "Question: What happens if you modify `a[3]` right before printing `s`?" msgstr "Frage: Was passiert, wenn Du `a[3]` änderst?" -#: src/basic-syntax/slices.md:20 +#: src/basic-syntax/slices.md:21 msgid "" "We create a slice by borrowing `a` and specifying the starting and ending " "indexes in brackets." @@ -3212,7 +3232,7 @@ msgstr "" "Wir erstellen ein Anteilstyp, indem wir `a` ausleihen (borrow) und den " "Start- und Endindex in Klammern angeben." -#: src/basic-syntax/slices.md:22 +#: src/basic-syntax/slices.md:23 msgid "" "If the slice starts at index 0, Rust’s range syntax allows us to drop the " "starting index, meaning that `&a[0..a.len()]` and `&a[..a.len()]` are " @@ -3222,7 +3242,7 @@ msgstr "" "Rust, den Startindex wegzulassen, was bedeutet, dass `&a[0..a.len()]` und " "`&a[..a.len()]` identisch sind." -#: src/basic-syntax/slices.md:24 +#: src/basic-syntax/slices.md:25 msgid "" "The same is true for the last index, so `&a[2..a.len()]` and `&a[2..]` are " "identical." @@ -3230,14 +3250,14 @@ msgstr "" "Das Gleiche gilt für den letzten Index, daher sind `&a[2..a.len()]` und " "`&a[2..]` identisch." -#: src/basic-syntax/slices.md:26 +#: src/basic-syntax/slices.md:27 msgid "" "To easily create a slice of the full array, we can therefore use `&a[..]`." msgstr "" "Um einfach einen Anteilstyp des gesamten Arrays zu erstellen, können wir " "daher „&a\\[..\\]“ verwenden." -#: src/basic-syntax/slices.md:28 +#: src/basic-syntax/slices.md:29 msgid "" "`s` is a reference to a slice of `i32`s. Notice that the type of `s` " "(`&[i32]`) no longer mentions the array length. This allows us to perform " @@ -3247,7 +3267,7 @@ msgstr "" "Typ `s` (`&[i32]`) die Array-Länge nicht mehr erwähnt. Dadurch können wir " "Berechnungen für Anteilstypen unterschiedlicher Größe durchführen." -#: src/basic-syntax/slices.md:30 +#: src/basic-syntax/slices.md:31 msgid "" "Slices always borrow from another object. In this example, `a` has to remain " "'alive' (in scope) for at least as long as our slice. " @@ -3256,12 +3276,15 @@ msgstr "" "Objekt aus. In diesem Beispiel muss `a` mindestens so lange (im " "Gültigkeitsbereich (scope)) „lebendig“ bleiben wie unser Anteilstyp." -#: src/basic-syntax/slices.md:32 +#: src/basic-syntax/slices.md:33 +#, fuzzy msgid "" "The question about modifying `a[3]` can spark an interesting discussion, but " -"the answer is that for memory safety reasons you cannot do it through `a` " -"after you created a slice, but you can read the data from both `a` and `s` " -"safely. More details will be explained in the borrow checker section." +"the answer is that for memory safety reasons you cannot do it through `a` at " +"this point in the execution, but you can read the data from both `a` and `s` " +"safely. It works before you created the slice, and again after the " +"`println`, when the slice is no longer used. More details will be explained " +"in the borrow checker section." msgstr "" "Die Frage nach einer Werteänderung durch `a[3]` kann eine interessante " "Diskussion auslösen, aber die Antwort lautet: aus Gründen der " @@ -3511,6 +3534,13 @@ msgstr "" "Inner doc Kommentare werden später besprochen (auf der Seite zu Modulen) und " "müssen hier nicht behandelt werden." +#: src/basic-syntax/rustdoc.md:33 +msgid "" +"Rustdoc comments can contain code snippets that we can run and test using " +"`cargo test`. We will discuss these tests in the [Testing section](../" +"testing/doc-tests.html)." +msgstr "" + #: src/basic-syntax/methods.md:3 msgid "" "Methods are functions associated with a type. The `self` argument of a " @@ -3556,29 +3586,25 @@ msgstr "" "Methoden befassen." #: src/basic-syntax/methods.md:34 -msgid "Add a `Rectangle::new` constructor and call this from `main`:" +#, fuzzy +msgid "Add a static method called `Rectangle::new` and call this from `main`:" msgstr "" "Füge einen `Rectangle::new`\\-Konstruktor hinzu und rufe diesen von `main` " "aus auf:" -#: src/basic-syntax/methods.md:36 -msgid "" -"```rust,editable,compile_fail\n" -"fn new(width: u32, height: u32) -> Rectangle {\n" -" Rectangle { width, height }\n" -"}\n" -"```" -msgstr "" -"```rust,editable,compile_fail\n" -"fn new(width: u32, height: u32) -> Rectangle {\n" -" Rectangle { width, height }\n" -"}\n" -"```" - #: src/basic-syntax/methods.md:42 msgid "" -"Add a `Rectangle::new_square(width: u32)` constructor to illustrate that " -"constructors can take arbitrary parameters." +"While _technically_, Rust does not have custom constructors, static methods " +"are commonly used to initialize structs (but don't have to). The actual " +"constructor, `Rectangle { width, height }`, could be called directly. See " +"the [Rustnomicon](https://doc.rust-lang.org/nomicon/constructors.html)." +msgstr "" + +#: src/basic-syntax/methods.md:45 +#, fuzzy +msgid "" +"Add a `Rectangle::square(width: u32)` constructor to illustrate that such " +"static methods can take arbitrary parameters." msgstr "" "Füge einen `Rectangle::new_square(width: u32)`\\-Konstruktor hinzu, um zu " "veranschaulichen, dass Konstruktoren beliebige Parameter annehmen können." @@ -3686,17 +3712,16 @@ msgstr "" "Die Code-Snippets sind absichtlich nicht editierbar: die Inline-Code-" "Snippets verlieren Deine Änderungen, sobald Du die Seite verlässt." -#: src/exercises/day-1/morning.md:22 src/exercises/day-1/afternoon.md:11 -#: src/exercises/day-2/morning.md:11 src/exercises/day-2/afternoon.md:7 -#: src/exercises/day-3/morning.md:7 src/exercises/bare-metal/morning.md:7 -#: src/exercises/bare-metal/afternoon.md:7 +#: src/exercises/day-1/morning.md:22 src/exercises/day-2/morning.md:11 +#: src/exercises/day-3/morning.md:9 src/exercises/bare-metal/morning.md:7 #: src/exercises/concurrency/morning.md:12 -#: src/exercises/concurrency/afternoon.md:13 +#, fuzzy msgid "" -"After looking at the exercises, you can look at the \\[solutions\\] provided." +"After looking at the exercises, you can look at the [solutions](solutions-" +"morning.md) provided." msgstr "" -"Nachdem Du Dir die Übungen angesehen hast, kannst Du Dir die " -"bereitgestellten \\[Lösungen\\] ansehen." +"Nachdem Sie sich die Übung angesehen haben, können Sie sich die " +"bereitgestellte \\[Lösung\\] ansehen." #: src/exercises/day-1/implicit-conversions.md:3 msgid "" @@ -3798,13 +3823,6 @@ msgstr "Arrays und `for`\\-Schleifen" msgid "We saw that an array can be declared like this:" msgstr "Wir haben gesehen, dass ein Array wie folgt deklariert werden kann:" -#: src/exercises/day-1/for-loops.md:5 -msgid "" -"```rust\n" -"let array = [10, 20, 30];\n" -"```" -msgstr "" - #: src/exercises/day-1/for-loops.md:9 msgid "" "You can print such an array by asking for its debug representation with `{:?}" @@ -3837,7 +3855,7 @@ msgid "" "fn main() {\n" " let array = [10, 20, 30];\n" " print!(\"Iterating over array:\");\n" -" for n in array {\n" +" for n in &array {\n" " print!(\" {n}\");\n" " }\n" " println!();\n" @@ -3943,6 +3961,354 @@ msgstr "" "Die Lösung und die Antwort zum Bonusteil findest Du im Abschnitt [Lösung]" "(solutions-morning.md#arrays-and-for-loops)." +#: src/exercises/day-1/for-loops.md:95 +msgid "" +"The use of the reference `&array` within `for n in &array` is a subtle " +"preview of issues of ownership that will come later in the afternoon." +msgstr "" + +#: src/exercises/day-1/for-loops.md:98 +msgid "Without the `&`..." +msgstr "" + +#: src/exercises/day-1/for-loops.md:99 +msgid "" +"The loop would have been one that consumes the array. This is a change " +"[introduced in the 2021 Edition](https://doc.rust-lang.org/edition-guide/" +"rust-2021/IntoIterator-for-arrays.html)." +msgstr "" + +#: src/exercises/day-1/for-loops.md:102 +msgid "" +"An implicit array copy would have occurred. Since `i32` is a copy type, " +"then `[i32; 3]` is also a copy type." +msgstr "" + +#: src/control-flow.md:3 +#, fuzzy +msgid "" +"As we have seen, `if` is an expression in Rust. It is used to conditionally " +"evaluate one of two blocks, but the blocks can have a value which then " +"becomes the value of the `if` expression. Other control flow expressions " +"work similarly in Rust." +msgstr "" +"Wie wir gesehen haben, ist `if` ein Ausdruck in Rust. Es ist bedingt gewohnt " +"einen von zwei Blöcken auswerten, aber die Blöcke können einen Wert haben, " +"der dann wird der Wert des `if`\\-Ausdrucks. Andere " +"Ablaufsteuerungsausdrücke funktionieren ähnlich in Rost." + +#: src/control-flow/blocks.md:3 +#, fuzzy +msgid "" +"A block in Rust contains a sequence of expressions. Each block has a value " +"and a type, which are those of the last expression of the block:" +msgstr "" +"Ein Block in Rust hat einen Wert und einen Typ: Der Wert ist der letzte " +"Ausdruck der Block:" + +#: src/control-flow/blocks.md:7 +msgid "" +"```rust,editable\n" +"fn main() {\n" +" let x = {\n" +" let y = 10;\n" +" println!(\"y: {y}\");\n" +" let z = {\n" +" let w = {\n" +" 3 + 4\n" +" };\n" +" println!(\"w: {w}\");\n" +" y * w\n" +" };\n" +" println!(\"z: {z}\");\n" +" z - y\n" +" };\n" +" println!(\"x: {x}\");\n" +"}\n" +"```" +msgstr "" + +#: src/control-flow/blocks.md:26 +msgid "" +"If the last expression ends with `;`, then the resulting value and type is " +"`()`." +msgstr "" + +#: src/control-flow/blocks.md:28 +#, fuzzy +msgid "" +"The same rule is used for functions: the value of the function body is the " +"return value:" +msgstr "" +"Die gleiche Regel gilt für Funktionen: Der Wert des Funktionskörpers ist der " +"Rückgabewert:" + +#: src/control-flow/blocks.md:31 +msgid "" +"```rust,editable\n" +"fn double(x: i32) -> i32 {\n" +" x + x\n" +"}\n" +"\n" +"fn main() {\n" +" println!(\"doubled: {}\", double(7));\n" +"}\n" +"```" +msgstr "" + +#: src/control-flow/blocks.md:43 src/enums.md:34 src/enums/sizes.md:28 +#: src/pattern-matching.md:25 src/pattern-matching/match-guards.md:22 +#: src/structs.md:31 src/methods.md:30 src/methods/example.md:46 +#, fuzzy +msgid "Key Points:" +msgstr "Wichtige Punkte:" + +#: src/control-flow/blocks.md:44 +#, fuzzy +msgid "" +"The point of this slide is to show that blocks have a type and value in " +"Rust. " +msgstr "" +"Der Zweck dieser Folie ist es zu zeigen, dass Blöcke in Rust einen Typ und " +"einen Wert haben." + +#: src/control-flow/blocks.md:45 +#, fuzzy +msgid "" +"You can show how the value of the block changes by changing the last line in " +"the block. For instance, adding/removing a semicolon or using a `return`." +msgstr "" +"Sie können zeigen, wie sich der Wert des Blocks ändert, indem Sie die letzte " +"Zeile im Block ändern. Zum Beispiel das Hinzufügen/Entfernen eines " +"Semikolons oder die Verwendung eines `Return`." + +#: src/control-flow/if-expressions.md:1 +#, fuzzy +msgid "`if` expressions" +msgstr "`if`\\-Ausdrücke" + +#: src/control-flow/if-expressions.md:3 +msgid "" +"You use [`if` expressions](https://doc.rust-lang.org/reference/expressions/" +"if-expr.html#if-expressions) exactly like `if` statements in other languages:" +msgstr "" + +#: src/control-flow/if-expressions.md:18 +#, fuzzy +msgid "" +"In addition, you can use `if` as an expression. The last expression of each " +"block becomes the value of the `if` expression:" +msgstr "" +"Darüber hinaus können Sie es als Ausdruck verwenden. Das macht dasselbe wie " +"oben:" + +#: src/control-flow/if-expressions.md:35 +msgid "" +"Because `if` is an expression and must have a particular type, both of its " +"branch blocks must have the same type. Consider showing what happens if you " +"add `;` after `x / 2` in the second example." +msgstr "" + +#: src/control-flow/for-expressions.md:1 +#, fuzzy +msgid "`for` loops" +msgstr "`for`\\-Schleifen" + +#: src/control-flow/for-expressions.md:3 +#, fuzzy +msgid "" +"The [`for` loop](https://doc.rust-lang.org/std/keyword.for.html) is closely " +"related to the [`while let` loop](while-let-expressions.md). It will " +"automatically call `into_iter()` on the expression and then iterate over it:" +msgstr "" +"Der „for“-Ausdruck ist eng verwandt mit dem „while let“-Ausdruck. Es wird " +"Rufen Sie automatisch `into_iter()` für den Ausdruck auf und iterieren Sie " +"dann darüber:" + +#: src/control-flow/for-expressions.md:7 +msgid "" +"```rust,editable\n" +"fn main() {\n" +" let v = vec![10, 20, 30];\n" +"\n" +" for x in v {\n" +" println!(\"x: {x}\");\n" +" }\n" +" \n" +" for i in (0..10).step_by(2) {\n" +" println!(\"i: {i}\");\n" +" }\n" +"}\n" +"```" +msgstr "" + +#: src/control-flow/for-expressions.md:21 +#, fuzzy +msgid "You can use `break` and `continue` here as usual." +msgstr "Sie können hier wie gewohnt `break` und `continue` verwenden." + +#: src/control-flow/for-expressions.md:25 +#, fuzzy +msgid "Index iteration is not a special syntax in Rust for just that case." +msgstr "" +"Index-Iteration ist in Rust keine spezielle Syntax für genau diesen Fall." + +#: src/control-flow/for-expressions.md:26 +#, fuzzy +msgid "`(0..10)` is a range that implements an `Iterator` trait. " +msgstr "„(0..10)“ ist ein Bereich, der ein „Iterator“-Merkmal implementiert." + +#: src/control-flow/for-expressions.md:27 +#, fuzzy +msgid "" +"`step_by` is a method that returns another `Iterator` that skips every other " +"element. " +msgstr "" +"„step_by“ ist eine Methode, die einen weiteren „Iterator“ zurückgibt, der " +"jedes andere Element überspringt." + +#: src/control-flow/for-expressions.md:28 +msgid "" +"Modify the elements in the vector and explain the compiler errors. Change " +"vector `v` to be mutable and the for loop to `for x in v.iter_mut()`." +msgstr "" + +#: src/control-flow/while-expressions.md:1 +#, fuzzy +msgid "`while` loops" +msgstr "`while`\\-Ausdrücke" + +#: src/control-flow/while-expressions.md:3 +msgid "" +"The [`while` keyword](https://doc.rust-lang.org/reference/expressions/loop-" +"expr.html#predicate-loops) works very similar to other languages:" +msgstr "" + +#: src/control-flow/while-expressions.md:6 +msgid "" +"```rust,editable\n" +"fn main() {\n" +" let mut x = 10;\n" +" while x != 1 {\n" +" x = if x % 2 == 0 {\n" +" x / 2\n" +" } else {\n" +" 3 * x + 1\n" +" };\n" +" }\n" +" println!(\"Final x: {x}\");\n" +"}\n" +"```" +msgstr "" + +#: src/control-flow/break-continue.md:1 +#, fuzzy +msgid "`break` and `continue`" +msgstr "`break` und `continue`" + +#: src/control-flow/break-continue.md:3 +msgid "" +"If you want to exit a loop early, use [`break`](https://doc.rust-lang.org/" +"reference/expressions/loop-expr.html#break-expressions)," +msgstr "" + +#: src/control-flow/break-continue.md:4 +msgid "" +"If you want to immediately start the next iteration use [`continue`](https://" +"doc.rust-lang.org/reference/expressions/loop-expr.html#continue-expressions)." +msgstr "" + +#: src/control-flow/break-continue.md:7 +#, fuzzy +msgid "" +"Both `continue` and `break` can optionally take a label argument which is " +"used to break out of nested loops:" +msgstr "" +"Wenn Sie eine Schleife vorzeitig verlassen möchten, verwenden Sie `break`, " +"wenn Sie sofort beginnen möchten Verwenden Sie für die nächste Iteration " +"\"Continue\". Sowohl `Continue` als auch `Break` können optional verwendet " +"werden Nehmen Sie ein Label-Argument, das zum Ausbrechen aus verschachtelten " +"Schleifen verwendet wird:" + +#: src/control-flow/break-continue.md:10 +msgid "" +"```rust,editable\n" +"fn main() {\n" +" let v = vec![10, 20, 30];\n" +" let mut iter = v.into_iter();\n" +" 'outer: while let Some(x) = iter.next() {\n" +" println!(\"x: {x}\");\n" +" let mut i = 0;\n" +" while i < x {\n" +" println!(\"x: {x}, i: {i}\");\n" +" i += 1;\n" +" if i == 3 {\n" +" break 'outer;\n" +" }\n" +" }\n" +" }\n" +"}\n" +"```" +msgstr "" + +#: src/control-flow/break-continue.md:28 +#, fuzzy +msgid "" +"In this case we break the outer loop after 3 iterations of the inner loop." +msgstr "" +"In diesem Fall brechen wir die äußere Schleife nach 3 Iterationen der " +"inneren Schleife." + +#: src/control-flow/loop-expressions.md:1 +#, fuzzy +msgid "`loop` expressions" +msgstr "`loop`\\-Ausdrücke" + +#: src/control-flow/loop-expressions.md:3 +msgid "" +"Finally, there is a [`loop` keyword](https://doc.rust-lang.org/reference/" +"expressions/loop-expr.html#infinite-loops) which creates an endless loop." +msgstr "" + +#: src/control-flow/loop-expressions.md:6 +#, fuzzy +msgid "Here you must either `break` or `return` to stop the loop:" +msgstr "" +"Schließlich gibt es noch ein „loop“-Schlüsselwort, das eine Endlosschleife " +"erzeugt. Hier müssen Sie entweder `break` oder `return`, um die Schleife zu " +"stoppen:" + +#: src/control-flow/loop-expressions.md:8 +msgid "" +"```rust,editable\n" +"fn main() {\n" +" let mut x = 10;\n" +" loop {\n" +" x = if x % 2 == 0 {\n" +" x / 2\n" +" } else {\n" +" 3 * x + 1\n" +" };\n" +" if x == 1 {\n" +" break;\n" +" }\n" +" }\n" +" println!(\"Final x: {x}\");\n" +"}\n" +"```" +msgstr "" + +#: src/control-flow/loop-expressions.md:27 +msgid "Break the `loop` with a value (e.g. `break 8`) and print it out." +msgstr "" + +#: src/control-flow/loop-expressions.md:28 +msgid "" +"Note that `loop` is the only looping construct which returns a non-trivial " +"value. This is because it's guaranteed to be entered at least once (unlike " +"`while` and `for` loops)." +msgstr "" + #: src/basic-syntax/variables.md:3 msgid "" "Rust provides type safety via static typing. Variable bindings are immutable " @@ -3973,15 +4339,6 @@ msgstr "" "die Typen nach und nach immer öfter weglassen, je weiter der Kurs " "fortschreitet." -#: src/basic-syntax/variables.md:18 -msgid "" -"Note that since `println!` is a macro, `x` is not moved, even using the " -"function like syntax of `println!(\"x: {}\", x)`" -msgstr "" -"Beachte, dass, da `println!` ein Makro ist, `x` nicht verschoben (moved) " -"wird, selbst wenn die funktionsähnliche Syntax von `println!(\"x: {}\", x)` " -"verwendet wird." - #: src/basic-syntax/type-inference.md:3 msgid "Rust will look at how the variable is _used_ to determine the type:" msgstr "" @@ -4058,10 +4415,13 @@ msgid "" msgstr "" #: src/basic-syntax/type-inference.md:46 +#, fuzzy msgid "" "[`collect`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator." -"html#method.collect) relies on `FromIterator`, which [`HashSet`](https://doc." -"rust-lang.org/std/iter/trait.FromIterator.html) implements." +"html#method.collect) relies on [`FromIterator`](https://doc.rust-lang.org/" +"std/iter/trait.FromIterator.html), which [`HashSet`](https://doc.rust-lang." +"org/std/collections/struct.HashSet.html#impl-FromIterator%3CT%3E-for-" +"HashSet%3CT,+S%3E) implements." msgstr "" "[`collect`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator." "html#method.collect) bezieht sich auf den `FromIterator`, den [`HashSet`]" @@ -4072,20 +4432,23 @@ msgid "Static and Constant Variables" msgstr "Statische und konstante Variablen" #: src/basic-syntax/static-and-const.md:3 -msgid "Global state is managed with static and constant variables." +msgid "" +"Static and constant variables are two different ways to create globally-" +"scoped values that cannot be moved or reallocated during the execution of " +"the program. " msgstr "" -"Der globale Status (global state) wird mit statischen und konstanten " -"Variablen verwaltet." -#: src/basic-syntax/static-and-const.md:5 +#: src/basic-syntax/static-and-const.md:6 msgid "`const`" msgstr "`const`" -#: src/basic-syntax/static-and-const.md:7 -msgid "You can declare compile-time constants:" -msgstr "Du kannst Kompilierzeitkonstanten deklarieren:" +#: src/basic-syntax/static-and-const.md:8 +msgid "" +"Constant variables are evaluated at compile time and their values are " +"inlined wherever they are used:" +msgstr "" -#: src/basic-syntax/static-and-const.md:9 +#: src/basic-syntax/static-and-const.md:11 msgid "" "```rust,editable\n" "const DIGEST_SIZE: usize = 3;\n" @@ -4107,7 +4470,7 @@ msgid "" "```" msgstr "" -#: src/basic-syntax/static-and-const.md:27 +#: src/basic-syntax/static-and-const.md:29 msgid "" "According to the [Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-" "vs-static.html) these are inlined upon use." @@ -4115,15 +4478,23 @@ msgstr "" "Gemäß dem [Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-vs-" "static.html) werden diese bei der Verwendung eingefügt (inlined upon use)." -#: src/basic-syntax/static-and-const.md:29 +#: src/basic-syntax/static-and-const.md:31 +msgid "" +"Only functions marked `const` can be called at compile time to generate " +"`const` values. `const` functions can however be called at runtime." +msgstr "" + +#: src/basic-syntax/static-and-const.md:33 msgid "`static`" msgstr "`static`" -#: src/basic-syntax/static-and-const.md:31 -msgid "You can also declare static variables:" -msgstr "Sie können auch statische Variablen deklarieren:" +#: src/basic-syntax/static-and-const.md:35 +msgid "" +"Static variables will live during the whole execution of the program, and " +"therefore will not move:" +msgstr "" -#: src/basic-syntax/static-and-const.md:33 +#: src/basic-syntax/static-and-const.md:37 msgid "" "```rust,editable\n" "static BANNER: &str = \"Welcome to RustOS 3.14\";\n" @@ -4134,12 +4505,15 @@ msgid "" "```" msgstr "" -#: src/basic-syntax/static-and-const.md:41 +#: src/basic-syntax/static-and-const.md:45 +#, fuzzy msgid "" "As noted in the [Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-" "vs-static.html), these are not inlined upon use and have an actual " -"associated memory location. This is useful for unsafe and embedded code, " -"and the variable lives through the entirety of the program execution." +"associated memory location. This is useful for unsafe and embedded code, " +"and the variable lives through the entirety of the program execution. When a " +"globally-scoped value does not have a reason to need object identity, " +"`const` is generally preferred." msgstr "" "Wie im [Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-vs-static." "html) erwähnt, werden diese bei der Verwendung nicht inliniert und haben " @@ -4147,20 +4521,22 @@ msgstr "" "(unsafe) und eingebetteten (embedded) Code. Die Variable existiert während " "der gesamten Programmausführung." -#: src/basic-syntax/static-and-const.md:44 +#: src/basic-syntax/static-and-const.md:49 msgid "" -"We will look at mutating static data in the [chapter on Unsafe Rust](../" -"unsafe.md)." +"Because `static` variables are accessible from any thread, they must be " +"`Sync`. Interior mutability is possible through a [`Mutex`](https://doc.rust-" +"lang.org/std/sync/struct.Mutex.html), atomic or similar. It is also possible " +"to have mutable statics, but they require manual synchronisation so any " +"access to them requires `unsafe` code. We will look at [mutable statics](../" +"unsafe/mutable-static-variables.md) in the chapter on Unsafe Rust." msgstr "" -"Wir werden uns im [Kapitel über unsicheres Rust](../unsafe.md) mit " -"mutierenden statischen Daten befassen." -#: src/basic-syntax/static-and-const.md:48 +#: src/basic-syntax/static-and-const.md:57 msgid "Mention that `const` behaves semantically similar to C++'s `constexpr`." msgstr "" "Erwähne, dass sich `const` semantisch ähnlich wie `constexpr` in C++ verhält." -#: src/basic-syntax/static-and-const.md:49 +#: src/basic-syntax/static-and-const.md:58 msgid "" "`static`, on the other hand, is much more similar to a `const` or mutable " "global variable in C++." @@ -4168,7 +4544,13 @@ msgstr "" "`static` hingegen ist einer `const` oder veränderlichen (mutable) globalen " "Variable in C++ viel ähnlicher." -#: src/basic-syntax/static-and-const.md:50 +#: src/basic-syntax/static-and-const.md:59 +msgid "" +"`static` provides object identity: an address in memory and state as " +"required by types with interior mutability such as `Mutex`." +msgstr "" + +#: src/basic-syntax/static-and-const.md:60 msgid "" "It isn't super common that one would need a runtime evaluated constant, but " "it is helpful and safer than using a static." @@ -4177,6 +4559,74 @@ msgstr "" "Konstante benötigt, aber es ist hilfreich und sicherer als die Verwendung " "einer statischen." +#: src/basic-syntax/static-and-const.md:61 +msgid "`thread_local` data can be created with the macro `std::thread_local`." +msgstr "" + +#: src/basic-syntax/static-and-const.md:63 +msgid "Properties table:" +msgstr "" + +#: src/basic-syntax/static-and-const.md:65 +msgid "Property" +msgstr "" + +#: src/basic-syntax/static-and-const.md:65 +#, fuzzy +msgid "Static" +msgstr "`static`" + +#: src/basic-syntax/static-and-const.md:65 +msgid "Constant" +msgstr "" + +#: src/basic-syntax/static-and-const.md:67 +msgid "Has an address in memory" +msgstr "" + +#: src/basic-syntax/static-and-const.md:67 +#: src/basic-syntax/static-and-const.md:68 +#: src/basic-syntax/static-and-const.md:70 +#: src/basic-syntax/static-and-const.md:71 +msgid "Yes" +msgstr "" + +#: src/basic-syntax/static-and-const.md:67 +msgid "No (inlined)" +msgstr "" + +#: src/basic-syntax/static-and-const.md:68 +#, fuzzy +msgid "Lives for the entire duration of the program" +msgstr "Die `main`\\-Funktion ist der Einstiegspunkt des Programms." + +#: src/basic-syntax/static-and-const.md:68 +#: src/basic-syntax/static-and-const.md:69 +#: src/basic-syntax/static-and-const.md:71 +msgid "No" +msgstr "" + +#: src/basic-syntax/static-and-const.md:69 +msgid "Can be mutable" +msgstr "" + +#: src/basic-syntax/static-and-const.md:69 +msgid "Yes (unsafe)" +msgstr "" + +#: src/basic-syntax/static-and-const.md:70 +#, fuzzy +msgid "Evaluated at compile time" +msgstr "Werte haben feste Größen, die zur Kompilierzeit bekannt sind." + +#: src/basic-syntax/static-and-const.md:70 +msgid "Yes (initialised at compile time)" +msgstr "" + +#: src/basic-syntax/static-and-const.md:71 +msgid "Inlined wherever it is used" +msgstr "" + #: src/basic-syntax/scopes-shadowing.md:3 msgid "" "You can shadow variables, both those from outer scopes and variables from " @@ -4251,2033 +4701,6 @@ msgid "" "```" msgstr "" -#: src/memory-management.md:3 -msgid "Traditionally, languages have fallen into two broad categories:" -msgstr "Traditionell fallen Sprachen in zwei grobe Kategorien:" - -#: src/memory-management.md:5 -msgid "Full control via manual memory management: C, C++, Pascal, ..." -msgstr "Volle Kontrolle über manuelle Speicherverwaltung: C, C++, Pascal, ..." - -#: src/memory-management.md:6 -msgid "" -"Full safety via automatic memory management at runtime: Java, Python, Go, " -"Haskell, ..." -msgstr "" -"Volle Sicherheit durch automatische Speicherverwaltung zur Laufzeit: Java, " -"Python, Go, Haskell, ..." - -#: src/memory-management.md:8 -msgid "Rust offers a new mix:" -msgstr "Rust bietet eine neue Mischung:" - -#: src/memory-management.md:10 -msgid "" -"Full control _and_ safety via compile time enforcement of correct memory " -"management." -msgstr "" -"Volle Kontrolle _und_ Sicherheit durch Erzwingung des korrekten Speichers " -"zur Kompilierzeit." - -#: src/memory-management.md:13 -msgid "It does this with an explicit ownership concept." -msgstr "" -"Dies geschieht mit einem expliziten Eigentumskonzept (explicit ownership " -"concept)." - -#: src/memory-management.md:15 -msgid "First, let's refresh how memory management works." -msgstr "" -"Lasst uns zunächst die Funktionsweise der Speicherverwaltung auffrischen." - -#: src/memory-management/stack-vs-heap.md:1 -msgid "The Stack vs The Heap" -msgstr "Stapel vs. Haufen" - -#: src/memory-management/stack-vs-heap.md:3 -msgid "Stack: Continuous area of memory for local variables." -msgstr "Stack: Kontinuierlicher Speicherbereich für lokale Variablen." - -#: src/memory-management/stack-vs-heap.md:4 -msgid "Values have fixed sizes known at compile time." -msgstr "Werte haben feste Größen, die zur Kompilierzeit bekannt sind." - -#: src/memory-management/stack-vs-heap.md:5 -msgid "Extremely fast: just move a stack pointer." -msgstr "Extrem schnell: Durch Bewegen eines Stapelzeigers." - -#: src/memory-management/stack-vs-heap.md:6 -msgid "Easy to manage: follows function calls." -msgstr "Einfach zu verwalten: folgt Funktionsaufrufen." - -#: src/memory-management/stack-vs-heap.md:7 -msgid "Great memory locality." -msgstr "Große Speicherlokalität (memory locality)." - -#: src/memory-management/stack-vs-heap.md:9 -msgid "Heap: Storage of values outside of function calls." -msgstr "Heap: Speicherung von Werten außerhalb von Funktionsaufrufen." - -#: src/memory-management/stack-vs-heap.md:10 -msgid "Values have dynamic sizes determined at runtime." -msgstr "Werte haben dynamische Größen, die zur Laufzeit bestimmt werden." - -#: src/memory-management/stack-vs-heap.md:11 -msgid "Slightly slower than the stack: some book-keeping needed." -msgstr "Etwas langsamer als der Stapel: Etwas Buchhaltung ist erforderlich." - -#: src/memory-management/stack-vs-heap.md:12 -msgid "No guarantee of memory locality." -msgstr "Keine Garantie für Speicherlokalität." - -#: src/memory-management/stack.md:3 -#, fuzzy -msgid "" -"Creating a `String` puts fixed-sized data on the stack and dynamically sized " -"data on the heap:" -msgstr "" -"Das Erstellen eines \"Strings\" legt Daten mit fester Größe auf den Stapel " -"und dynamisch in der Größe Daten auf dem Haufen:" - -#: src/memory-management/stack.md:6 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let s1 = String::from(\"Hello\");\n" -"}\n" -"```" -msgstr "" - -#: src/memory-management/stack.md:12 -msgid "" -"```bob\n" -" Stack Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - -.\n" -": : : :\n" -": s1 : : :\n" -": +-----------+-------+ : : +----+----+----+----+----+ :\n" -": | ptr | o---+---+-----+-->| H | e | l | l | o | :\n" -": | len | 5 | : : +----+----+----+----+----+ :\n" -": | capacity | 5 | : : :\n" -": +-----------+-------+ : : :\n" -": : `- - - - - - - - - - - - - - - -'\n" -"`- - - - - - - - - - - - - -'\n" -"```" -msgstr "" - -#: src/memory-management/stack.md:28 -msgid "" -"Mention that a `String` is backed by a `Vec`, so it has a capacity and " -"length and can grow if mutable via reallocation on the heap." -msgstr "" - -#: src/memory-management/stack.md:30 -msgid "" -"If students ask about it, you can mention that the underlying memory is heap " -"allocated using the [System Allocator](https://doc.rust-lang.org/std/alloc/" -"struct.System.html) and custom allocators can be implemented using the " -"[Allocator API](https://doc.rust-lang.org/std/alloc/index.html)" -msgstr "" - -#: src/memory-management/stack.md:32 -msgid "" -"We can inspect the memory layout with `unsafe` code. However, you should " -"point out that this is rightfully unsafe!" -msgstr "" - -#: src/memory-management/stack.md:34 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut s1 = String::from(\"Hello\");\n" -" s1.push(' ');\n" -" s1.push_str(\"world\");\n" -" // DON'T DO THIS AT HOME! For educational purposes only.\n" -" // String provides no guarantees about its layout, so this could lead " -"to\n" -" // undefined behavior.\n" -" unsafe {\n" -" let (capacity, ptr, len): (usize, usize, usize) = std::mem::" -"transmute(s1);\n" -" println!(\"ptr = {ptr:#x}, len = {len}, capacity = {capacity}\");\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/memory-management/manual.md:3 -#, fuzzy -msgid "You allocate and deallocate heap memory yourself." -msgstr "Heap-Speicher können Sie selbst zuweisen und freigeben." - -#: src/memory-management/manual.md:5 -#, fuzzy -msgid "" -"If not done with care, this can lead to crashes, bugs, security " -"vulnerabilities, and memory leaks." -msgstr "" -"Wenn dies nicht sorgfältig durchgeführt wird, kann dies zu Abstürzen, " -"Fehlern, Sicherheitslücken und Speicherlecks führen." - -#: src/memory-management/manual.md:7 -#, fuzzy -msgid "C Example" -msgstr "\\##C Beispiel" - -#: src/memory-management/manual.md:9 -#, fuzzy -msgid "You must call `free` on every pointer you allocate with `malloc`:" -msgstr "" -"Sie müssen `free` auf jedem Zeiger aufrufen, den Sie mit `malloc` zuweisen:" - -#: src/memory-management/manual.md:11 -msgid "" -"```c\n" -"void foo(size_t n) {\n" -" int* int_array = (int*)malloc(n * sizeof(int));\n" -" //\n" -" // ... lots of code\n" -" //\n" -" free(int_array);\n" -"}\n" -"```" -msgstr "" - -#: src/memory-management/manual.md:21 -#, fuzzy -msgid "" -"Memory is leaked if the function returns early between `malloc` and `free`: " -"the pointer is lost and we cannot deallocate the memory." -msgstr "" -"Speicherverlust, wenn die Funktion früh zwischen `malloc` und `free` " -"zurückkehrt: the Zeiger geht verloren und wir können den Speicher nicht " -"freigeben." - -#: src/memory-management/scope-based.md:3 -#, fuzzy -msgid "" -"Constructors and destructors let you hook into the lifetime of an object." -msgstr "" -"Mit Konstruktoren und Destruktoren können Sie sich in die Lebensdauer eines " -"Objekts einklinken." - -#: src/memory-management/scope-based.md:5 -#, fuzzy -msgid "" -"By wrapping a pointer in an object, you can free memory when the object is " -"destroyed. The compiler guarantees that this happens, even if an exception " -"is raised." -msgstr "" -"Indem Sie einen Zeiger in ein Objekt einschließen, können Sie Speicher " -"freigeben, wenn das Objekt vorhanden ist zerstört. Der Compiler garantiert, " -"dass dies geschieht, auch wenn es sich um eine Ausnahme handelt erzogen." - -#: src/memory-management/scope-based.md:9 -#, fuzzy -msgid "" -"This is often called _resource acquisition is initialization_ (RAII) and " -"gives you smart pointers." -msgstr "" -"Dies wird oft als _Ressourcenerwerb ist Initialisierung_ (RAII) bezeichnet " -"und gibt ihr klugen zeiger." - -#: src/memory-management/scope-based.md:12 -#, fuzzy -msgid "C++ Example" -msgstr "C++-Beispiel" - -#: src/memory-management/scope-based.md:14 -msgid "" -"```c++\n" -"void say_hello(std::unique_ptr person) {\n" -" std::cout << \"Hello \" << person->name << std::endl;\n" -"}\n" -"```" -msgstr "" - -#: src/memory-management/scope-based.md:20 -#, fuzzy -msgid "" -"The `std::unique_ptr` object is allocated on the stack, and points to memory " -"allocated on the heap." -msgstr "" -"Das `std::unique_ptr`\\-Objekt wird auf dem Stack allokiert und zeigt auf " -"auf dem Heap zugewiesener Speicher." - -#: src/memory-management/scope-based.md:22 -#, fuzzy -msgid "At the end of `say_hello`, the `std::unique_ptr` destructor will run." -msgstr "" -"Am Ende von `say_hello` wird der Destruktor `std::unique_ptr` ausgeführt." - -#: src/memory-management/scope-based.md:23 -#, fuzzy -msgid "The destructor frees the `Person` object it points to." -msgstr "Der Destruktor gibt das `Person`\\-Objekt frei, auf das er zeigt." - -#: src/memory-management/scope-based.md:25 -#, fuzzy -msgid "" -"Special move constructors are used when passing ownership to a function:" -msgstr "" -"Spezielle Move-Konstruktoren werden verwendet, wenn der Besitz an eine " -"Funktion übergeben wird:" - -#: src/memory-management/scope-based.md:27 -msgid "" -"```c++\n" -"std::unique_ptr person = find_person(\"Carla\");\n" -"say_hello(std::move(person));\n" -"```" -msgstr "" - -#: src/memory-management/garbage-collection.md:1 -#, fuzzy -msgid "Automatic Memory Management" -msgstr "Automatische Speicherverwaltung" - -#: src/memory-management/garbage-collection.md:3 -#, fuzzy -msgid "" -"An alternative to manual and scope-based memory management is automatic " -"memory management:" -msgstr "" -"Eine Alternative zur manuellen und bereichsbasierten Speicherverwaltung ist " -"der automatische Speicher Management:" - -#: src/memory-management/garbage-collection.md:6 -#, fuzzy -msgid "The programmer never allocates or deallocates memory explicitly." -msgstr "" -"Der Programmierer weist Speicher nie explizit zu oder gibt ihn nicht mehr " -"frei." - -#: src/memory-management/garbage-collection.md:7 -#, fuzzy -msgid "" -"A garbage collector finds unused memory and deallocates it for the " -"programmer." -msgstr "" -"Ein Garbage Collector findet ungenutzten Speicher und gibt ihn für den " -"Programmierer frei." - -#: src/memory-management/garbage-collection.md:9 -#, fuzzy -msgid "Java Example" -msgstr "Java-Beispiel" - -#: src/memory-management/garbage-collection.md:11 -#, fuzzy -msgid "The `person` object is not deallocated after `sayHello` returns:" -msgstr "" -"Das `person`\\-Objekt wird nicht freigegeben, nachdem `sayHello` " -"zurückgegeben wird:" - -#: src/memory-management/garbage-collection.md:13 -msgid "" -"```java\n" -"void sayHello(Person person) {\n" -" System.out.println(\"Hello \" + person.getName());\n" -"}\n" -"```" -msgstr "" - -#: src/memory-management/rust.md:1 -#, fuzzy -msgid "Memory Management in Rust" -msgstr "Speicherverwaltung in Rust" - -#: src/memory-management/rust.md:3 -#, fuzzy -msgid "Memory management in Rust is a mix:" -msgstr "Die Speicherverwaltung in Rust ist eine Mischung:" - -#: src/memory-management/rust.md:5 -#, fuzzy -msgid "Safe and correct like Java, but without a garbage collector." -msgstr "Sicher und korrekt wie Java, aber ohne Garbage Collector." - -#: src/memory-management/rust.md:6 -#, fuzzy -msgid "" -"Depending on which abstraction (or combination of abstractions) you choose, " -"can be a single unique pointer, reference counted, or atomically reference " -"counted." -msgstr "" -"Je nachdem, welche Abstraktion (oder Kombination von Abstraktionen) Sie " -"wählen, kann es sich um einen einzelnen eindeutigen Zeiger, eine " -"Referenzzählung oder eine atomare Referenzzählung handeln." - -#: src/memory-management/rust.md:7 -#, fuzzy -msgid "Scope-based like C++, but the compiler enforces full adherence." -msgstr "" -"Bereichsbasiert wie C++, aber der Compiler erzwingt die vollständige " -"Einhaltung." - -#: src/memory-management/rust.md:8 -#, fuzzy -msgid "" -"A Rust user can choose the right abstraction for the situation, some even " -"have no cost at runtime like C." -msgstr "" -"Ein Rust-Benutzer kann die richtige Abstraktion für die Situation auswählen, " -"einige haben sogar keine Kosten zur Laufzeit wie C." - -#: src/memory-management/rust.md:10 -#, fuzzy -msgid "It achieves this by modeling _ownership_ explicitly." -msgstr "Dies wird erreicht, indem _Eigentum_ explizit modelliert wird." - -#: src/memory-management/rust.md:14 -#, fuzzy -msgid "" -"If asked how at this point, you can mention that in Rust this is usually " -"handled by RAII wrapper types such as [Box](https://doc.rust-lang.org/std/" -"boxed/struct.Box.html), [Vec](https://doc.rust-lang.org/std/vec/struct.Vec." -"html), [Rc](https://doc.rust-lang.org/std/rc/struct.Rc.html), or [Arc]" -"(https://doc.rust-lang.org/std/sync/struct.Arc.html). These encapsulate " -"ownership and memory allocation via various means, and prevent the potential " -"errors in C." -msgstr "" -"Wenn Sie an dieser Stelle fragen, wie das geht, können Sie erwähnen, dass " -"dies in Rust normalerweise von RAII-Wrapper-Typen wie [Box](https://doc.rust-" -"lang.org/std/boxed/struct.Box.html), [Vec](https://doc.rust-lang.org/std/vec/" -"struct.Vec.html), [Rc](https://doc.rust-lang.org/std/rc/struct.Rc.html) oder " -"[Arc](https://doc.rust-lang.org/std/sync/struct.Arc.html) gehandhabt wird. " -"Diese kapseln den Besitz und die Speicherzuweisung auf verschiedene Weise " -"und verhindern die potenziellen Fehler in C." - -#: src/memory-management/rust.md:16 -msgid "" -"You may be asked about destructors here, the [Drop](https://doc.rust-lang." -"org/std/ops/trait.Drop.html) trait is the Rust equivalent." -msgstr "" - -#: src/memory-management/comparison.md:3 -#, fuzzy -msgid "Here is a rough comparison of the memory management techniques." -msgstr "Hier ist ein grober Vergleich der Speicherverwaltungstechniken." - -#: src/memory-management/comparison.md:5 -#, fuzzy -msgid "Pros of Different Memory Management Techniques" -msgstr "Vorteile verschiedener Speicherverwaltungstechniken" - -#: src/memory-management/comparison.md:7 src/memory-management/comparison.md:22 -#, fuzzy -msgid "Manual like C:" -msgstr "Handbuch wie C:" - -#: src/memory-management/comparison.md:8 src/memory-management/comparison.md:14 -#: src/memory-management/comparison.md:17 -#, fuzzy -msgid "No runtime overhead." -msgstr "Kein Laufzeitaufwand." - -#: src/memory-management/comparison.md:9 src/memory-management/comparison.md:26 -#, fuzzy -msgid "Automatic like Java:" -msgstr "Automatisch wie Java:" - -#: src/memory-management/comparison.md:10 -#, fuzzy -msgid "Fully automatic." -msgstr "Komplett automatisch." - -#: src/memory-management/comparison.md:11 -#: src/memory-management/comparison.md:18 -#, fuzzy -msgid "Safe and correct." -msgstr "Sicher und korrekt." - -#: src/memory-management/comparison.md:12 -#: src/memory-management/comparison.md:29 -#, fuzzy -msgid "Scope-based like C++:" -msgstr "Bereichsbasiert wie C++:" - -#: src/memory-management/comparison.md:13 -#, fuzzy -msgid "Partially automatic." -msgstr "Teilautomatisch." - -#: src/memory-management/comparison.md:15 -#, fuzzy -msgid "Compiler-enforced scope-based like Rust:" -msgstr "Vom Compiler erzwungener Geltungsbereich wie Rust:" - -#: src/memory-management/comparison.md:16 -#, fuzzy -msgid "Enforced by compiler." -msgstr "Vom Compiler erzwungen." - -#: src/memory-management/comparison.md:20 -#, fuzzy -msgid "Cons of Different Memory Management Techniques" -msgstr "Nachteile verschiedener Techniken zur Speicherverwaltung" - -#: src/memory-management/comparison.md:23 -#, fuzzy -msgid "Use-after-free." -msgstr "Use-after-free." - -#: src/memory-management/comparison.md:24 -#, fuzzy -msgid "Double-frees." -msgstr "Double-frees." - -#: src/memory-management/comparison.md:25 -#, fuzzy -msgid "Memory leaks." -msgstr "Speicherlecks." - -#: src/memory-management/comparison.md:27 -#, fuzzy -msgid "Garbage collection pauses." -msgstr "Garbage Collection pausiert." - -#: src/memory-management/comparison.md:28 -#, fuzzy -msgid "Destructor delays." -msgstr "Destruktorverzögerungen." - -#: src/memory-management/comparison.md:30 -#, fuzzy -msgid "Complex, opt-in by programmer." -msgstr "Komplex, Opt-in durch Programmierer." - -#: src/memory-management/comparison.md:31 -#, fuzzy -msgid "Potential for use-after-free." -msgstr "Potenzial für die Nutzung nach dem Kostenlos." - -#: src/memory-management/comparison.md:32 -#, fuzzy -msgid "Compiler-enforced and scope-based like Rust:" -msgstr "Compiler-erzwungen und bereichsbasiert wie Rust:" - -#: src/memory-management/comparison.md:33 -#, fuzzy -msgid "Some upfront complexity." -msgstr "Etwas Komplexität im Voraus." - -#: src/memory-management/comparison.md:34 -#, fuzzy -msgid "Can reject valid programs." -msgstr "Kann gültige Programme ablehnen." - -#: src/ownership.md:3 -#, fuzzy -msgid "" -"All variable bindings have a _scope_ where they are valid and it is an error " -"to use a variable outside its scope:" -msgstr "" -"Alle Variablenbindungen haben einen _Geltungsbereich_, wo sie gültig sind " -"und es ein Fehler ist Verwenden Sie eine Variable außerhalb ihres " -"Gültigkeitsbereichs:" - -#: src/ownership.md:6 -msgid "" -"```rust,editable,compile_fail\n" -"struct Point(i32, i32);\n" -"\n" -"fn main() {\n" -" {\n" -" let p = Point(3, 4);\n" -" println!(\"x: {}\", p.0);\n" -" }\n" -" println!(\"y: {}\", p.1);\n" -"}\n" -"```" -msgstr "" - -#: src/ownership.md:18 -#, fuzzy -msgid "" -"At the end of the scope, the variable is _dropped_ and the data is freed." -msgstr "" -"Am Ende des Gültigkeitsbereichs wird die Variable _gelöscht_ und die Daten " -"werden freigegeben." - -#: src/ownership.md:19 -#, fuzzy -msgid "A destructor can run here to free up resources." -msgstr "Hier kann ein Destruktor laufen, um Ressourcen freizugeben." - -#: src/ownership.md:20 -#, fuzzy -msgid "We say that the variable _owns_ the value." -msgstr "Wir sagen, dass die Variable den Wert _besitzt_." - -#: src/ownership/move-semantics.md:3 -#, fuzzy -msgid "An assignment will transfer ownership between variables:" -msgstr "Eine Zuweisung überträgt den Besitz zwischen Variablen:" - -#: src/ownership/move-semantics.md:5 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let s1: String = String::from(\"Hello!\");\n" -" let s2: String = s1;\n" -" println!(\"s2: {s2}\");\n" -" // println!(\"s1: {s1}\");\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/move-semantics.md:14 -#, fuzzy -msgid "The assignment of `s1` to `s2` transfers ownership." -msgstr "Die Zuweisung von `s1` an `s2` überträgt das Eigentum." - -#: src/ownership/move-semantics.md:15 -#, fuzzy -msgid "The data was _moved_ from `s1` and `s1` is no longer accessible." -msgstr "" -"Die Daten wurden von `s1` _verschoben_ und `s1` ist nicht mehr zugänglich." - -#: src/ownership/move-semantics.md:16 -#, fuzzy -msgid "When `s1` goes out of scope, nothing happens: it has no ownership." -msgstr "" -"Wenn `s1` den Gültigkeitsbereich verlässt, passiert nichts: Es hat keinen " -"Besitz." - -#: src/ownership/move-semantics.md:17 -#, fuzzy -msgid "When `s2` goes out of scope, the string data is freed." -msgstr "" -"Wenn `s2` den Geltungsbereich verlässt, werden die String-Daten freigegeben." - -#: src/ownership/move-semantics.md:18 -#, fuzzy -msgid "There is always _exactly_ one variable binding which owns a value." -msgstr "Es gibt immer _genau_ eine Variablenbindung, die einen Wert besitzt." - -#: src/ownership/move-semantics.md:22 -#, fuzzy -msgid "" -"Mention that this is the opposite of the defaults in C++, which copies by " -"value unless you use `std::move` (and the move constructor is defined!)." -msgstr "" -"Erwähnen Sie, dass dies das Gegenteil der Standardeinstellungen in C++ ist, " -"die nach Wert kopieren, es sei denn, Sie verwenden `std::move` (und der Move-" -"Konstruktor ist definiert!)." - -#: src/ownership/move-semantics.md:24 -msgid "In Rust, clones are explicit (by using `clone`)." -msgstr "" - -#: src/ownership/moved-strings-rust.md:3 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let s1: String = String::from(\"Rust\");\n" -" let s2: String = s1;\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/moved-strings-rust.md:10 -#, fuzzy -msgid "The heap data from `s1` is reused for `s2`." -msgstr "Die Heap-Daten von „s1“ werden für „s2“ wiederverwendet." - -#: src/ownership/moved-strings-rust.md:11 -#, fuzzy -msgid "When `s1` goes out of scope, nothing happens (it has been moved from)." -msgstr "" -"Wenn `s1` den Gültigkeitsbereich verlässt, passiert nichts (es wurde " -"verschoben)." - -#: src/ownership/moved-strings-rust.md:13 -#, fuzzy -msgid "Before move to `s2`:" -msgstr "Vor dem Wechsel zu `s2`:" - -#: src/ownership/moved-strings-rust.md:15 -msgid "" -"```bob\n" -" Stack Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - -.\n" -": : : :\n" -": s1 : : :\n" -": +-----------+-------+ : : +----+----+----+----+ :\n" -": | ptr | o---+---+-----+-->| R | u | s | t | :\n" -": | len | 4 | : : +----+----+----+----+ :\n" -": | capacity | 4 | : : :\n" -": +-----------+-------+ : : :\n" -": : `- - - - - - - - - - - - - -'\n" -": :\n" -"`- - - - - - - - - - - - - -'\n" -"```" -msgstr "" - -#: src/ownership/moved-strings-rust.md:30 -#, fuzzy -msgid "After move to `s2`:" -msgstr "Nach Umzug nach `s2`:" - -#: src/ownership/moved-strings-rust.md:32 -msgid "" -"```bob\n" -" Stack Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - -.\n" -": : : :\n" -": s1 \"(inaccessible)\" : : :\n" -": +-----------+-------+ : : +----+----+----+----+ :\n" -": | ptr | o---+---+--+--+-->| R | u | s | t | :\n" -": | len | 4 | : | : +----+----+----+----+ :\n" -": | capacity | 4 | : | : :\n" -": +-----------+-------+ : | : :\n" -": : | `- - - - - - - - - - - - - -'\n" -": s2 : |\n" -": +-----------+-------+ : |\n" -": | ptr | o---+---+--'\n" -": | len | 4 | :\n" -": | capacity | 4 | :\n" -": +-----------+-------+ :\n" -": :\n" -"`- - - - - - - - - - - - - -'\n" -"```" -msgstr "" - -#: src/ownership/double-free-modern-cpp.md:3 -#, fuzzy -msgid "Modern C++ solves this differently:" -msgstr "Modernes C++ löst dies anders:" - -#: src/ownership/double-free-modern-cpp.md:5 -msgid "" -"```c++\n" -"std::string s1 = \"Cpp\";\n" -"std::string s2 = s1; // Duplicate the data in s1.\n" -"```" -msgstr "" - -#: src/ownership/double-free-modern-cpp.md:10 -#, fuzzy -msgid "" -"The heap data from `s1` is duplicated and `s2` gets its own independent copy." -msgstr "" -"Die Heap-Daten von `s1` werden dupliziert und `s2` bekommt seine eigene " -"unabhängige Kopie." - -#: src/ownership/double-free-modern-cpp.md:11 -#, fuzzy -msgid "When `s1` and `s2` go out of scope, they each free their own memory." -msgstr "" -"Wenn `s1` und `s2` den Geltungsbereich verlassen, geben sie jeweils ihren " -"eigenen Speicher frei." - -#: src/ownership/double-free-modern-cpp.md:13 -#, fuzzy -msgid "Before copy-assignment:" -msgstr "Vor Kopierauftrag:" - -#: src/ownership/double-free-modern-cpp.md:16 -msgid "" -"```bob\n" -" Stack Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n" -": : : :\n" -": s1 : : :\n" -": +-----------+-------+ : : +----+----+----+ :\n" -": | ptr | o---+---+--+--+-->| C | p | p | :\n" -": | len | 3 | : : +----+----+----+ :\n" -": | capacity | 3 | : : :\n" -": +-----------+-------+ : : :\n" -": : `- - - - - - - - - - - -'\n" -"`- - - - - - - - - - - - - -'\n" -"```" -msgstr "" - -#: src/ownership/double-free-modern-cpp.md:30 -#, fuzzy -msgid "After copy-assignment:" -msgstr "Nach der Kopierzuweisung:" - -#: src/ownership/double-free-modern-cpp.md:32 -msgid "" -"```bob\n" -" Stack Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n" -": : : :\n" -": s1 : : :\n" -": +-----------+-------+ : : +----+----+----+ :\n" -": | ptr | o---+---+--+--+-->| C | p | p | :\n" -": | len | 3 | : : +----+----+----+ :\n" -": | capacity | 3 | : : :\n" -": +-----------+-------+ : : :\n" -": : : :\n" -": s2 : : :\n" -": +-----------+-------+ : : +----+----+----+ :\n" -": | ptr | o---+---+-----+-->| C | p | p | :\n" -": | len | 3 | : : +----+----+----+ :\n" -": | capacity | 3 | : : :\n" -": +-----------+-------+ : : :\n" -": : `- - - - - - - - - - - -'\n" -"`- - - - - - - - - - - - - -'\n" -"```" -msgstr "" - -#: src/ownership/moves-function-calls.md:3 -#, fuzzy -msgid "" -"When you pass a value to a function, the value is assigned to the function " -"parameter. This transfers ownership:" -msgstr "" -"Wenn Sie einer Funktion einen Wert übergeben, wird der Wert der Funktion " -"zugewiesen Parameter. Dadurch wird das Eigentum übertragen:" - -#: src/ownership/moves-function-calls.md:6 -msgid "" -"```rust,editable\n" -"fn say_hello(name: String) {\n" -" println!(\"Hello {name}\")\n" -"}\n" -"\n" -"fn main() {\n" -" let name = String::from(\"Alice\");\n" -" say_hello(name);\n" -" // say_hello(name);\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/moves-function-calls.md:20 -#, fuzzy -msgid "" -"With the first call to `say_hello`, `main` gives up ownership of `name`. " -"Afterwards, `name` cannot be used anymore within `main`." -msgstr "" -"Mit dem ersten Aufruf von `say_hello` gibt `main` den Besitz von `name` auf. " -"Danach kann `name` nicht mehr innerhalb von `main` verwendet werden." - -#: src/ownership/moves-function-calls.md:21 -#, fuzzy -msgid "" -"The heap memory allocated for `name` will be freed at the end of the " -"`say_hello` function." -msgstr "" -"Der für `name` zugewiesene Heap-Speicher wird am Ende der `say_hello`\\-" -"Funktion freigegeben." - -#: src/ownership/moves-function-calls.md:22 -#, fuzzy -msgid "" -"`main` can retain ownership if it passes `name` as a reference (`&name`) and " -"if `say_hello` accepts a reference as a parameter." -msgstr "" -"`main` kann den Besitz behalten, wenn es `name` als Referenz (`&name`) " -"übergibt und wenn `say_hello` eine Referenz als Parameter akzeptiert." - -#: src/ownership/moves-function-calls.md:23 -#, fuzzy -msgid "" -"Alternatively, `main` can pass a clone of `name` in the first call (`name." -"clone()`)." -msgstr "" -"Alternativ kann `main` beim ersten Aufruf (`name.clone()`) einen Klon von " -"`name` übergeben." - -#: src/ownership/moves-function-calls.md:24 -#, fuzzy -msgid "" -"Rust makes it harder than C++ to inadvertently create copies by making move " -"semantics the default, and by forcing programmers to make clones explicit." -msgstr "" -"Rust macht es schwieriger als C++, versehentlich Kopien zu erstellen, indem " -"es die Bewegungssemantik zum Standard macht und Programmierer dazu zwingt, " -"Klone explizit zu machen." - -#: src/ownership/copy-clone.md:3 -#, fuzzy -msgid "" -"While move semantics are the default, certain types are copied by default:" -msgstr "" -"Während die Bewegungssemantik der Standard ist, werden bestimmte Typen " -"standardmäßig kopiert:" - -#: src/ownership/copy-clone.md:5 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let x = 42;\n" -" let y = x;\n" -" println!(\"x: {x}\");\n" -" println!(\"y: {y}\");\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/copy-clone.md:14 -#, fuzzy -msgid "These types implement the `Copy` trait." -msgstr "Diese Typen implementieren das `Copy`\\-Merkmal." - -#: src/ownership/copy-clone.md:16 -#, fuzzy -msgid "You can opt-in your own types to use copy semantics:" -msgstr "" -"Sie können Ihre eigenen Typen für die Verwendung von Kopiersemantik " -"aktivieren:" - -#: src/ownership/copy-clone.md:18 -msgid "" -"```rust,editable\n" -"#[derive(Copy, Clone, Debug)]\n" -"struct Point(i32, i32);\n" -"\n" -"fn main() {\n" -" let p1 = Point(3, 4);\n" -" let p2 = p1;\n" -" println!(\"p1: {p1:?}\");\n" -" println!(\"p2: {p2:?}\");\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/copy-clone.md:30 -#, fuzzy -msgid "After the assignment, both `p1` and `p2` own their own data." -msgstr "" -"Nach der Zuweisung besitzen sowohl `p1` als auch `p2` ihre eigenen Daten." - -#: src/ownership/copy-clone.md:31 -#, fuzzy -msgid "We can also use `p1.clone()` to explicitly copy the data." -msgstr "" -"Wir können auch `p1.clone()` verwenden, um die Daten explizit zu kopieren." - -#: src/ownership/copy-clone.md:35 -#, fuzzy -msgid "Copying and cloning are not the same thing:" -msgstr "Kopieren und Klonen sind nicht dasselbe:" - -#: src/ownership/copy-clone.md:37 -#, fuzzy -msgid "" -"Copying refers to bitwise copies of memory regions and does not work on " -"arbitrary objects." -msgstr "" -"Kopieren bezieht sich auf bitweises Kopieren von Speicherbereichen und " -"funktioniert nicht mit beliebigen Objekten." - -#: src/ownership/copy-clone.md:38 -#, fuzzy -msgid "" -"Copying does not allow for custom logic (unlike copy constructors in C++)." -msgstr "" -"Beim Kopieren ist keine benutzerdefinierte Logik möglich (im Gegensatz zu " -"Kopierkonstruktoren in C++)." - -#: src/ownership/copy-clone.md:39 -#, fuzzy -msgid "" -"Cloning is a more general operation and also allows for custom behavior by " -"implementing the `Clone` trait." -msgstr "" -"Klonen ist eine allgemeinere Operation und ermöglicht auch " -"benutzerdefiniertes Verhalten durch Implementieren der Eigenschaft " -"\"Klonen\"." - -#: src/ownership/copy-clone.md:40 -#, fuzzy -msgid "Copying does not work on types that implement the `Drop` trait." -msgstr "" -"Das Kopieren funktioniert nicht bei Typen, die das `Drop`\\-Merkmal " -"implementieren." - -#: src/ownership/copy-clone.md:42 src/ownership/lifetimes-function-calls.md:29 -#, fuzzy -msgid "In the above example, try the following:" -msgstr "Versuchen Sie im obigen Beispiel Folgendes:" - -#: src/ownership/copy-clone.md:44 -#, fuzzy -msgid "" -"Add a `String` field to `struct Point`. It will not compile because `String` " -"is not a `Copy` type." -msgstr "" -"Fügen Sie ein `String`\\-Feld zu `struct Point` hinzu. Es wird nicht " -"kompiliert, da `String` kein `Copy`\\-Typ ist." - -#: src/ownership/copy-clone.md:45 -#, fuzzy -msgid "" -"Remove `Copy` from the `derive` attribute. The compiler error is now in the " -"`println!` for `p1`." -msgstr "" -"Entfernen Sie „Copy“ aus dem „derive“-Attribut. Der Compiler-Fehler steht " -"jetzt im `println!` für `p1`." - -#: src/ownership/copy-clone.md:46 -#, fuzzy -msgid "Show that it works if you clone `p1` instead." -msgstr "Zeigen Sie, dass es funktioniert, wenn Sie stattdessen `p1` klonen." - -#: src/ownership/copy-clone.md:48 -#, fuzzy -msgid "" -"If students ask about `derive`, it is sufficient to say that this is a way " -"to generate code in Rust at compile time. In this case the default " -"implementations of `Copy` and `Clone` traits are generated." -msgstr "" -"Wenn Schüler nach „derive“ fragen, reicht es zu sagen, dass dies eine " -"Möglichkeit ist, Code in Rust zu generieren zur Kompilierzeit. In diesem " -"Fall werden die Standardimplementierungen der Merkmale „Kopieren“ und " -"„Klonen“ generiert." - -#: src/ownership/borrowing.md:3 -#, fuzzy -msgid "" -"Instead of transferring ownership when calling a function, you can let a " -"function _borrow_ the value:" -msgstr "" -"Anstatt den Besitz beim Aufruf einer Funktion zu übertragen, können Sie a " -"function _borrow_ den Wert:" - -#: src/ownership/borrowing.md:6 -msgid "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Point(i32, i32);\n" -"\n" -"fn add(p1: &Point, p2: &Point) -> Point {\n" -" Point(p1.0 + p2.0, p1.1 + p2.1)\n" -"}\n" -"\n" -"fn main() {\n" -" let p1 = Point(3, 4);\n" -" let p2 = Point(10, 20);\n" -" let p3 = add(&p1, &p2);\n" -" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/borrowing.md:22 -#, fuzzy -msgid "The `add` function _borrows_ two points and returns a new point." -msgstr "" -"Die `add`\\-Funktion _leiht_ zwei Punkte und gibt einen neuen Punkt zurück." - -#: src/ownership/borrowing.md:23 -#, fuzzy -msgid "The caller retains ownership of the inputs." -msgstr "Der Aufrufer behält das Eigentum an den Eingaben." - -#: src/ownership/borrowing.md:27 -#, fuzzy -msgid "Notes on stack returns:" -msgstr "Hinweise zur Stapelrückgabe:" - -#: src/ownership/borrowing.md:28 -msgid "" -"Demonstrate that the return from `add` is cheap because the compiler can " -"eliminate the copy operation. Change the above code to print stack addresses " -"and run it on the [Playground](https://play.rust-lang.org/). In the " -"\"DEBUG\" optimization level, the addresses should change, while they stay " -"the same when changing to the \"RELEASE\" setting:" -msgstr "" - -#: src/ownership/borrowing.md:30 -msgid "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Point(i32, i32);\n" -"\n" -"fn add(p1: &Point, p2: &Point) -> Point {\n" -" let p = Point(p1.0 + p2.0, p1.1 + p2.1);\n" -" println!(\"&p.0: {:p}\", &p.0);\n" -" p\n" -"}\n" -"\n" -"fn main() {\n" -" let p1 = Point(3, 4);\n" -" let p2 = Point(10, 20);\n" -" let p3 = add(&p1, &p2);\n" -" println!(\"&p3.0: {:p}\", &p3.0);\n" -" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/borrowing.md:48 -msgid "The Rust compiler can do return value optimization (RVO)." -msgstr "" - -#: src/ownership/borrowing.md:49 -msgid "" -"In C++, copy elision has to be defined in the language specification because " -"constructors can have side effects. In Rust, this is not an issue at all. If " -"RVO did not happen, Rust will always performs a simple and efficient " -"`memcpy` copy." -msgstr "" - -#: src/ownership/shared-unique-borrows.md:3 -#, fuzzy -msgid "Rust puts constraints on the ways you can borrow values:" -msgstr "Rust schränkt die Art und Weise ein, wie Sie Werte ausleihen können:" - -#: src/ownership/shared-unique-borrows.md:5 -#, fuzzy -msgid "You can have one or more `&T` values at any given time, _or_" -msgstr "Sie können jederzeit einen oder mehrere `&T`\\-Werte haben, _oder_" - -#: src/ownership/shared-unique-borrows.md:6 -#, fuzzy -msgid "You can have exactly one `&mut T` value." -msgstr "Sie können genau einen `&mut T`\\-Wert haben." - -#: src/ownership/shared-unique-borrows.md:8 -msgid "" -"```rust,editable,compile_fail\n" -"fn main() {\n" -" let mut a: i32 = 10;\n" -" let b: &i32 = &a;\n" -"\n" -" {\n" -" let c: &mut i32 = &mut a;\n" -" *c = 20;\n" -" }\n" -"\n" -" println!(\"a: {a}\");\n" -" println!(\"b: {b}\");\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/shared-unique-borrows.md:25 -#, fuzzy -msgid "" -"The above code does not compile because `a` is borrowed as mutable (through " -"`c`) and as immutable (through `b`) at the same time." -msgstr "" -"Der obige Code lässt sich nicht kompilieren, da `a` gleichzeitig als " -"veränderlich (durch `c`) und als unveränderlich (durch `b`) ausgeliehen wird." - -#: src/ownership/shared-unique-borrows.md:26 -#, fuzzy -msgid "" -"Move the `println!` statement for `b` before the scope that introduces `c` " -"to make the code compile." -msgstr "" -"Verschieben Sie die `println!`\\-Anweisung für `b` vor den " -"Gültigkeitsbereich, der `c` einführt, um den Code zu kompilieren." - -#: src/ownership/shared-unique-borrows.md:27 -#, fuzzy -msgid "" -"After that change, the compiler realizes that `b` is only ever used before " -"the new mutable borrow of `a` through `c`. This is a feature of the borrow " -"checker called \"non-lexical lifetimes\"." -msgstr "" -"Nach dieser Änderung erkennt der Compiler, dass `b` immer nur vor dem neuen " -"änderbaren Borgen von `a` bis `c` verwendet wird. Dies ist eine Funktion des " -"Borrow-Checkers, die als \"nicht-lexikalische Lebensdauern\" bezeichnet wird." - -#: src/ownership/lifetimes.md:3 -#, fuzzy -msgid "A borrowed value has a _lifetime_:" -msgstr "Ein geliehener Wert hat eine _Lebensdauer_:" - -#: src/ownership/lifetimes.md:5 -msgid "The lifetime can be implicit: `add(p1: &Point, p2: &Point) -> Point`." -msgstr "" - -#: src/ownership/lifetimes.md:6 -msgid "Lifetimes can also be explicit: `&'a Point`, `&'document str`." -msgstr "" - -#: src/ownership/lifetimes.md:7 src/ownership/lifetimes-function-calls.md:23 -#, fuzzy -msgid "" -"Read `&'a Point` as \"a borrowed `Point` which is valid for at least the " -"lifetime `a`\"." -msgstr "" -"Lesen Sie `&'einen Punkt` als \"einen geliehenen `Punkt`, der mindestens für " -"den gilt Lebenszeit `a`\"." - -#: src/ownership/lifetimes.md:9 -msgid "" -"Lifetimes are always inferred by the compiler: you cannot assign a lifetime " -"yourself." -msgstr "" - -#: src/ownership/lifetimes.md:11 -msgid "" -"Lifetime annotations create constraints; the compiler verifies that there is " -"a valid solution." -msgstr "" - -#: src/ownership/lifetimes.md:13 -msgid "" -"Lifetimes for function arguments and return values must be fully specified, " -"but Rust allows these to be elided in most cases with [a few simple rules]" -"(https://doc.rust-lang.org/nomicon/lifetime-elision.html)." -msgstr "" - -#: src/ownership/lifetimes-function-calls.md:3 -#, fuzzy -msgid "" -"In addition to borrowing its arguments, a function can return a borrowed " -"value:" -msgstr "" -"Zusätzlich zum Ausleihen ihrer Argumente kann eine Funktion einen geliehenen " -"Wert zurückgeben:" - -#: src/ownership/lifetimes-function-calls.md:5 -msgid "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Point(i32, i32);\n" -"\n" -"fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n" -" if p1.0 < p2.0 { p1 } else { p2 }\n" -"}\n" -"\n" -"fn main() {\n" -" let p1: Point = Point(10, 10);\n" -" let p2: Point = Point(20, 20);\n" -" let p3: &Point = left_most(&p1, &p2);\n" -" println!(\"left-most point: {:?}\", p3);\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/lifetimes-function-calls.md:21 -#, fuzzy -msgid "`'a` is a generic parameter, it is inferred by the compiler." -msgstr "„a“ ist ein generischer Parameter, er wird vom Compiler abgeleitet." - -#: src/ownership/lifetimes-function-calls.md:22 -#, fuzzy -msgid "Lifetimes start with `'` and `'a` is a typical default name." -msgstr "Lebensdauern beginnen mit `'` und `'a` ist ein typischer Standardname." - -#: src/ownership/lifetimes-function-calls.md:25 -#, fuzzy -msgid "" -"The _at least_ part is important when parameters are in different scopes." -msgstr "" -"Der Teil _at least_ ist wichtig, wenn sich Parameter in unterschiedlichen " -"Geltungsbereichen befinden." - -#: src/ownership/lifetimes-function-calls.md:31 -#, fuzzy -msgid "" -"Move the declaration of `p2` and `p3` into a new scope (`{ ... }`), " -"resulting in the following code:" -msgstr "" -"Setzen Sie den Arbeitsbereich zurück und ändern Sie die Funktionssignatur zu " -"`fn left_most<'a, 'b>(p1: &'a Point, p2: &'a Point) -> &'b Point`. Dies wird " -"nicht kompiliert, da die Beziehung zwischen den Lebensdauern „a“ und „b“ " -"unklar ist." - -#: src/ownership/lifetimes-function-calls.md:32 -#, fuzzy -msgid "" -"```rust,ignore\n" -"#[derive(Debug)]\n" -"struct Point(i32, i32);\n" -"\n" -"fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n" -" if p1.0 < p2.0 { p1 } else { p2 }\n" -"}\n" -"\n" -"fn main() {\n" -" let p1: Point = Point(10, 10);\n" -" let p3: &Point;\n" -" {\n" -" let p2: Point = Point(20, 20);\n" -" p3 = left_most(&p1, &p2);\n" -" }\n" -" println!(\"left-most point: {:?}\", p3);\n" -"}\n" -"```" -msgstr "Eine andere Möglichkeit, es zu erklären:" - -#: src/ownership/lifetimes-function-calls.md:50 -#, fuzzy -msgid "Note how this does not compile since `p3` outlives `p2`." -msgstr "" -"Zwei Referenzen auf zwei Werte werden von einer Funktion ausgeliehen und die " -"Funktion kehrt zurück eine andere Referenz." - -#: src/ownership/lifetimes-function-calls.md:52 -#, fuzzy -msgid "" -"Reset the workspace and change the function signature to `fn left_most<'a, " -"'b>(p1: &'a Point, p2: &'a Point) -> &'b Point`. This will not compile " -"because the relationship between the lifetimes `'a` and `'b` is unclear." -msgstr "" -"Es muss von einem dieser beiden Eingänge stammen (oder von einer globalen " -"Variablen)." - -#: src/ownership/lifetimes-function-calls.md:53 -#, fuzzy -msgid "Another way to explain it:" -msgstr "" -"Welches ist es? Der Compiler muss es wissen, damit die zurückgegebene " -"Referenz auf der Aufrufseite nicht verwendet wird länger als eine Variable, " -"von der die Referenz stammt." - -#: src/ownership/lifetimes-function-calls.md:54 -msgid "" -"Two references to two values are borrowed by a function and the function " -"returns another reference." -msgstr "" - -#: src/ownership/lifetimes-function-calls.md:56 -msgid "" -"It must have come from one of those two inputs (or from a global variable)." -msgstr "" - -#: src/ownership/lifetimes-function-calls.md:57 -msgid "" -"Which one is it? The compiler needs to know, so at the call site the " -"returned reference is not used for longer than a variable from where the " -"reference came from." -msgstr "" - -#: src/ownership/lifetimes-data-structures.md:3 -#, fuzzy -msgid "" -"If a data type stores borrowed data, it must be annotated with a lifetime:" -msgstr "" -"Wenn ein Datentyp geliehene Daten speichert, muss er mit einer Lebensdauer " -"versehen werden:" - -#: src/ownership/lifetimes-data-structures.md:5 -msgid "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Highlight<'doc>(&'doc str);\n" -"\n" -"fn erase(text: String) {\n" -" println!(\"Bye {text}!\");\n" -"}\n" -"\n" -"fn main() {\n" -" let text = String::from(\"The quick brown fox jumps over the lazy dog." -"\");\n" -" let fox = Highlight(&text[4..19]);\n" -" let dog = Highlight(&text[35..43]);\n" -" // erase(text);\n" -" println!(\"{fox:?}\");\n" -" println!(\"{dog:?}\");\n" -"}\n" -"```" -msgstr "" - -#: src/ownership/lifetimes-data-structures.md:25 -#, fuzzy -msgid "" -"In the above example, the annotation on `Highlight` enforces that the data " -"underlying the contained `&str` lives at least as long as any instance of " -"`Highlight` that uses that data." -msgstr "" -"Im obigen Beispiel erzwingt die Anmerkung zu `Highlight`, dass die Daten, " -"die dem enthaltenen `&str` zugrunde liegen, mindestens so lange leben wie " -"jede Instanz von `Highlight`, die diese Daten verwendet." - -#: src/ownership/lifetimes-data-structures.md:26 -#, fuzzy -msgid "" -"If `text` is consumed before the end of the lifetime of `fox` (or `dog`), " -"the borrow checker throws an error." -msgstr "" -"Wenn `text` vor dem Ende der Lebensdauer von `fox` (oder `dog`) verbraucht " -"wird, wirft der Borrow-Checker einen Fehler." - -#: src/ownership/lifetimes-data-structures.md:27 -#, fuzzy -msgid "" -"Types with borrowed data force users to hold on to the original data. This " -"can be useful for creating lightweight views, but it generally makes them " -"somewhat harder to use." -msgstr "" -"Typen mit geliehenen Daten zwingen Benutzer, an den Originaldaten " -"festzuhalten. Dies kann nützlich sein, um einfache Ansichten zu erstellen, " -"macht sie jedoch im Allgemeinen etwas schwieriger zu verwenden." - -#: src/ownership/lifetimes-data-structures.md:28 -#, fuzzy -msgid "When possible, make data structures own their data directly." -msgstr "" -"Wenn möglich, machen Sie Datenstrukturen direkt Eigentümer ihrer Daten." - -#: src/ownership/lifetimes-data-structures.md:29 -#, fuzzy -msgid "" -"Some structs with multiple references inside can have more than one lifetime " -"annotation. This can be necessary if there is a need to describe lifetime " -"relationships between the references themselves, in addition to the lifetime " -"of the struct itself. Those are very advanced use cases." -msgstr "" -"Einige Strukturen mit mehreren darin enthaltenen Referenzen können mehr als " -"eine lebenslange Anmerkung haben. Dies kann erforderlich sein, wenn " -"zusätzlich zur Lebensdauer der Struktur selbst Lebensdauerbeziehungen " -"zwischen den Referenzen selbst beschrieben werden müssen. Das sind sehr " -"fortgeschrittene Anwendungsfälle." - -#: src/exercises/day-1/afternoon.md:1 -#, fuzzy -msgid "Day 1: Afternoon Exercises" -msgstr "Tag 1: Nachmittagsübungen" - -#: src/exercises/day-1/afternoon.md:3 -#, fuzzy -msgid "We will look at two things:" -msgstr "Wir werden uns zwei Dinge ansehen:" - -#: src/exercises/day-1/afternoon.md:5 -#, fuzzy -msgid "A small book library," -msgstr "Iteratoren und Besitz (schwer)." - -#: src/exercises/day-1/afternoon.md:7 -msgid "Iterators and ownership (hard)." -msgstr "" - -#: src/exercises/day-1/book-library.md:3 -#, fuzzy -msgid "" -"We will learn much more about structs and the `Vec` type tomorrow. For " -"now, you just need to know part of its API:" -msgstr "" -"Wir werden morgen viel mehr über Strukturen und den Typ `Vec` lernen. Zur " -"Zeit, Sie müssen nur einen Teil seiner API kennen:" - -#: src/exercises/day-1/book-library.md:6 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut vec = vec![10, 20];\n" -" vec.push(30);\n" -" let midpoint = vec.len() / 2;\n" -" println!(\"middle value: {}\", vec[midpoint]);\n" -" for item in &vec {\n" -" println!(\"item: {item}\");\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/exercises/day-1/book-library.md:18 -#, fuzzy -msgid "" -"Use this to create a library application. Copy the code below to and update the types to make it compile:" -msgstr "" -"Verwenden Sie dies, um eine Bibliotheksanwendung zu erstellen. Kopieren Sie " -"den folgenden Code nach und aktualisieren Sie " -"die Typen, damit es kompiliert wird:" - -#: src/exercises/day-1/book-library.md:21 -msgid "" -"```rust,should_panic\n" -"struct Library {\n" -" books: Vec,\n" -"}\n" -"\n" -"struct Book {\n" -" title: String,\n" -" year: u16,\n" -"}\n" -"\n" -"impl Book {\n" -" // This is a constructor, used below.\n" -" fn new(title: &str, year: u16) -> Book {\n" -" Book {\n" -" title: String::from(title),\n" -" year,\n" -" }\n" -" }\n" -"}\n" -"\n" -"// Implement the methods below. Update the `self` parameter to\n" -"// indicate the method's required level of ownership over the object:\n" -"//\n" -"// - `&self` for shared read-only access,\n" -"// - `&mut self` for unique and mutable access,\n" -"// - `self` for unique access by value.\n" -"impl Library {\n" -" fn new() -> Library {\n" -" todo!(\"Initialize and return a `Library` value\")\n" -" }\n" -"\n" -" //fn len(self) -> usize {\n" -" // todo!(\"Return the length of `self.books`\")\n" -" //}\n" -"\n" -" //fn is_empty(self) -> bool {\n" -" // todo!(\"Return `true` if `self.books` is empty\")\n" -" //}\n" -"\n" -" //fn add_book(self, book: Book) {\n" -" // todo!(\"Add a new book to `self.books`\")\n" -" //}\n" -"\n" -" //fn print_books(self) {\n" -" // todo!(\"Iterate over `self.books` and each book's title and " -"year\")\n" -" //}\n" -"\n" -" //fn oldest_book(self) -> Option<&Book> {\n" -" // todo!(\"Return a reference to the oldest book (if any)\")\n" -" //}\n" -"}\n" -"\n" -"// This shows the desired behavior. Uncomment the code below and\n" -"// implement the missing methods. You will need to update the\n" -"// method signatures, including the \"self\" parameter! You may\n" -"// also need to update the variable bindings within main.\n" -"fn main() {\n" -" let library = Library::new();\n" -"\n" -" //println!(\"The library is empty: {}\", library.is_empty());\n" -" //\n" -" //library.add_book(Book::new(\"Lord of the Rings\", 1954));\n" -" //library.add_book(Book::new(\"Alice's Adventures in Wonderland\", " -"1865));\n" -" //\n" -" //println!(\"The library is no longer empty: {}\", library.is_empty());\n" -" //\n" -" //\n" -" //library.print_books();\n" -" //\n" -" //match library.oldest_book() {\n" -" // Some(book) => println!(\"The oldest book is {}\", book.title),\n" -" // None => println!(\"The library is empty!\"),\n" -" //}\n" -" //\n" -" //println!(\"The library has {} books\", library.len());\n" -" //library.print_books();\n" -"}\n" -"```" -msgstr "" - -#: src/exercises/day-1/book-library.md:102 -#, fuzzy -msgid "[Solution](solutions-afternoon.md#designing-a-library)" -msgstr "[Lösung](solutions-afternoon.md#designing-a-library)" - -#: src/exercises/day-1/iterators-and-ownership.md:3 -#, fuzzy -msgid "" -"The ownership model of Rust affects many APIs. An example of this is the " -"[`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html) and " -"[`IntoIterator`](https://doc.rust-lang.org/std/iter/trait.IntoIterator.html) " -"traits." -msgstr "" -"Das Eigentumsmodell von Rust betrifft viele APIs. Ein Beispiel hierfür ist " -"die [`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html) und " -"[`IntoIterator`](https://doc.rust-lang.org/std/iter/trait.IntoIterator.html) " -"Züge." - -#: src/exercises/day-1/iterators-and-ownership.md:8 src/bare-metal/no_std.md:28 -#, fuzzy -msgid "`Iterator`" -msgstr "`Iterator`" - -#: src/exercises/day-1/iterators-and-ownership.md:10 -#, fuzzy -msgid "" -"Traits are like interfaces: they describe behavior (methods) for a type. The " -"`Iterator` trait simply says that you can call `next` until you get `None` " -"back:" -msgstr "" -"Merkmale sind wie Schnittstellen: Sie beschreiben das Verhalten (Methoden) " -"für einen Typ. Der Das `Iterator`\\-Merkmal sagt einfach, dass Sie `next` " -"aufrufen können, bis Sie `None` zurückbekommen:" - -#: src/exercises/day-1/iterators-and-ownership.md:13 -msgid "" -"```rust\n" -"pub trait Iterator {\n" -" type Item;\n" -" fn next(&mut self) -> Option;\n" -"}\n" -"```" -msgstr "" - -#: src/exercises/day-1/iterators-and-ownership.md:20 -#, fuzzy -msgid "You use this trait like this:" -msgstr "Sie verwenden diese Eigenschaft wie folgt:" - -#: src/exercises/day-1/iterators-and-ownership.md:22 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let v: Vec = vec![10, 20, 30];\n" -" let mut iter = v.iter();\n" -"\n" -" println!(\"v[0]: {:?}\", iter.next());\n" -" println!(\"v[1]: {:?}\", iter.next());\n" -" println!(\"v[2]: {:?}\", iter.next());\n" -" println!(\"No more items: {:?}\", iter.next());\n" -"}\n" -"```" -msgstr "" - -#: src/exercises/day-1/iterators-and-ownership.md:34 -#, fuzzy -msgid "What is the type returned by the iterator? Test your answer here:" -msgstr "Welchen Typ gibt der Iterator zurück? Testen Sie Ihre Antwort hier:" - -#: src/exercises/day-1/iterators-and-ownership.md:36 -msgid "" -"```rust,editable,compile_fail\n" -"fn main() {\n" -" let v: Vec = vec![10, 20, 30];\n" -" let mut iter = v.iter();\n" -"\n" -" let v0: Option<..> = iter.next();\n" -" println!(\"v0: {v0:?}\");\n" -"}\n" -"```" -msgstr "" - -#: src/exercises/day-1/iterators-and-ownership.md:46 -#, fuzzy -msgid "Why is this type used?" -msgstr "Warum wird dieser Typ verwendet?" - -#: src/exercises/day-1/iterators-and-ownership.md:48 -#, fuzzy -msgid "`IntoIterator`" -msgstr "`IntoIterator`" - -#: src/exercises/day-1/iterators-and-ownership.md:50 -#, fuzzy -msgid "" -"The `Iterator` trait tells you how to _iterate_ once you have created an " -"iterator. The related trait `IntoIterator` tells you how to create the " -"iterator:" -msgstr "" -"Die Eigenschaft „Iterator“ sagt Ihnen, wie Sie _iteraten_, sobald Sie eine " -"erstellt haben Iterator. Die zugehörige Eigenschaft `IntoIterator` sagt " -"Ihnen, wie Sie den Iterator erstellen:" - -#: src/exercises/day-1/iterators-and-ownership.md:53 -msgid "" -"```rust\n" -"pub trait IntoIterator {\n" -" type Item;\n" -" type IntoIter: Iterator;\n" -"\n" -" fn into_iter(self) -> Self::IntoIter;\n" -"}\n" -"```" -msgstr "" - -#: src/exercises/day-1/iterators-and-ownership.md:62 -#, fuzzy -msgid "" -"The syntax here means that every implementation of `IntoIterator` must " -"declare two types:" -msgstr "" -"Die Syntax hier bedeutet, dass jede Implementierung von `IntoIterator` muss " -"deklarieren Sie zwei Arten:" - -#: src/exercises/day-1/iterators-and-ownership.md:65 -#, fuzzy -msgid "`Item`: the type we iterate over, such as `i8`," -msgstr "`Item`: der Typ, über den wir iterieren, wie z. B. `i8`," - -#: src/exercises/day-1/iterators-and-ownership.md:66 -#, fuzzy -msgid "`IntoIter`: the `Iterator` type returned by the `into_iter` method." -msgstr "" -"`IntoIter`: der `Iterator`\\-Typ, der von der `into_iter`\\-Methode " -"zurückgegeben wird." - -#: src/exercises/day-1/iterators-and-ownership.md:68 -#, fuzzy -msgid "" -"Note that `IntoIter` and `Item` are linked: the iterator must have the same " -"`Item` type, which means that it returns `Option`" -msgstr "" -"Beachten Sie, dass „IntoIter“ und „Item“ verknüpft sind: Der Iterator muss " -"dasselbe haben `Item`\\-Typ, was bedeutet, dass es `Option` zurückgibt" - -#: src/exercises/day-1/iterators-and-ownership.md:71 -#, fuzzy -msgid "Like before, what is the type returned by the iterator?" -msgstr "Welchen Typ gibt der Iterator wie zuvor zurück?" - -#: src/exercises/day-1/iterators-and-ownership.md:73 -msgid "" -"```rust,editable,compile_fail\n" -"fn main() {\n" -" let v: Vec = vec![String::from(\"foo\"), String::" -"from(\"bar\")];\n" -" let mut iter = v.into_iter();\n" -"\n" -" let v0: Option<..> = iter.next();\n" -" println!(\"v0: {v0:?}\");\n" -"}\n" -"```" -msgstr "" - -#: src/exercises/day-1/iterators-and-ownership.md:83 -#, fuzzy -msgid "`for` Loops" -msgstr "`for`\\-Schleifen" - -#: src/exercises/day-1/iterators-and-ownership.md:85 -#, fuzzy -msgid "" -"Now that we know both `Iterator` and `IntoIterator`, we can build `for` " -"loops. They call `into_iter()` on an expression and iterates over the " -"resulting iterator:" -msgstr "" -"Jetzt, da wir sowohl „Iterator“ als auch „IntoIterator“ kennen, können wir " -"„for“-Schleifen bauen. Sie rufen `into_iter()` für einen Ausdruck auf und " -"iterieren über das Ergebnis Iterator:" - -#: src/exercises/day-1/iterators-and-ownership.md:89 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let v: Vec = vec![String::from(\"foo\"), String::" -"from(\"bar\")];\n" -"\n" -" for word in &v {\n" -" println!(\"word: {word}\");\n" -" }\n" -"\n" -" for word in v {\n" -" println!(\"word: {word}\");\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/exercises/day-1/iterators-and-ownership.md:103 -#, fuzzy -msgid "What is the type of `word` in each loop?" -msgstr "Was ist die Art von „Wort“ in jeder Schleife?" - -#: src/exercises/day-1/iterators-and-ownership.md:105 -#, fuzzy -msgid "" -"Experiment with the code above and then consult the documentation for [`impl " -"IntoIterator for &Vec`](https://doc.rust-lang.org/std/vec/struct.Vec." -"html#impl-IntoIterator-for-%26%27a%20Vec%3CT%2C%20A%3E) and [`impl " -"IntoIterator for Vec`](https://doc.rust-lang.org/std/vec/struct.Vec." -"html#impl-IntoIterator-for-Vec%3CT%2C%20A%3E) to check your answers." -msgstr "" -"Experimentieren Sie mit dem obigen Code und konsultieren Sie dann die " -"Dokumentation für [`impl IntoIterator für &Vec`](https://doc.rust-lang." -"org/std/vec/struct.Vec.html#impl-IntoIterator-for-" -"%26%27a%20Vec%3CT%2C%20A%3E) und [`impl IntoIterator for Vec`](https://" -"doc.rust-lang.org/std/vec/struct.Vec.html#impl-IntoIterator-for-" -"Vec%3CT%2C%20A%3E) um Ihre Antworten zu überprüfen." - -#: src/welcome-day-2.md:1 -#, fuzzy -msgid "Welcome to Day 2" -msgstr "Willkommen zu Tag 2" - -#: src/welcome-day-2.md:3 -#, fuzzy -msgid "Now that we have seen a fair amount of Rust, we will continue with:" -msgstr "" -"Nachdem wir nun eine ganze Menge Rust gesehen haben, fahren wir fort mit:" - -#: src/welcome-day-2.md:5 -msgid "Structs, enums, methods." -msgstr "" - -#: src/welcome-day-2.md:7 -msgid "Pattern matching: destructuring enums, structs, and arrays." -msgstr "" - -#: src/welcome-day-2.md:9 -msgid "" -"Control flow constructs: `if`, `if let`, `while`, `while let`, `break`, and " -"`continue`." -msgstr "" - -#: src/welcome-day-2.md:12 -msgid "" -"The Standard Library: `String`, `Option` and `Result`, `Vec`, `HashMap`, " -"`Rc` and `Arc`." -msgstr "" - -#: src/welcome-day-2.md:15 -msgid "Modules: visibility, paths, and filesystem hierarchy." -msgstr "" - -#: src/structs.md:3 -#, fuzzy -msgid "Like C and C++, Rust has support for custom structs:" -msgstr "Wie C und C++ unterstützt Rust benutzerdefinierte Strukturen:" - -#: src/structs.md:5 -msgid "" -"```rust,editable\n" -"struct Person {\n" -" name: String,\n" -" age: u8,\n" -"}\n" -"\n" -"fn main() {\n" -" let mut peter = Person {\n" -" name: String::from(\"Peter\"),\n" -" age: 27,\n" -" };\n" -" println!(\"{} is {} years old\", peter.name, peter.age);\n" -" \n" -" peter.age = 28;\n" -" println!(\"{} is {} years old\", peter.name, peter.age);\n" -" \n" -" let jackie = Person {\n" -" name: String::from(\"Jackie\"),\n" -" ..peter\n" -" };\n" -" println!(\"{} is {} years old\", jackie.name, jackie.age);\n" -"}\n" -"```" -msgstr "" - -#: src/structs.md:31 src/enums.md:34 src/enums/sizes.md:29 src/methods.md:30 -#: src/methods/example.md:46 src/pattern-matching.md:25 -#: src/pattern-matching/match-guards.md:22 src/control-flow/blocks.md:42 -#, fuzzy -msgid "Key Points:" -msgstr "Wichtige Punkte:" - -#: src/structs.md:33 -msgid "Structs work like in C or C++." -msgstr "" - -#: src/structs.md:34 -msgid "Like in C++, and unlike in C, no typedef is needed to define a type." -msgstr "" - -#: src/structs.md:35 -msgid "Unlike in C++, there is no inheritance between structs." -msgstr "" - -#: src/structs.md:36 -msgid "" -"Methods are defined in an `impl` block, which we will see in following " -"slides." -msgstr "" - -#: src/structs.md:37 -msgid "" -"This may be a good time to let people know there are different types of " -"structs. " -msgstr "" - -#: src/structs.md:38 -msgid "" -"Zero-sized structs `e.g., struct Foo;` might be used when implementing a " -"trait on some type but don’t have any data that you want to store in the " -"value itself. " -msgstr "" - -#: src/structs.md:39 -msgid "" -"The next slide will introduce Tuple structs, used when the field names are " -"not important." -msgstr "" - -#: src/structs.md:40 -msgid "" -"The syntax `..peter` allows us to copy the majority of the fields from the " -"old struct without having to explicitly type it all out. It must always be " -"the last element." -msgstr "" - -#: src/structs/tuple-structs.md:3 -#, fuzzy -msgid "If the field names are unimportant, you can use a tuple struct:" -msgstr "" -"Wenn die Feldnamen unwichtig sind, können Sie eine Tupelstruktur verwenden:" - -#: src/structs/tuple-structs.md:5 -msgid "" -"```rust,editable\n" -"struct Point(i32, i32);\n" -"\n" -"fn main() {\n" -" let p = Point(17, 23);\n" -" println!(\"({}, {})\", p.0, p.1);\n" -"}\n" -"```" -msgstr "" - -#: src/structs/tuple-structs.md:14 -#, fuzzy -msgid "This is often used for single-field wrappers (called newtypes):" -msgstr "Dies wird häufig für Einzelfeld-Wrapper (genannt Newtypes) verwendet:" - -#: src/structs/tuple-structs.md:16 -msgid "" -"```rust,editable,compile_fail\n" -"struct PoundsOfForce(f64);\n" -"struct Newtons(f64);\n" -"\n" -"fn compute_thruster_force() -> PoundsOfForce {\n" -" todo!(\"Ask a rocket scientist at NASA\")\n" -"}\n" -"\n" -"fn set_thruster_force(force: Newtons) {\n" -" // ...\n" -"}\n" -"\n" -"fn main() {\n" -" let force = compute_thruster_force();\n" -" set_thruster_force(force);\n" -"}\n" -"\n" -"```" -msgstr "" - -#: src/structs/tuple-structs.md:37 -msgid "" -"Newtypes are a great way to encode additional information about the value in " -"a primitive type, for example:" -msgstr "" - -#: src/structs/tuple-structs.md:38 -msgid "The number is measured in some units: `Newtons` in the example above." -msgstr "" - -#: src/structs/tuple-structs.md:39 -msgid "" -"The value passed some validation when it was created, so you no longer have " -"to validate it again at every use: 'PhoneNumber(String)`or`OddNumber(u32)\\`." -msgstr "" - -#: src/structs/tuple-structs.md:40 -msgid "" -"Demonstrate how to add a `f64` value to a `Newtons` type by accessing the " -"single field in the newtype." -msgstr "" - -#: src/structs/tuple-structs.md:41 -msgid "" -"Rust generally doesn’t like inexplicit things, like automatic unwrapping or " -"for instance using booleans as integers." -msgstr "" - -#: src/structs/tuple-structs.md:42 -msgid "Operator overloading is discussed on Day 3 (generics). " -msgstr "" - -#: src/structs/field-shorthand.md:3 -#, fuzzy -msgid "" -"If you already have variables with the right names, then you can create the " -"struct using a shorthand:" -msgstr "" -"Wenn Sie bereits Variablen mit den richtigen Namen haben, können Sie die " -"erstellen struct mit einer Abkürzung:" - -#: src/structs/field-shorthand.md:6 -msgid "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Person {\n" -" name: String,\n" -" age: u8,\n" -"}\n" -"\n" -"impl Person {\n" -" fn new(name: String, age: u8) -> Person {\n" -" Person { name, age }\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" let peter = Person::new(String::from(\"Peter\"), 27);\n" -" println!(\"{peter:?}\");\n" -"}\n" -"```" -msgstr "" - -#: src/structs/field-shorthand.md:27 -msgid "" -"The `new` function could be written using `Self` as a type, as it is " -"interchangeable with the struct type name" -msgstr "" - -#: src/structs/field-shorthand.md:29 -msgid "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Person {\n" -" name: String,\n" -" age: u8,\n" -"}\n" -"impl Person {\n" -" fn new(name: String, age: u8) -> Self {\n" -" Self { name, age }\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/structs/field-shorthand.md:41 -msgid "" -"Implement the `Default` trait for the struct. Define some fields and use the " -"default values for the other fields." -msgstr "" - -#: src/structs/field-shorthand.md:43 -msgid "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Person {\n" -" name: String,\n" -" age: u8,\n" -"}\n" -"impl Default for Person {\n" -" fn default() -> Person {\n" -" Person {\n" -" name: \"Bot\".to_string(),\n" -" age: 0,\n" -" }\n" -" }\n" -"}\n" -"fn create_default() {\n" -" let tmp = Person {\n" -" ..Default::default()\n" -" };\n" -" let tmp = Person {\n" -" name: \"Sam\".to_string(),\n" -" ..Default::default()\n" -" };\n" -"}\n" -"```" -msgstr "" - -#: src/structs/field-shorthand.md:68 -msgid "Methods are defined in the `impl` block." -msgstr "" - -#: src/structs/field-shorthand.md:69 -msgid "" -"Use struct update syntax to define a new structure using `peter`. Note that " -"the variable `peter` will no longer be accessible afterwards." -msgstr "" - -#: src/structs/field-shorthand.md:70 -msgid "" -"Use `{:#?}` when printing structs to request the `Debug` representation." -msgstr "" - #: src/enums.md:3 #, fuzzy msgid "" @@ -6327,7 +4750,7 @@ msgstr "" #, fuzzy msgid "" "This page offers an enum type `CoinFlip` with two variants `Heads` and " -"`Tail`. You might note the namespace when using variants." +"`Tails`. You might note the namespace when using variants." msgstr "" "Diese Seite bietet einen Aufzählungstyp `CoinFlip` mit zwei Varianten " "`Heads` und `Tail`. Beachten Sie bei der Verwendung von Varianten " @@ -6472,13 +4895,12 @@ msgstr "" #: src/enums/sizes.md:5 msgid "" "```rust,editable\n" +"use std::any::type_name;\n" "use std::mem::{align_of, size_of};\n" "\n" -"macro_rules! dbg_size {\n" -" ($t:ty) => {\n" -" println!(\"{}: size {} bytes, align: {} bytes\",\n" -" stringify!($t), size_of::<$t>(), align_of::<$t>());\n" -" };\n" +"fn dbg_size() {\n" +" println!(\"{}: size {} bytes, align: {} bytes\",\n" +" type_name::(), size_of::(), align_of::());\n" "}\n" "\n" "enum Foo {\n" @@ -6487,12 +4909,12 @@ msgid "" "}\n" "\n" "fn main() {\n" -" dbg_size!(Foo);\n" +" dbg_size::();\n" "}\n" "```" msgstr "" -#: src/enums/sizes.md:25 +#: src/enums/sizes.md:24 #, fuzzy msgid "" "See the [Rust Reference](https://doc.rust-lang.org/reference/type-layout." @@ -6501,18 +4923,18 @@ msgstr "" "Siehe die \\[Rust-Referenz\\] (https://doc.rust-lang.org/reference/type-" "layout.html)." -#: src/enums/sizes.md:31 +#: src/enums/sizes.md:30 msgid "" "Internally Rust is using a field (discriminant) to keep track of the enum " "variant." msgstr "" -#: src/enums/sizes.md:33 +#: src/enums/sizes.md:32 msgid "" "You can control the discriminant if needed (e.g., for compatibility with C):" msgstr "" -#: src/enums/sizes.md:35 +#: src/enums/sizes.md:34 msgid "" "```rust,editable\n" "#[repr(u32)]\n" @@ -6530,57 +4952,57 @@ msgid "" "```" msgstr "" -#: src/enums/sizes.md:50 +#: src/enums/sizes.md:49 msgid "" "Without `repr`, the discriminant type takes 2 bytes, because 10001 fits 2 " "bytes." msgstr "" -#: src/enums/sizes.md:54 +#: src/enums/sizes.md:53 msgid "Try out other types such as" msgstr "" -#: src/enums/sizes.md:56 +#: src/enums/sizes.md:55 msgid "`dbg_size!(bool)`: size 1 bytes, align: 1 bytes," msgstr "" -#: src/enums/sizes.md:57 +#: src/enums/sizes.md:56 msgid "" "`dbg_size!(Option)`: size 1 bytes, align: 1 bytes (niche optimization, " "see below)," msgstr "" -#: src/enums/sizes.md:58 +#: src/enums/sizes.md:57 msgid "`dbg_size!(&i32)`: size 8 bytes, align: 8 bytes (on a 64-bit machine)," msgstr "" -#: src/enums/sizes.md:59 +#: src/enums/sizes.md:58 msgid "" "`dbg_size!(Option<&i32>)`: size 8 bytes, align: 8 bytes (null pointer " "optimization, see below)." msgstr "" -#: src/enums/sizes.md:61 +#: src/enums/sizes.md:60 msgid "" -"Niche optimization: Rust will merge use unused bit patterns for the enum " +"Niche optimization: Rust will merge unused bit patterns for the enum " "discriminant." msgstr "" -#: src/enums/sizes.md:64 +#: src/enums/sizes.md:63 msgid "" "Null pointer optimization: For [some types](https://doc.rust-lang.org/std/" "option/#representation), Rust guarantees that `size_of::()` equals " "`size_of::>()`." msgstr "" -#: src/enums/sizes.md:68 +#: src/enums/sizes.md:67 msgid "" "Example code if you want to show how the bitwise representation _may_ look " "like in practice. It's important to note that the compiler provides no " "guarantees regarding this representation, therefore this is totally unsafe." msgstr "" -#: src/enums/sizes.md:71 +#: src/enums/sizes.md:70 msgid "" "```rust,editable\n" "use std::mem::transmute;\n" @@ -6619,13 +5041,13 @@ msgid "" "```" msgstr "" -#: src/enums/sizes.md:106 +#: src/enums/sizes.md:105 msgid "" "More complex example if you want to discuss what happens when we chain more " "than 256 `Option`s together." msgstr "" -#: src/enums/sizes.md:108 +#: src/enums/sizes.md:107 msgid "" "```rust,editable\n" "#![recursion_limit = \"1000\"]\n" @@ -6678,293 +5100,224 @@ msgid "" "```" msgstr "" -#: src/methods.md:3 -#, fuzzy +#: src/control-flow/novel.md:3 msgid "" -"Rust allows you to associate functions with your new types. You do this with " -"an `impl` block:" +"Rust has a few control flow constructs which differ from other languages. " +"They are used for pattern matching:" msgstr "" -"Mit Rust können Sie Ihren neuen Typen Funktionen zuordnen. Das machst du mit " -"einem `impl`\\-Block:" -#: src/methods.md:6 +#: src/control-flow/novel.md:6 src/control-flow/if-let-expressions.md:1 +#, fuzzy +msgid "`if let` expressions" +msgstr "`if let`\\-Ausdrücke" + +#: src/control-flow/novel.md:7 +#, fuzzy +msgid "`while let` expressions" +msgstr "while let-Ausdrücke" + +#: src/control-flow/novel.md:8 src/control-flow/match-expressions.md:1 +#, fuzzy +msgid "`match` expressions" +msgstr "`Match`\\-Ausdrücke" + +#: src/control-flow/if-let-expressions.md:3 +msgid "" +"The [`if let` expression](https://doc.rust-lang.org/reference/expressions/if-" +"expr.html#if-let-expressions) lets you execute different code depending on " +"whether a value matches a pattern:" +msgstr "" + +#: src/control-flow/if-let-expressions.md:7 msgid "" "```rust,editable\n" -"#[derive(Debug)]\n" -"struct Person {\n" -" name: String,\n" -" age: u8,\n" -"}\n" -"\n" -"impl Person {\n" -" fn say_hello(&self) {\n" -" println!(\"Hello, my name is {}\", self.name);\n" +"fn main() {\n" +" let arg = std::env::args().next();\n" +" if let Some(value) = arg {\n" +" println!(\"Program name: {value}\");\n" +" } else {\n" +" println!(\"Missing name?\");\n" " }\n" "}\n" -"\n" +"```" +msgstr "" + +#: src/control-flow/if-let-expressions.md:18 +#: src/control-flow/while-let-expressions.md:21 +#: src/control-flow/match-expressions.md:23 +#, fuzzy +msgid "" +"See [pattern matching](../pattern-matching.md) for more details on patterns " +"in Rust." +msgstr "" +"Siehe [pattern matching](../pattern-matching.md) für weitere Details zu " +"Mustern in Rost." + +#: src/control-flow/if-let-expressions.md:23 +msgid "" +"Unlike `match`, `if let` does not have to cover all branches. This can make " +"it more concise than `match`." +msgstr "" + +#: src/control-flow/if-let-expressions.md:24 +msgid "A common usage is handling `Some` values when working with `Option`." +msgstr "" + +#: src/control-flow/if-let-expressions.md:25 +msgid "" +"Unlike `match`, `if let` does not support guard clauses for pattern matching." +msgstr "" + +#: src/control-flow/if-let-expressions.md:26 +msgid "" +"Since 1.65, a similar [let-else](https://doc.rust-lang.org/rust-by-example/" +"flow_control/let_else.html) construct allows to do a destructuring " +"assignment, or if it fails, execute a block which is required to abort " +"normal control flow (with `panic`/`return`/`break`/`continue`):" +msgstr "" + +#: src/control-flow/if-let-expressions.md:28 +msgid "" +"```rust,editable\n" "fn main() {\n" -" let peter = Person {\n" -" name: String::from(\"Peter\"),\n" -" age: 27,\n" +" println!(\"{:?}\", second_word_to_upper(\"foo bar\"));\n" +"}\n" +" \n" +"fn second_word_to_upper(s: &str) -> Option {\n" +" let mut it = s.split(' ');\n" +" let (Some(_), Some(item)) = (it.next(), it.next()) else {\n" +" return None;\n" " };\n" -" peter.say_hello();\n" +" Some(item.to_uppercase())\n" "}\n" +"\n" "```" msgstr "" -#: src/methods.md:31 +#: src/control-flow/while-let-expressions.md:1 #, fuzzy -msgid "It can be helpful to introduce methods by comparing them to functions." -msgstr "" -"Es kann hilfreich sein, Methoden einzuführen, indem man sie mit Funktionen " -"vergleicht." +msgid "`while let` loops" +msgstr "`while let`\\-Ausdrücke" -#: src/methods.md:32 +#: src/control-flow/while-let-expressions.md:3 #, fuzzy msgid "" -"Methods are called on an instance of a type (such as a struct or enum), the " -"first parameter represents the instance as `self`." +"Like with `if let`, there is a [`while let`](https://doc.rust-lang.org/" +"reference/expressions/loop-expr.html#predicate-pattern-loops) variant which " +"repeatedly tests a value against a pattern:" msgstr "" -"Methoden werden für eine Instanz eines Typs aufgerufen (z. B. eine Struktur " -"oder Aufzählung), der erste Parameter repräsentiert die Instanz als „self“." +"Wie bei `if` gibt es eine `while let`\\-Variante, die einen Wert wiederholt " +"testet gegen ein Muster:" -#: src/methods.md:33 -#, fuzzy -msgid "" -"Developers may choose to use methods to take advantage of method receiver " -"syntax and to help keep them more organized. By using methods we can keep " -"all the implementation code in one predictable place." -msgstr "" -"Entwickler können sich dafür entscheiden, Methoden zu verwenden, um die " -"Methodenempfängersyntax zu nutzen und sie besser organisiert zu halten. " -"Durch die Verwendung von Methoden können wir den gesamten " -"Implementierungscode an einem vorhersehbaren Ort aufbewahren." - -#: src/methods.md:34 -#, fuzzy -msgid "Point out the use of the keyword `self`, a method receiver. " -msgstr "" -"Weisen Sie auf die Verwendung des Schlüsselworts „self“ hin, einem " -"Methodenempfänger." - -#: src/methods.md:35 -#, fuzzy -msgid "" -"Show that it is an abbreviated term for `self:&Self` and perhaps show how " -"the struct name could also be used. " -msgstr "" -"Zeigen Sie, dass es sich um eine Abkürzung für `self:&Self` handelt und " -"zeigen Sie vielleicht, wie der Strukturname auch verwendet werden könnte." - -#: src/methods.md:36 -#, fuzzy -msgid "" -"Explain that `Self` is a type alias for the type the `impl` block is in and " -"can be used elsewhere in the block." -msgstr "" -"Erklären Sie, dass Self ein Typ-Alias für den Typ ist, in dem sich der " -"„impl“-Block befindet, und an anderer Stelle im Block verwendet werden kann." - -#: src/methods.md:37 -#, fuzzy -msgid "" -"Note how `self` is used like other structs and dot notation can be used to " -"refer to individual fields." -msgstr "" -"Beachten Sie, dass self wie andere Strukturen verwendet wird und die " -"Punktnotation verwendet werden kann, um auf einzelne Felder zu verweisen." - -#: src/methods.md:38 -#, fuzzy -msgid "" -"This might be a good time to demonstrate how the `&self` differs from `self` " -"by modifying the code and trying to run say_hello twice." -msgstr "" -"Dies könnte ein guter Zeitpunkt sein, um zu demonstrieren, wie sich `&self` " -"von `self` unterscheidet, indem Sie den Code ändern und versuchen, say_hello " -"zweimal auszuführen." - -#: src/methods.md:39 -#, fuzzy -msgid "We describe the distinction between method receivers next." -msgstr "" -"Als nächstes beschreiben wir die Unterscheidung zwischen Methodenempfängern." - -#: src/methods/receiver.md:3 -#, fuzzy -msgid "" -"The `&self` above indicates that the method borrows the object immutably. " -"There are other possible receivers for a method:" -msgstr "" -"Das obige `&self` gibt an, dass die Methode das Objekt unveränderlich " -"ausleiht. Dort sind weitere mögliche Empfänger für eine Methode:" - -#: src/methods/receiver.md:6 -#, fuzzy -msgid "" -"`&self`: borrows the object from the caller using a shared and immutable " -"reference. The object can be used again afterwards." -msgstr "" -"`&self`: leiht sich das Objekt vom Aufrufer unter Verwendung eines Shared " -"und Immutable Referenz. Das Objekt kann danach wieder verwendet werden." - -#: src/methods/receiver.md:8 -#, fuzzy -msgid "" -"`&mut self`: borrows the object from the caller using a unique and mutable " -"reference. The object can be used again afterwards." -msgstr "" -"`&mut self`: leiht sich das Objekt vom Aufrufer unter Verwendung eines " -"Unique und Mutable Referenz. Das Objekt kann danach wieder verwendet werden." - -#: src/methods/receiver.md:10 -#, fuzzy -msgid "" -"`self`: takes ownership of the object and moves it away from the caller. The " -"method becomes the owner of the object. The object will be dropped " -"(deallocated) when the method returns, unless its ownership is explicitly " -"transmitted. Complete ownership does not automatically mean mutability." -msgstr "" -"`self`: übernimmt den Besitz des Objekts und verschiebt es vom Aufrufer weg. " -"Der Die Methode wird Eigentümer des Objekts. Das Objekt wird gelöscht " -"(deallocated) wenn die Methode zurückkehrt, es sei denn, ihr Besitz ist " -"explizit übermittelt." - -#: src/methods/receiver.md:14 -#, fuzzy -msgid "`mut self`: same as above, but the method can mutate the object. " -msgstr "" -"`mut self`: wie oben, aber während die Methode das Objekt besitzt, kann sie " -"es mutiere es auch. Vollständiges Eigentum bedeutet nicht automatisch " -"Wandelbarkeit." - -#: src/methods/receiver.md:15 -#, fuzzy -msgid "" -"No receiver: this becomes a static method on the struct. Typically used to " -"create constructors which are called `new` by convention." -msgstr "" -"Kein Empfänger: Dies wird zu einer statischen Methode für die Struktur. " -"Typischerweise gewohnt Erstellen Sie Konstruktoren, die per Konvention " -"\"neu\" genannt werden." - -#: src/methods/receiver.md:18 -#, fuzzy -msgid "" -"Beyond variants on `self`, there are also [special wrapper types](https://" -"doc.rust-lang.org/reference/special-types-and-traits.html) allowed to be " -"receiver types, such as `Box`." -msgstr "" -"Neben Varianten von „self“ gibt es auch [spezielle Wrapper-Typen](https://" -"doc.rust-lang.org/reference/special-types-and-traits.html) dürfen " -"Empfängertypen sein, wie z. B. `Box`." - -#: src/methods/receiver.md:24 -#, fuzzy -msgid "" -"Consider emphasizing \"shared and immutable\" and \"unique and mutable\". " -"These constraints always come together in Rust due to borrow checker rules, " -"and `self` is no exception. It isn't possible to reference a struct from " -"multiple locations and call a mutating (`&mut self`) method on it." -msgstr "" -"Erwägen Sie, die Betonung auf „gemeinsam und unveränderlich“ und " -"„einzigartig und veränderlich“ zu legen. Diese Einschränkungen kommen immer " -"zusammen in Rust aufgrund der Borrow-Checker-Regeln, und `self` ist keine " -"Ausnahme. Es wird nicht möglich sein Verweisen Sie auf eine Struktur von " -"mehreren Stellen und rufen Sie eine Mutationsmethode (`&mut self`) darauf " -"auf." - -#: src/methods/example.md:3 +#: src/control-flow/while-let-expressions.md:6 msgid "" "```rust,editable\n" -"#[derive(Debug)]\n" -"struct Race {\n" -" name: String,\n" -" laps: Vec,\n" -"}\n" -"\n" -"impl Race {\n" -" fn new(name: &str) -> Race { // No receiver, a static method\n" -" Race { name: String::from(name), laps: Vec::new() }\n" -" }\n" -"\n" -" fn add_lap(&mut self, lap: i32) { // Exclusive borrowed read-write " -"access to self\n" -" self.laps.push(lap);\n" -" }\n" -"\n" -" fn print_laps(&self) { // Shared and read-only borrowed access to self\n" -" println!(\"Recorded {} laps for {}:\", self.laps.len(), self.name);\n" -" for (idx, lap) in self.laps.iter().enumerate() {\n" -" println!(\"Lap {idx}: {lap} sec\");\n" -" }\n" -" }\n" -"\n" -" fn finish(self) { // Exclusive ownership of self\n" -" let total = self.laps.iter().sum::();\n" -" println!(\"Race {} is finished, total lap time: {}\", self.name, " -"total);\n" -" }\n" -"}\n" -"\n" "fn main() {\n" -" let mut race = Race::new(\"Monaco Grand Prix\");\n" -" race.add_lap(70);\n" -" race.add_lap(68);\n" -" race.print_laps();\n" -" race.add_lap(71);\n" -" race.print_laps();\n" -" race.finish();\n" -" // race.add_lap(42);\n" +" let v = vec![10, 20, 30];\n" +" let mut iter = v.into_iter();\n" +"\n" +" while let Some(x) = iter.next() {\n" +" println!(\"x: {x}\");\n" +" }\n" "}\n" "```" msgstr "" -#: src/methods/example.md:47 -#, fuzzy -msgid "All four methods here use a different method receiver." -msgstr "Alle vier Methoden hier verwenden einen anderen Methodenempfänger." - -#: src/methods/example.md:48 +#: src/control-flow/while-let-expressions.md:17 #, fuzzy msgid "" -"You can point out how that changes what the function can do with the " -"variable values and if/how it can be used again in `main`." +"Here the iterator returned by `v.into_iter()` will return a `Option` on " +"every call to `next()`. It returns `Some(x)` until it is done, after which " +"it will return `None`. The `while let` lets us keep iterating through all " +"items." msgstr "" -"Sie können darauf hinweisen, wie sich das ändert, was die Funktion mit den " -"Variablenwerten machen kann und ob/wie sie wieder in `main` verwendet werden " -"kann." +"Hier gibt der von `v.iter()` zurückgegebene Iterator bei jedem eine " +"`Option` zurück Aufruf von `next()`. Es gibt `Some(x)` zurück, bis es " +"fertig ist, danach wird es gibt \"Keine\" zurück. Das `while let` lässt uns " +"alle Elemente durchlaufen." -#: src/methods/example.md:49 +#: src/control-flow/while-let-expressions.md:26 #, fuzzy msgid "" -"You can showcase the error that appears when trying to call `finish` twice." +"Point out that the `while let` loop will keep going as long as the value " +"matches the pattern." msgstr "" -"Sie können den Fehler zeigen, der auftritt, wenn Sie versuchen, zweimal " -"„finish“ aufzurufen." +"Weisen Sie darauf hin, dass die „while let“-Schleife so lange läuft, wie der " +"Wert mit dem Muster übereinstimmt." -#: src/methods/example.md:50 +#: src/control-flow/while-let-expressions.md:27 #, fuzzy msgid "" -"Note that although the method receivers are different, the non-static " -"functions are called the same way in the main body. Rust enables automatic " -"referencing and dereferencing when calling methods. Rust automatically adds " -"in the `&`, `*`, `muts` so that that object matches the method signature." +"You could rewrite the `while let` loop as an infinite loop with an if " +"statement that breaks when there is no value to unwrap for `iter.next()`. " +"The `while let` provides syntactic sugar for the above scenario." msgstr "" -"Beachten Sie, dass, obwohl die Methodenempfänger unterschiedlich sind, die " -"nicht statischen Funktionen im Hauptteil auf die gleiche Weise aufgerufen " -"werden. Rust ermöglicht die automatische Referenzierung und Dereferenzierung " -"beim Methodenaufruf. Rust fügt automatisch die `&`, `*`, `muts` hinzu, " -"sodass dieses Objekt mit der Methodensignatur übereinstimmt." +"Sie könnten die „while let“-Schleife als Endlosschleife mit einer if-" +"Anweisung umschreiben, die abbricht, wenn es keinen Wert zum Auspacken für " +"„iter.next()“ gibt. Das `while let` liefert syntaktischen Zucker für das " +"obige Szenario." -#: src/methods/example.md:51 +#: src/control-flow/match-expressions.md:3 #, fuzzy msgid "" -"You might point out that `print_laps` is using a vector that is iterated " -"over. We describe vectors in more detail in the afternoon. " +"The [`match` keyword](https://doc.rust-lang.org/reference/expressions/match-" +"expr.html) is used to match a value against one or more patterns. In that " +"sense, it works like a series of `if let` expressions:" +msgstr "" +"Das Schlüsselwort „match“ wird verwendet, um einen Wert mit einem oder " +"mehreren Mustern abzugleichen. In In diesem Sinne funktioniert es wie eine " +"Reihe von `if let`\\-Ausdrücken:" + +#: src/control-flow/match-expressions.md:7 +msgid "" +"```rust,editable\n" +"fn main() {\n" +" match std::env::args().next().as_deref() {\n" +" Some(\"cat\") => println!(\"Will do cat things\"),\n" +" Some(\"ls\") => println!(\"Will ls some files\"),\n" +" Some(\"mv\") => println!(\"Let's move some files\"),\n" +" Some(\"rm\") => println!(\"Uh, dangerous!\"),\n" +" None => println!(\"Hmm, no program name?\"),\n" +" _ => println!(\"Unknown program name!\"),\n" +" }\n" +"}\n" +"```" +msgstr "" + +#: src/control-flow/match-expressions.md:20 +#, fuzzy +msgid "" +"Like `if let`, each match arm must have the same type. The type is the last " +"expression of the block, if any. In the example above, the type is `()`." +msgstr "" +"Wie bei „if let“ muss jeder Match-Arm denselben Typ haben. Der Typ ist der " +"letzte Ausdruck des Blocks, falls vorhanden. Im obigen Beispiel ist der Typ " +"`()`." + +#: src/control-flow/match-expressions.md:28 +msgid "Save the match expression to a variable and print it out." +msgstr "" + +#: src/control-flow/match-expressions.md:29 +msgid "Remove `.as_deref()` and explain the error." +msgstr "" + +#: src/control-flow/match-expressions.md:30 +msgid "" +"`std::env::args().next()` returns an `Option`, but we cannot match " +"against `String`." +msgstr "" + +#: src/control-flow/match-expressions.md:31 +msgid "" +"`as_deref()` transforms an `Option` to `Option<&T::Target>`. In our case, " +"this turns `Option` into `Option<&str>`." +msgstr "" + +#: src/control-flow/match-expressions.md:32 +msgid "" +"We can now use pattern matching to match against the `&str` inside `Option`." msgstr "" -"Sie könnten darauf hinweisen, dass `print_laps` einen Vektor verwendet, der " -"iteriert wird. Am Nachmittag beschreiben wir Vektoren genauer." #: src/pattern-matching.md:3 #, fuzzy @@ -7300,6 +5653,1932 @@ msgstr "" "Die im Guard definierte Bedingung gilt für jeden Ausdruck in einem Muster " "mit einem `|`." +#: src/exercises/day-1/afternoon.md:1 +#, fuzzy +msgid "Day 1: Afternoon Exercises" +msgstr "Tag 1: Nachmittagsübungen" + +#: src/exercises/day-1/afternoon.md:3 +#, fuzzy +msgid "We will look at two things:" +msgstr "Wir werden uns zwei Dinge ansehen:" + +#: src/exercises/day-1/afternoon.md:5 +#, fuzzy +msgid "The Luhn algorithm," +msgstr "Luhn-Algorithmus" + +#: src/exercises/day-1/afternoon.md:7 +#, fuzzy +msgid "An exercise on pattern matching." +msgstr "Enums und Musterabgleich (pattern matching)." + +#: src/exercises/day-1/afternoon.md:11 src/exercises/day-2/afternoon.md:7 +#: src/exercises/bare-metal/afternoon.md:7 +#: src/exercises/concurrency/afternoon.md:13 +#, fuzzy +msgid "" +"After looking at the exercises, you can look at the [solutions](solutions-" +"afternoon.md) provided." +msgstr "" +"Nachdem Sie sich die Übung angesehen haben, können Sie sich die " +"bereitgestellte \\[Lösung\\] ansehen." + +#: src/exercises/day-1/luhn.md:3 +#, fuzzy +msgid "" +"The [Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm) is used " +"to validate credit card numbers. The algorithm takes a string as input and " +"does the following to validate the credit card number:" +msgstr "" +"Dazu dient der [Luhn-Algorithmus](https://en.wikipedia.org/wiki/" +"Luhn_algorithm). Kreditkartennummern validieren. Der Algorithmus nimmt eine " +"Zeichenfolge als Eingabe und führt die aus Folgendes, um die " +"Kreditkartennummer zu validieren:" + +#: src/exercises/day-1/luhn.md:7 +msgid "Ignore all spaces. Reject number with less than two digits." +msgstr "" + +#: src/exercises/day-1/luhn.md:9 +msgid "" +"Moving from **right to left**, double every second digit: for the number " +"`1234`, we double `3` and `1`. For the number `98765`, we double `6` and `8`." +msgstr "" + +#: src/exercises/day-1/luhn.md:12 +msgid "" +"After doubling a digit, sum the digits if the result is greater than 9. So " +"doubling `7` becomes `14` which becomes `1 + 4 = 5`." +msgstr "" + +#: src/exercises/day-1/luhn.md:15 +msgid "Sum all the undoubled and doubled digits." +msgstr "" + +#: src/exercises/day-1/luhn.md:17 +msgid "The credit card number is valid if the sum ends with `0`." +msgstr "" + +#: src/exercises/day-1/luhn.md:19 +#, fuzzy +msgid "" +"Copy the code below to and implement the " +"function." +msgstr "" +"Kopiere den folgenden Code nach und " +"implementiere die Funktionen:" + +#: src/exercises/day-1/luhn.md:21 +msgid "" +"Try to solve the problem the \"simple\" way first, using `for` loops and " +"integers. Then, revisit the solution and try to implement it with iterators." +msgstr "" + +#: src/exercises/day-1/luhn.md:25 +msgid "" +"```rust\n" +"// TODO: remove this when you're done with your implementation.\n" +"#![allow(unused_variables, dead_code)]\n" +"\n" +"pub fn luhn(cc_number: &str) -> bool {\n" +" unimplemented!()\n" +"}\n" +"\n" +"#[test]\n" +"fn test_non_digit_cc_number() {\n" +" assert!(!luhn(\"foo\"));\n" +" assert!(!luhn(\"foo 0 0\"));\n" +"}\n" +"\n" +"#[test]\n" +"fn test_empty_cc_number() {\n" +" assert!(!luhn(\"\"));\n" +" assert!(!luhn(\" \"));\n" +" assert!(!luhn(\" \"));\n" +" assert!(!luhn(\" \"));\n" +"}\n" +"\n" +"#[test]\n" +"fn test_single_digit_cc_number() {\n" +" assert!(!luhn(\"0\"));\n" +"}\n" +"\n" +"#[test]\n" +"fn test_two_digit_cc_number() {\n" +" assert!(luhn(\" 0 0 \"));\n" +"}\n" +"\n" +"#[test]\n" +"fn test_valid_cc_number() {\n" +" assert!(luhn(\"4263 9826 4026 9299\"));\n" +" assert!(luhn(\"4539 3195 0343 6467\"));\n" +" assert!(luhn(\"7992 7398 713\"));\n" +"}\n" +"\n" +"#[test]\n" +"fn test_invalid_cc_number() {\n" +" assert!(!luhn(\"4223 9826 4026 9299\"));\n" +" assert!(!luhn(\"4539 3195 0343 6476\"));\n" +" assert!(!luhn(\"8273 1232 7352 0569\"));\n" +"}\n" +"\n" +"#[allow(dead_code)]\n" +"fn main() {}\n" +"```" +msgstr "" + +#: src/welcome-day-2.md:1 +#, fuzzy +msgid "Welcome to Day 2" +msgstr "Willkommen zu Tag 2" + +#: src/welcome-day-2.md:3 +#, fuzzy +msgid "Now that we have seen a fair amount of Rust, we will continue with:" +msgstr "" +"Nachdem wir nun eine ganze Menge Rust gesehen haben, fahren wir fort mit:" + +#: src/welcome-day-2.md:5 +msgid "" +"Memory management: stack vs heap, manual memory management, scope-based " +"memory management, and garbage collection." +msgstr "" +"Speicherverwaltung: Stack vs. Heap, manuelle Speicherverwaltung, " +"bereichsbasierte Speicherverwaltung und Speicherbereinigung (garbage " +"collection)." + +#: src/welcome-day-2.md:8 +msgid "" +"Ownership: move semantics, copying and cloning, borrowing, and lifetimes." +msgstr "" +"Eigentum (ownership): Bewegungssemantik (move semantics), Kopieren und " +"Klonen (copy and cloning), Ausleihen (borrowing) und Lebensdauer (lifetimes)." + +#: src/welcome-day-2.md:10 +#, fuzzy +msgid "Structs and methods." +msgstr "Strings und Iteratoren" + +#: src/welcome-day-2.md:12 +msgid "" +"The Standard Library: `String`, `Option` and `Result`, `Vec`, `HashMap`, " +"`Rc` and `Arc`." +msgstr "" + +#: src/welcome-day-2.md:15 +msgid "Modules: visibility, paths, and filesystem hierarchy." +msgstr "" + +#: src/memory-management.md:3 +msgid "Traditionally, languages have fallen into two broad categories:" +msgstr "Traditionell fallen Sprachen in zwei grobe Kategorien:" + +#: src/memory-management.md:5 +msgid "Full control via manual memory management: C, C++, Pascal, ..." +msgstr "Volle Kontrolle über manuelle Speicherverwaltung: C, C++, Pascal, ..." + +#: src/memory-management.md:6 +msgid "" +"Full safety via automatic memory management at runtime: Java, Python, Go, " +"Haskell, ..." +msgstr "" +"Volle Sicherheit durch automatische Speicherverwaltung zur Laufzeit: Java, " +"Python, Go, Haskell, ..." + +#: src/memory-management.md:8 +msgid "Rust offers a new mix:" +msgstr "Rust bietet eine neue Mischung:" + +#: src/memory-management.md:10 +msgid "" +"Full control _and_ safety via compile time enforcement of correct memory " +"management." +msgstr "" +"Volle Kontrolle _und_ Sicherheit durch Erzwingung des korrekten Speichers " +"zur Kompilierzeit." + +#: src/memory-management.md:13 +msgid "It does this with an explicit ownership concept." +msgstr "" +"Dies geschieht mit einem expliziten Eigentumskonzept (explicit ownership " +"concept)." + +#: src/memory-management.md:15 +msgid "First, let's refresh how memory management works." +msgstr "" +"Lasst uns zunächst die Funktionsweise der Speicherverwaltung auffrischen." + +#: src/memory-management/stack-vs-heap.md:1 +msgid "The Stack vs The Heap" +msgstr "Stapel vs. Haufen" + +#: src/memory-management/stack-vs-heap.md:3 +msgid "Stack: Continuous area of memory for local variables." +msgstr "Stack: Kontinuierlicher Speicherbereich für lokale Variablen." + +#: src/memory-management/stack-vs-heap.md:4 +msgid "Values have fixed sizes known at compile time." +msgstr "Werte haben feste Größen, die zur Kompilierzeit bekannt sind." + +#: src/memory-management/stack-vs-heap.md:5 +msgid "Extremely fast: just move a stack pointer." +msgstr "Extrem schnell: Durch Bewegen eines Stapelzeigers." + +#: src/memory-management/stack-vs-heap.md:6 +msgid "Easy to manage: follows function calls." +msgstr "Einfach zu verwalten: folgt Funktionsaufrufen." + +#: src/memory-management/stack-vs-heap.md:7 +msgid "Great memory locality." +msgstr "Große Speicherlokalität (memory locality)." + +#: src/memory-management/stack-vs-heap.md:9 +msgid "Heap: Storage of values outside of function calls." +msgstr "Heap: Speicherung von Werten außerhalb von Funktionsaufrufen." + +#: src/memory-management/stack-vs-heap.md:10 +msgid "Values have dynamic sizes determined at runtime." +msgstr "Werte haben dynamische Größen, die zur Laufzeit bestimmt werden." + +#: src/memory-management/stack-vs-heap.md:11 +msgid "Slightly slower than the stack: some book-keeping needed." +msgstr "Etwas langsamer als der Stapel: Etwas Buchhaltung ist erforderlich." + +#: src/memory-management/stack-vs-heap.md:12 +msgid "No guarantee of memory locality." +msgstr "Keine Garantie für Speicherlokalität." + +#: src/memory-management/stack.md:1 +#, fuzzy +msgid "Stack and Heap Example" +msgstr "Stapelspeicher vs. Haldenspeicher" + +#: src/memory-management/stack.md:3 +#, fuzzy +msgid "" +"Creating a `String` puts fixed-sized metadata on the stack and dynamically " +"sized data, the actual string, on the heap:" +msgstr "" +"Das Erstellen eines \"Strings\" legt Daten mit fester Größe auf den Stapel " +"und dynamisch in der Größe Daten auf dem Haufen:" + +#: src/memory-management/stack.md:6 +msgid "" +"```rust,editable\n" +"fn main() {\n" +" let s1 = String::from(\"Hello\");\n" +"}\n" +"```" +msgstr "" + +#: src/memory-management/stack.md:28 +msgid "" +"Mention that a `String` is backed by a `Vec`, so it has a capacity and " +"length and can grow if mutable via reallocation on the heap." +msgstr "" + +#: src/memory-management/stack.md:30 +msgid "" +"If students ask about it, you can mention that the underlying memory is heap " +"allocated using the [System Allocator](https://doc.rust-lang.org/std/alloc/" +"struct.System.html) and custom allocators can be implemented using the " +"[Allocator API](https://doc.rust-lang.org/std/alloc/index.html)" +msgstr "" + +#: src/memory-management/stack.md:32 +msgid "" +"We can inspect the memory layout with `unsafe` code. However, you should " +"point out that this is rightfully unsafe!" +msgstr "" + +#: src/memory-management/stack.md:34 +msgid "" +"```rust,editable\n" +"fn main() {\n" +" let mut s1 = String::from(\"Hello\");\n" +" s1.push(' ');\n" +" s1.push_str(\"world\");\n" +" // DON'T DO THIS AT HOME! For educational purposes only.\n" +" // String provides no guarantees about its layout, so this could lead " +"to\n" +" // undefined behavior.\n" +" unsafe {\n" +" let (ptr, capacity, len): (usize, usize, usize) = std::mem::" +"transmute(s1);\n" +" println!(\"ptr = {ptr:#x}, len = {len}, capacity = {capacity}\");\n" +" }\n" +"}\n" +"```" +msgstr "" + +#: src/memory-management/manual.md:3 +#, fuzzy +msgid "You allocate and deallocate heap memory yourself." +msgstr "Heap-Speicher können Sie selbst zuweisen und freigeben." + +#: src/memory-management/manual.md:5 +#, fuzzy +msgid "" +"If not done with care, this can lead to crashes, bugs, security " +"vulnerabilities, and memory leaks." +msgstr "" +"Wenn dies nicht sorgfältig durchgeführt wird, kann dies zu Abstürzen, " +"Fehlern, Sicherheitslücken und Speicherlecks führen." + +#: src/memory-management/manual.md:7 +#, fuzzy +msgid "C Example" +msgstr "\\##C Beispiel" + +#: src/memory-management/manual.md:9 +#, fuzzy +msgid "You must call `free` on every pointer you allocate with `malloc`:" +msgstr "" +"Sie müssen `free` auf jedem Zeiger aufrufen, den Sie mit `malloc` zuweisen:" + +#: src/memory-management/manual.md:11 +msgid "" +"```c\n" +"void foo(size_t n) {\n" +" int* int_array = malloc(n * sizeof(int));\n" +" //\n" +" // ... lots of code\n" +" //\n" +" free(int_array);\n" +"}\n" +"```" +msgstr "" + +#: src/memory-management/manual.md:21 +#, fuzzy +msgid "" +"Memory is leaked if the function returns early between `malloc` and `free`: " +"the pointer is lost and we cannot deallocate the memory. Worse, freeing the " +"pointer twice, or accessing a freed pointer can lead to exploitable security " +"vulnerabilities." +msgstr "" +"Speicherverlust, wenn die Funktion früh zwischen `malloc` und `free` " +"zurückkehrt: the Zeiger geht verloren und wir können den Speicher nicht " +"freigeben." + +#: src/memory-management/scope-based.md:3 +#, fuzzy +msgid "" +"Constructors and destructors let you hook into the lifetime of an object." +msgstr "" +"Mit Konstruktoren und Destruktoren können Sie sich in die Lebensdauer eines " +"Objekts einklinken." + +#: src/memory-management/scope-based.md:5 +#, fuzzy +msgid "" +"By wrapping a pointer in an object, you can free memory when the object is " +"destroyed. The compiler guarantees that this happens, even if an exception " +"is raised." +msgstr "" +"Indem Sie einen Zeiger in ein Objekt einschließen, können Sie Speicher " +"freigeben, wenn das Objekt vorhanden ist zerstört. Der Compiler garantiert, " +"dass dies geschieht, auch wenn es sich um eine Ausnahme handelt erzogen." + +#: src/memory-management/scope-based.md:9 +#, fuzzy +msgid "" +"This is often called _resource acquisition is initialization_ (RAII) and " +"gives you smart pointers." +msgstr "" +"Dies wird oft als _Ressourcenerwerb ist Initialisierung_ (RAII) bezeichnet " +"und gibt ihr klugen zeiger." + +#: src/memory-management/scope-based.md:12 +#, fuzzy +msgid "C++ Example" +msgstr "C++-Beispiel" + +#: src/memory-management/scope-based.md:14 +msgid "" +"```c++\n" +"void say_hello(std::unique_ptr person) {\n" +" std::cout << \"Hello \" << person->name << std::endl;\n" +"}\n" +"```" +msgstr "" + +#: src/memory-management/scope-based.md:20 +#, fuzzy +msgid "" +"The `std::unique_ptr` object is allocated on the stack, and points to memory " +"allocated on the heap." +msgstr "" +"Das `std::unique_ptr`\\-Objekt wird auf dem Stack allokiert und zeigt auf " +"auf dem Heap zugewiesener Speicher." + +#: src/memory-management/scope-based.md:22 +#, fuzzy +msgid "At the end of `say_hello`, the `std::unique_ptr` destructor will run." +msgstr "" +"Am Ende von `say_hello` wird der Destruktor `std::unique_ptr` ausgeführt." + +#: src/memory-management/scope-based.md:23 +#, fuzzy +msgid "The destructor frees the `Person` object it points to." +msgstr "Der Destruktor gibt das `Person`\\-Objekt frei, auf das er zeigt." + +#: src/memory-management/scope-based.md:25 +#, fuzzy +msgid "" +"Special move constructors are used when passing ownership to a function:" +msgstr "" +"Spezielle Move-Konstruktoren werden verwendet, wenn der Besitz an eine " +"Funktion übergeben wird:" + +#: src/memory-management/scope-based.md:27 +msgid "" +"```c++\n" +"std::unique_ptr person = find_person(\"Carla\");\n" +"say_hello(std::move(person));\n" +"```" +msgstr "" + +#: src/memory-management/garbage-collection.md:1 +#, fuzzy +msgid "Automatic Memory Management" +msgstr "Automatische Speicherverwaltung" + +#: src/memory-management/garbage-collection.md:3 +#, fuzzy +msgid "" +"An alternative to manual and scope-based memory management is automatic " +"memory management:" +msgstr "" +"Eine Alternative zur manuellen und bereichsbasierten Speicherverwaltung ist " +"der automatische Speicher Management:" + +#: src/memory-management/garbage-collection.md:6 +#, fuzzy +msgid "The programmer never allocates or deallocates memory explicitly." +msgstr "" +"Der Programmierer weist Speicher nie explizit zu oder gibt ihn nicht mehr " +"frei." + +#: src/memory-management/garbage-collection.md:7 +#, fuzzy +msgid "" +"A garbage collector finds unused memory and deallocates it for the " +"programmer." +msgstr "" +"Ein Garbage Collector findet ungenutzten Speicher und gibt ihn für den " +"Programmierer frei." + +#: src/memory-management/garbage-collection.md:9 +#, fuzzy +msgid "Java Example" +msgstr "Java-Beispiel" + +#: src/memory-management/garbage-collection.md:11 +#, fuzzy +msgid "The `person` object is not deallocated after `sayHello` returns:" +msgstr "" +"Das `person`\\-Objekt wird nicht freigegeben, nachdem `sayHello` " +"zurückgegeben wird:" + +#: src/memory-management/garbage-collection.md:13 +msgid "" +"```java\n" +"void sayHello(Person person) {\n" +" System.out.println(\"Hello \" + person.getName());\n" +"}\n" +"```" +msgstr "" + +#: src/memory-management/rust.md:1 +#, fuzzy +msgid "Memory Management in Rust" +msgstr "Speicherverwaltung in Rust" + +#: src/memory-management/rust.md:3 +#, fuzzy +msgid "Memory management in Rust is a mix:" +msgstr "Die Speicherverwaltung in Rust ist eine Mischung:" + +#: src/memory-management/rust.md:5 +#, fuzzy +msgid "Safe and correct like Java, but without a garbage collector." +msgstr "Sicher und korrekt wie Java, aber ohne Garbage Collector." + +#: src/memory-management/rust.md:6 +#, fuzzy +msgid "Scope-based like C++, but the compiler enforces full adherence." +msgstr "" +"Bereichsbasiert wie C++, aber der Compiler erzwingt die vollständige " +"Einhaltung." + +#: src/memory-management/rust.md:7 +#, fuzzy +msgid "" +"A Rust user can choose the right abstraction for the situation, some even " +"have no cost at runtime like C." +msgstr "" +"Ein Rust-Benutzer kann die richtige Abstraktion für die Situation auswählen, " +"einige haben sogar keine Kosten zur Laufzeit wie C." + +#: src/memory-management/rust.md:9 +#, fuzzy +msgid "Rust achieves this by modeling _ownership_ explicitly." +msgstr "Dies wird erreicht, indem _Eigentum_ explizit modelliert wird." + +#: src/memory-management/rust.md:13 +#, fuzzy +msgid "" +"If asked how at this point, you can mention that in Rust this is usually " +"handled by RAII wrapper types such as [Box](https://doc.rust-lang.org/std/" +"boxed/struct.Box.html), [Vec](https://doc.rust-lang.org/std/vec/struct.Vec." +"html), [Rc](https://doc.rust-lang.org/std/rc/struct.Rc.html), or [Arc]" +"(https://doc.rust-lang.org/std/sync/struct.Arc.html). These encapsulate " +"ownership and memory allocation via various means, and prevent the potential " +"errors in C." +msgstr "" +"Wenn Sie an dieser Stelle fragen, wie das geht, können Sie erwähnen, dass " +"dies in Rust normalerweise von RAII-Wrapper-Typen wie [Box](https://doc.rust-" +"lang.org/std/boxed/struct.Box.html), [Vec](https://doc.rust-lang.org/std/vec/" +"struct.Vec.html), [Rc](https://doc.rust-lang.org/std/rc/struct.Rc.html) oder " +"[Arc](https://doc.rust-lang.org/std/sync/struct.Arc.html) gehandhabt wird. " +"Diese kapseln den Besitz und die Speicherzuweisung auf verschiedene Weise " +"und verhindern die potenziellen Fehler in C." + +#: src/memory-management/rust.md:15 +msgid "" +"You may be asked about destructors here, the [Drop](https://doc.rust-lang." +"org/std/ops/trait.Drop.html) trait is the Rust equivalent." +msgstr "" + +#: src/ownership.md:3 +#, fuzzy +msgid "" +"All variable bindings have a _scope_ where they are valid and it is an error " +"to use a variable outside its scope:" +msgstr "" +"Alle Variablenbindungen haben einen _Geltungsbereich_, wo sie gültig sind " +"und es ein Fehler ist Verwenden Sie eine Variable außerhalb ihres " +"Gültigkeitsbereichs:" + +#: src/ownership.md:6 +msgid "" +"```rust,editable,compile_fail\n" +"struct Point(i32, i32);\n" +"\n" +"fn main() {\n" +" {\n" +" let p = Point(3, 4);\n" +" println!(\"x: {}\", p.0);\n" +" }\n" +" println!(\"y: {}\", p.1);\n" +"}\n" +"```" +msgstr "" + +#: src/ownership.md:18 +#, fuzzy +msgid "" +"At the end of the scope, the variable is _dropped_ and the data is freed." +msgstr "" +"Am Ende des Gültigkeitsbereichs wird die Variable _gelöscht_ und die Daten " +"werden freigegeben." + +#: src/ownership.md:19 +#, fuzzy +msgid "A destructor can run here to free up resources." +msgstr "Hier kann ein Destruktor laufen, um Ressourcen freizugeben." + +#: src/ownership.md:20 +#, fuzzy +msgid "We say that the variable _owns_ the value." +msgstr "Wir sagen, dass die Variable den Wert _besitzt_." + +#: src/ownership/move-semantics.md:3 +#, fuzzy +msgid "An assignment will transfer _ownership_ between variables:" +msgstr "Eine Zuweisung überträgt den Besitz zwischen Variablen:" + +#: src/ownership/move-semantics.md:5 +msgid "" +"```rust,editable\n" +"fn main() {\n" +" let s1: String = String::from(\"Hello!\");\n" +" let s2: String = s1;\n" +" println!(\"s2: {s2}\");\n" +" // println!(\"s1: {s1}\");\n" +"}\n" +"```" +msgstr "" + +#: src/ownership/move-semantics.md:14 +#, fuzzy +msgid "The assignment of `s1` to `s2` transfers ownership." +msgstr "Die Zuweisung von `s1` an `s2` überträgt das Eigentum." + +#: src/ownership/move-semantics.md:15 +#, fuzzy +msgid "When `s1` goes out of scope, nothing happens: it does not own anything." +msgstr "" +"Wenn `s1` den Gültigkeitsbereich verlässt, passiert nichts: Es hat keinen " +"Besitz." + +#: src/ownership/move-semantics.md:16 +#, fuzzy +msgid "When `s2` goes out of scope, the string data is freed." +msgstr "" +"Wenn `s2` den Geltungsbereich verlässt, werden die String-Daten freigegeben." + +#: src/ownership/move-semantics.md:17 +#, fuzzy +msgid "There is always _exactly_ one variable binding which owns a value." +msgstr "Es gibt immer _genau_ eine Variablenbindung, die einen Wert besitzt." + +#: src/ownership/move-semantics.md:21 +#, fuzzy +msgid "" +"Mention that this is the opposite of the defaults in C++, which copies by " +"value unless you use `std::move` (and the move constructor is defined!)." +msgstr "" +"Erwähnen Sie, dass dies das Gegenteil der Standardeinstellungen in C++ ist, " +"die nach Wert kopieren, es sei denn, Sie verwenden `std::move` (und der Move-" +"Konstruktor ist definiert!)." + +#: src/ownership/move-semantics.md:23 +msgid "" +"It is only the ownership that moves. Whether any machine code is generated " +"to manipulate the data itself is a matter of optimization, and such copies " +"are aggressively optimized away." +msgstr "" + +#: src/ownership/move-semantics.md:25 +msgid "" +"Simple values (such as integers) can be marked `Copy` (see later slides)." +msgstr "" + +#: src/ownership/move-semantics.md:27 +msgid "In Rust, clones are explicit (by using `clone`)." +msgstr "" + +#: src/ownership/moved-strings-rust.md:3 +msgid "" +"```rust,editable\n" +"fn main() {\n" +" let s1: String = String::from(\"Rust\");\n" +" let s2: String = s1;\n" +"}\n" +"```" +msgstr "" + +#: src/ownership/moved-strings-rust.md:10 +#, fuzzy +msgid "The heap data from `s1` is reused for `s2`." +msgstr "Die Heap-Daten von „s1“ werden für „s2“ wiederverwendet." + +#: src/ownership/moved-strings-rust.md:11 +#, fuzzy +msgid "When `s1` goes out of scope, nothing happens (it has been moved from)." +msgstr "" +"Wenn `s1` den Gültigkeitsbereich verlässt, passiert nichts (es wurde " +"verschoben)." + +#: src/ownership/moved-strings-rust.md:13 +#, fuzzy +msgid "Before move to `s2`:" +msgstr "Vor dem Wechsel zu `s2`:" + +#: src/ownership/moved-strings-rust.md:30 +#, fuzzy +msgid "After move to `s2`:" +msgstr "Nach Umzug nach `s2`:" + +#: src/ownership/moved-strings-rust.md:32 +msgid "" +"```bob\n" +" Stack Heap\n" +".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - -.\n" +": : : :\n" +": s1 \"(inaccessible)\" : : :\n" +": +-----------+-------+ : : +----+----+----+----+ :\n" +": | ptr | o---+---+--+--+-->| R | u | s | t | :\n" +": | len | 4 | : | : +----+----+----+----+ :\n" +": | capacity | 4 | : | : :\n" +": +-----------+-------+ : | : :\n" +": : | `- - - - - - - - - - - - - -'\n" +": s2 : |\n" +": +-----------+-------+ : |\n" +": | ptr | o---+---+--'\n" +": | len | 4 | :\n" +": | capacity | 4 | :\n" +": +-----------+-------+ :\n" +": :\n" +"`- - - - - - - - - - - - - -'\n" +"```" +msgstr "" + +#: src/ownership/double-free-modern-cpp.md:1 +#, fuzzy +msgid "Defensive Copies in Modern C++" +msgstr "Doppel-Freigabe-Fehler in modernem C++" + +#: src/ownership/double-free-modern-cpp.md:3 +#, fuzzy +msgid "Modern C++ solves this differently:" +msgstr "Modernes C++ löst dies anders:" + +#: src/ownership/double-free-modern-cpp.md:5 +msgid "" +"```c++\n" +"std::string s1 = \"Cpp\";\n" +"std::string s2 = s1; // Duplicate the data in s1.\n" +"```" +msgstr "" + +#: src/ownership/double-free-modern-cpp.md:10 +#, fuzzy +msgid "" +"The heap data from `s1` is duplicated and `s2` gets its own independent copy." +msgstr "" +"Die Heap-Daten von `s1` werden dupliziert und `s2` bekommt seine eigene " +"unabhängige Kopie." + +#: src/ownership/double-free-modern-cpp.md:11 +#, fuzzy +msgid "When `s1` and `s2` go out of scope, they each free their own memory." +msgstr "" +"Wenn `s1` und `s2` den Geltungsbereich verlassen, geben sie jeweils ihren " +"eigenen Speicher frei." + +#: src/ownership/double-free-modern-cpp.md:13 +#, fuzzy +msgid "Before copy-assignment:" +msgstr "Vor Kopierauftrag:" + +#: src/ownership/double-free-modern-cpp.md:30 +#, fuzzy +msgid "After copy-assignment:" +msgstr "Nach der Kopierzuweisung:" + +#: src/ownership/double-free-modern-cpp.md:57 +msgid "" +"C++ has made a slightly different choice than Rust. Because `=` copies data, " +"the string data has to be cloned. Otherwise we would get a double-free when " +"either string goes out of scope." +msgstr "" + +#: src/ownership/double-free-modern-cpp.md:61 +msgid "" +"C++ also has [`std::move`](https://en.cppreference.com/w/cpp/utility/move), " +"which is used to indicate when a value may be moved from. If the example had " +"been `s2 = std::move(s1)`, no heap allocation would take place. After the " +"move, `s1` would be in a valid but unspecified state. Unlike Rust, the " +"programmer is allowed to keep using `s1`." +msgstr "" + +#: src/ownership/double-free-modern-cpp.md:66 +msgid "" +"Unlike Rust, `=` in C++ can run arbitrary code as determined by the type " +"which is being copied or moved." +msgstr "" + +#: src/ownership/moves-function-calls.md:3 +#, fuzzy +msgid "" +"When you pass a value to a function, the value is assigned to the function " +"parameter. This transfers ownership:" +msgstr "" +"Wenn Sie einer Funktion einen Wert übergeben, wird der Wert der Funktion " +"zugewiesen Parameter. Dadurch wird das Eigentum übertragen:" + +#: src/ownership/moves-function-calls.md:6 +msgid "" +"```rust,editable\n" +"fn say_hello(name: String) {\n" +" println!(\"Hello {name}\")\n" +"}\n" +"\n" +"fn main() {\n" +" let name = String::from(\"Alice\");\n" +" say_hello(name);\n" +" // say_hello(name);\n" +"}\n" +"```" +msgstr "" + +#: src/ownership/moves-function-calls.md:20 +#, fuzzy +msgid "" +"With the first call to `say_hello`, `main` gives up ownership of `name`. " +"Afterwards, `name` cannot be used anymore within `main`." +msgstr "" +"Mit dem ersten Aufruf von `say_hello` gibt `main` den Besitz von `name` auf. " +"Danach kann `name` nicht mehr innerhalb von `main` verwendet werden." + +#: src/ownership/moves-function-calls.md:21 +#, fuzzy +msgid "" +"The heap memory allocated for `name` will be freed at the end of the " +"`say_hello` function." +msgstr "" +"Der für `name` zugewiesene Heap-Speicher wird am Ende der `say_hello`\\-" +"Funktion freigegeben." + +#: src/ownership/moves-function-calls.md:22 +#, fuzzy +msgid "" +"`main` can retain ownership if it passes `name` as a reference (`&name`) and " +"if `say_hello` accepts a reference as a parameter." +msgstr "" +"`main` kann den Besitz behalten, wenn es `name` als Referenz (`&name`) " +"übergibt und wenn `say_hello` eine Referenz als Parameter akzeptiert." + +#: src/ownership/moves-function-calls.md:23 +#, fuzzy +msgid "" +"Alternatively, `main` can pass a clone of `name` in the first call (`name." +"clone()`)." +msgstr "" +"Alternativ kann `main` beim ersten Aufruf (`name.clone()`) einen Klon von " +"`name` übergeben." + +#: src/ownership/moves-function-calls.md:24 +#, fuzzy +msgid "" +"Rust makes it harder than C++ to inadvertently create copies by making move " +"semantics the default, and by forcing programmers to make clones explicit." +msgstr "" +"Rust macht es schwieriger als C++, versehentlich Kopien zu erstellen, indem " +"es die Bewegungssemantik zum Standard macht und Programmierer dazu zwingt, " +"Klone explizit zu machen." + +#: src/ownership/copy-clone.md:3 +#, fuzzy +msgid "" +"While move semantics are the default, certain types are copied by default:" +msgstr "" +"Während die Bewegungssemantik der Standard ist, werden bestimmte Typen " +"standardmäßig kopiert:" + +#: src/ownership/copy-clone.md:5 +msgid "" +"```rust,editable\n" +"fn main() {\n" +" let x = 42;\n" +" let y = x;\n" +" println!(\"x: {x}\");\n" +" println!(\"y: {y}\");\n" +"}\n" +"```" +msgstr "" + +#: src/ownership/copy-clone.md:14 +#, fuzzy +msgid "These types implement the `Copy` trait." +msgstr "Diese Typen implementieren das `Copy`\\-Merkmal." + +#: src/ownership/copy-clone.md:16 +#, fuzzy +msgid "You can opt-in your own types to use copy semantics:" +msgstr "" +"Sie können Ihre eigenen Typen für die Verwendung von Kopiersemantik " +"aktivieren:" + +#: src/ownership/copy-clone.md:18 +msgid "" +"```rust,editable\n" +"#[derive(Copy, Clone, Debug)]\n" +"struct Point(i32, i32);\n" +"\n" +"fn main() {\n" +" let p1 = Point(3, 4);\n" +" let p2 = p1;\n" +" println!(\"p1: {p1:?}\");\n" +" println!(\"p2: {p2:?}\");\n" +"}\n" +"```" +msgstr "" + +#: src/ownership/copy-clone.md:30 +#, fuzzy +msgid "After the assignment, both `p1` and `p2` own their own data." +msgstr "" +"Nach der Zuweisung besitzen sowohl `p1` als auch `p2` ihre eigenen Daten." + +#: src/ownership/copy-clone.md:31 +#, fuzzy +msgid "We can also use `p1.clone()` to explicitly copy the data." +msgstr "" +"Wir können auch `p1.clone()` verwenden, um die Daten explizit zu kopieren." + +#: src/ownership/copy-clone.md:35 +#, fuzzy +msgid "Copying and cloning are not the same thing:" +msgstr "Kopieren und Klonen sind nicht dasselbe:" + +#: src/ownership/copy-clone.md:37 +#, fuzzy +msgid "" +"Copying refers to bitwise copies of memory regions and does not work on " +"arbitrary objects." +msgstr "" +"Kopieren bezieht sich auf bitweises Kopieren von Speicherbereichen und " +"funktioniert nicht mit beliebigen Objekten." + +#: src/ownership/copy-clone.md:38 +#, fuzzy +msgid "" +"Copying does not allow for custom logic (unlike copy constructors in C++)." +msgstr "" +"Beim Kopieren ist keine benutzerdefinierte Logik möglich (im Gegensatz zu " +"Kopierkonstruktoren in C++)." + +#: src/ownership/copy-clone.md:39 +#, fuzzy +msgid "" +"Cloning is a more general operation and also allows for custom behavior by " +"implementing the `Clone` trait." +msgstr "" +"Klonen ist eine allgemeinere Operation und ermöglicht auch " +"benutzerdefiniertes Verhalten durch Implementieren der Eigenschaft " +"\"Klonen\"." + +#: src/ownership/copy-clone.md:40 +#, fuzzy +msgid "Copying does not work on types that implement the `Drop` trait." +msgstr "" +"Das Kopieren funktioniert nicht bei Typen, die das `Drop`\\-Merkmal " +"implementieren." + +#: src/ownership/copy-clone.md:42 src/ownership/lifetimes-function-calls.md:29 +#, fuzzy +msgid "In the above example, try the following:" +msgstr "Versuchen Sie im obigen Beispiel Folgendes:" + +#: src/ownership/copy-clone.md:44 +#, fuzzy +msgid "" +"Add a `String` field to `struct Point`. It will not compile because `String` " +"is not a `Copy` type." +msgstr "" +"Fügen Sie ein `String`\\-Feld zu `struct Point` hinzu. Es wird nicht " +"kompiliert, da `String` kein `Copy`\\-Typ ist." + +#: src/ownership/copy-clone.md:45 +#, fuzzy +msgid "" +"Remove `Copy` from the `derive` attribute. The compiler error is now in the " +"`println!` for `p1`." +msgstr "" +"Entfernen Sie „Copy“ aus dem „derive“-Attribut. Der Compiler-Fehler steht " +"jetzt im `println!` für `p1`." + +#: src/ownership/copy-clone.md:46 +#, fuzzy +msgid "Show that it works if you clone `p1` instead." +msgstr "Zeigen Sie, dass es funktioniert, wenn Sie stattdessen `p1` klonen." + +#: src/ownership/copy-clone.md:48 +#, fuzzy +msgid "" +"If students ask about `derive`, it is sufficient to say that this is a way " +"to generate code in Rust at compile time. In this case the default " +"implementations of `Copy` and `Clone` traits are generated." +msgstr "" +"Wenn Schüler nach „derive“ fragen, reicht es zu sagen, dass dies eine " +"Möglichkeit ist, Code in Rust zu generieren zur Kompilierzeit. In diesem " +"Fall werden die Standardimplementierungen der Merkmale „Kopieren“ und " +"„Klonen“ generiert." + +#: src/ownership/borrowing.md:3 +#, fuzzy +msgid "" +"Instead of transferring ownership when calling a function, you can let a " +"function _borrow_ the value:" +msgstr "" +"Anstatt den Besitz beim Aufruf einer Funktion zu übertragen, können Sie a " +"function _borrow_ den Wert:" + +#: src/ownership/borrowing.md:6 +msgid "" +"```rust,editable\n" +"#[derive(Debug)]\n" +"struct Point(i32, i32);\n" +"\n" +"fn add(p1: &Point, p2: &Point) -> Point {\n" +" Point(p1.0 + p2.0, p1.1 + p2.1)\n" +"}\n" +"\n" +"fn main() {\n" +" let p1 = Point(3, 4);\n" +" let p2 = Point(10, 20);\n" +" let p3 = add(&p1, &p2);\n" +" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n" +"}\n" +"```" +msgstr "" + +#: src/ownership/borrowing.md:22 +#, fuzzy +msgid "The `add` function _borrows_ two points and returns a new point." +msgstr "" +"Die `add`\\-Funktion _leiht_ zwei Punkte und gibt einen neuen Punkt zurück." + +#: src/ownership/borrowing.md:23 +#, fuzzy +msgid "The caller retains ownership of the inputs." +msgstr "Der Aufrufer behält das Eigentum an den Eingaben." + +#: src/ownership/borrowing.md:27 +#, fuzzy +msgid "Notes on stack returns:" +msgstr "Hinweise zur Stapelrückgabe:" + +#: src/ownership/borrowing.md:28 +msgid "" +"Demonstrate that the return from `add` is cheap because the compiler can " +"eliminate the copy operation. Change the above code to print stack addresses " +"and run it on the [Playground](https://play.rust-lang.org/) or look at the " +"assembly in [Godbolt](https://rust.godbolt.org/). In the \"DEBUG\" " +"optimization level, the addresses should change, while they stay the same " +"when changing to the \"RELEASE\" setting:" +msgstr "" + +#: src/ownership/borrowing.md:30 +#, fuzzy +msgid "" +"```rust,editable\n" +"#[derive(Debug)]\n" +"struct Point(i32, i32);\n" +"\n" +"fn add(p1: &Point, p2: &Point) -> Point {\n" +" let p = Point(p1.0 + p2.0, p1.1 + p2.1);\n" +" println!(\"&p.0: {:p}\", &p.0);\n" +" p\n" +"}\n" +"\n" +"pub fn main() {\n" +" let p1 = Point(3, 4);\n" +" let p2 = Point(10, 20);\n" +" let p3 = add(&p1, &p2);\n" +" println!(\"&p3.0: {:p}\", &p3.0);\n" +" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n" +"}\n" +"```" +msgstr "Eine andere Möglichkeit, es zu erklären:" + +#: src/ownership/borrowing.md:48 +msgid "The Rust compiler can do return value optimization (RVO)." +msgstr "" + +#: src/ownership/borrowing.md:49 +msgid "" +"In C++, copy elision has to be defined in the language specification because " +"constructors can have side effects. In Rust, this is not an issue at all. If " +"RVO did not happen, Rust will always perform a simple and efficient `memcpy` " +"copy." +msgstr "" + +#: src/ownership/shared-unique-borrows.md:3 +#, fuzzy +msgid "Rust puts constraints on the ways you can borrow values:" +msgstr "Rust schränkt die Art und Weise ein, wie Sie Werte ausleihen können:" + +#: src/ownership/shared-unique-borrows.md:5 +#, fuzzy +msgid "You can have one or more `&T` values at any given time, _or_" +msgstr "Sie können jederzeit einen oder mehrere `&T`\\-Werte haben, _oder_" + +#: src/ownership/shared-unique-borrows.md:6 +#, fuzzy +msgid "You can have exactly one `&mut T` value." +msgstr "Sie können genau einen `&mut T`\\-Wert haben." + +#: src/ownership/shared-unique-borrows.md:8 +msgid "" +"```rust,editable,compile_fail\n" +"fn main() {\n" +" let mut a: i32 = 10;\n" +" let b: &i32 = &a;\n" +"\n" +" {\n" +" let c: &mut i32 = &mut a;\n" +" *c = 20;\n" +" }\n" +"\n" +" println!(\"a: {a}\");\n" +" println!(\"b: {b}\");\n" +"}\n" +"```" +msgstr "" + +#: src/ownership/shared-unique-borrows.md:25 +#, fuzzy +msgid "" +"The above code does not compile because `a` is borrowed as mutable (through " +"`c`) and as immutable (through `b`) at the same time." +msgstr "" +"Der obige Code lässt sich nicht kompilieren, da `a` gleichzeitig als " +"veränderlich (durch `c`) und als unveränderlich (durch `b`) ausgeliehen wird." + +#: src/ownership/shared-unique-borrows.md:26 +#, fuzzy +msgid "" +"Move the `println!` statement for `b` before the scope that introduces `c` " +"to make the code compile." +msgstr "" +"Verschieben Sie die `println!`\\-Anweisung für `b` vor den " +"Gültigkeitsbereich, der `c` einführt, um den Code zu kompilieren." + +#: src/ownership/shared-unique-borrows.md:27 +#, fuzzy +msgid "" +"After that change, the compiler realizes that `b` is only ever used before " +"the new mutable borrow of `a` through `c`. This is a feature of the borrow " +"checker called \"non-lexical lifetimes\"." +msgstr "" +"Nach dieser Änderung erkennt der Compiler, dass `b` immer nur vor dem neuen " +"änderbaren Borgen von `a` bis `c` verwendet wird. Dies ist eine Funktion des " +"Borrow-Checkers, die als \"nicht-lexikalische Lebensdauern\" bezeichnet wird." + +#: src/ownership/lifetimes.md:3 +#, fuzzy +msgid "A borrowed value has a _lifetime_:" +msgstr "Ein geliehener Wert hat eine _Lebensdauer_:" + +#: src/ownership/lifetimes.md:5 +msgid "The lifetime can be implicit: `add(p1: &Point, p2: &Point) -> Point`." +msgstr "" + +#: src/ownership/lifetimes.md:6 +msgid "Lifetimes can also be explicit: `&'a Point`, `&'document str`." +msgstr "" + +#: src/ownership/lifetimes.md:7 src/ownership/lifetimes-function-calls.md:23 +#, fuzzy +msgid "" +"Read `&'a Point` as \"a borrowed `Point` which is valid for at least the " +"lifetime `a`\"." +msgstr "" +"Lesen Sie `&'einen Punkt` als \"einen geliehenen `Punkt`, der mindestens für " +"den gilt Lebenszeit `a`\"." + +#: src/ownership/lifetimes.md:9 +msgid "" +"Lifetimes are always inferred by the compiler: you cannot assign a lifetime " +"yourself." +msgstr "" + +#: src/ownership/lifetimes.md:11 +msgid "" +"Lifetime annotations create constraints; the compiler verifies that there is " +"a valid solution." +msgstr "" + +#: src/ownership/lifetimes.md:13 +msgid "" +"Lifetimes for function arguments and return values must be fully specified, " +"but Rust allows lifetimes to be elided in most cases with [a few simple " +"rules](https://doc.rust-lang.org/nomicon/lifetime-elision.html)." +msgstr "" + +#: src/ownership/lifetimes-function-calls.md:3 +#, fuzzy +msgid "" +"In addition to borrowing its arguments, a function can return a borrowed " +"value:" +msgstr "" +"Zusätzlich zum Ausleihen ihrer Argumente kann eine Funktion einen geliehenen " +"Wert zurückgeben:" + +#: src/ownership/lifetimes-function-calls.md:5 +msgid "" +"```rust,editable\n" +"#[derive(Debug)]\n" +"struct Point(i32, i32);\n" +"\n" +"fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n" +" if p1.0 < p2.0 { p1 } else { p2 }\n" +"}\n" +"\n" +"fn main() {\n" +" let p1: Point = Point(10, 10);\n" +" let p2: Point = Point(20, 20);\n" +" let p3: &Point = left_most(&p1, &p2);\n" +" println!(\"left-most point: {:?}\", p3);\n" +"}\n" +"```" +msgstr "" + +#: src/ownership/lifetimes-function-calls.md:21 +#, fuzzy +msgid "`'a` is a generic parameter, it is inferred by the compiler." +msgstr "„a“ ist ein generischer Parameter, er wird vom Compiler abgeleitet." + +#: src/ownership/lifetimes-function-calls.md:22 +#, fuzzy +msgid "Lifetimes start with `'` and `'a` is a typical default name." +msgstr "Lebensdauern beginnen mit `'` und `'a` ist ein typischer Standardname." + +#: src/ownership/lifetimes-function-calls.md:25 +#, fuzzy +msgid "" +"The _at least_ part is important when parameters are in different scopes." +msgstr "" +"Der Teil _at least_ ist wichtig, wenn sich Parameter in unterschiedlichen " +"Geltungsbereichen befinden." + +#: src/ownership/lifetimes-function-calls.md:31 +#, fuzzy +msgid "" +"Move the declaration of `p2` and `p3` into a new scope (`{ ... }`), " +"resulting in the following code:" +msgstr "" +"Setzen Sie den Arbeitsbereich zurück und ändern Sie die Funktionssignatur zu " +"`fn left_most<'a, 'b>(p1: &'a Point, p2: &'a Point) -> &'b Point`. Dies wird " +"nicht kompiliert, da die Beziehung zwischen den Lebensdauern „a“ und „b“ " +"unklar ist." + +#: src/ownership/lifetimes-function-calls.md:32 +#, fuzzy +msgid "" +"```rust,ignore\n" +"#[derive(Debug)]\n" +"struct Point(i32, i32);\n" +"\n" +"fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n" +" if p1.0 < p2.0 { p1 } else { p2 }\n" +"}\n" +"\n" +"fn main() {\n" +" let p1: Point = Point(10, 10);\n" +" let p3: &Point;\n" +" {\n" +" let p2: Point = Point(20, 20);\n" +" p3 = left_most(&p1, &p2);\n" +" }\n" +" println!(\"left-most point: {:?}\", p3);\n" +"}\n" +"```" +msgstr "Eine andere Möglichkeit, es zu erklären:" + +#: src/ownership/lifetimes-function-calls.md:50 +#, fuzzy +msgid "Note how this does not compile since `p3` outlives `p2`." +msgstr "" +"Zwei Referenzen auf zwei Werte werden von einer Funktion ausgeliehen und die " +"Funktion kehrt zurück eine andere Referenz." + +#: src/ownership/lifetimes-function-calls.md:52 +#, fuzzy +msgid "" +"Reset the workspace and change the function signature to `fn left_most<'a, " +"'b>(p1: &'a Point, p2: &'a Point) -> &'b Point`. This will not compile " +"because the relationship between the lifetimes `'a` and `'b` is unclear." +msgstr "" +"Es muss von einem dieser beiden Eingänge stammen (oder von einer globalen " +"Variablen)." + +#: src/ownership/lifetimes-function-calls.md:53 +#, fuzzy +msgid "Another way to explain it:" +msgstr "" +"Welches ist es? Der Compiler muss es wissen, damit die zurückgegebene " +"Referenz auf der Aufrufseite nicht verwendet wird länger als eine Variable, " +"von der die Referenz stammt." + +#: src/ownership/lifetimes-function-calls.md:54 +msgid "" +"Two references to two values are borrowed by a function and the function " +"returns another reference." +msgstr "" + +#: src/ownership/lifetimes-function-calls.md:56 +msgid "" +"It must have come from one of those two inputs (or from a global variable)." +msgstr "" + +#: src/ownership/lifetimes-function-calls.md:57 +msgid "" +"Which one is it? The compiler needs to know, so at the call site the " +"returned reference is not used for longer than a variable from where the " +"reference came from." +msgstr "" + +#: src/ownership/lifetimes-data-structures.md:3 +#, fuzzy +msgid "" +"If a data type stores borrowed data, it must be annotated with a lifetime:" +msgstr "" +"Wenn ein Datentyp geliehene Daten speichert, muss er mit einer Lebensdauer " +"versehen werden:" + +#: src/ownership/lifetimes-data-structures.md:5 +msgid "" +"```rust,editable\n" +"#[derive(Debug)]\n" +"struct Highlight<'doc>(&'doc str);\n" +"\n" +"fn erase(text: String) {\n" +" println!(\"Bye {text}!\");\n" +"}\n" +"\n" +"fn main() {\n" +" let text = String::from(\"The quick brown fox jumps over the lazy dog." +"\");\n" +" let fox = Highlight(&text[4..19]);\n" +" let dog = Highlight(&text[35..43]);\n" +" // erase(text);\n" +" println!(\"{fox:?}\");\n" +" println!(\"{dog:?}\");\n" +"}\n" +"```" +msgstr "" + +#: src/ownership/lifetimes-data-structures.md:25 +#, fuzzy +msgid "" +"In the above example, the annotation on `Highlight` enforces that the data " +"underlying the contained `&str` lives at least as long as any instance of " +"`Highlight` that uses that data." +msgstr "" +"Im obigen Beispiel erzwingt die Anmerkung zu `Highlight`, dass die Daten, " +"die dem enthaltenen `&str` zugrunde liegen, mindestens so lange leben wie " +"jede Instanz von `Highlight`, die diese Daten verwendet." + +#: src/ownership/lifetimes-data-structures.md:26 +#, fuzzy +msgid "" +"If `text` is consumed before the end of the lifetime of `fox` (or `dog`), " +"the borrow checker throws an error." +msgstr "" +"Wenn `text` vor dem Ende der Lebensdauer von `fox` (oder `dog`) verbraucht " +"wird, wirft der Borrow-Checker einen Fehler." + +#: src/ownership/lifetimes-data-structures.md:27 +#, fuzzy +msgid "" +"Types with borrowed data force users to hold on to the original data. This " +"can be useful for creating lightweight views, but it generally makes them " +"somewhat harder to use." +msgstr "" +"Typen mit geliehenen Daten zwingen Benutzer, an den Originaldaten " +"festzuhalten. Dies kann nützlich sein, um einfache Ansichten zu erstellen, " +"macht sie jedoch im Allgemeinen etwas schwieriger zu verwenden." + +#: src/ownership/lifetimes-data-structures.md:28 +#, fuzzy +msgid "When possible, make data structures own their data directly." +msgstr "" +"Wenn möglich, machen Sie Datenstrukturen direkt Eigentümer ihrer Daten." + +#: src/ownership/lifetimes-data-structures.md:29 +#, fuzzy +msgid "" +"Some structs with multiple references inside can have more than one lifetime " +"annotation. This can be necessary if there is a need to describe lifetime " +"relationships between the references themselves, in addition to the lifetime " +"of the struct itself. Those are very advanced use cases." +msgstr "" +"Einige Strukturen mit mehreren darin enthaltenen Referenzen können mehr als " +"eine lebenslange Anmerkung haben. Dies kann erforderlich sein, wenn " +"zusätzlich zur Lebensdauer der Struktur selbst Lebensdauerbeziehungen " +"zwischen den Referenzen selbst beschrieben werden müssen. Das sind sehr " +"fortgeschrittene Anwendungsfälle." + +#: src/structs.md:3 +#, fuzzy +msgid "Like C and C++, Rust has support for custom structs:" +msgstr "Wie C und C++ unterstützt Rust benutzerdefinierte Strukturen:" + +#: src/structs.md:5 +msgid "" +"```rust,editable\n" +"struct Person {\n" +" name: String,\n" +" age: u8,\n" +"}\n" +"\n" +"fn main() {\n" +" let mut peter = Person {\n" +" name: String::from(\"Peter\"),\n" +" age: 27,\n" +" };\n" +" println!(\"{} is {} years old\", peter.name, peter.age);\n" +" \n" +" peter.age = 28;\n" +" println!(\"{} is {} years old\", peter.name, peter.age);\n" +" \n" +" let jackie = Person {\n" +" name: String::from(\"Jackie\"),\n" +" ..peter\n" +" };\n" +" println!(\"{} is {} years old\", jackie.name, jackie.age);\n" +"}\n" +"```" +msgstr "" + +#: src/structs.md:33 +msgid "Structs work like in C or C++." +msgstr "" + +#: src/structs.md:34 +msgid "Like in C++, and unlike in C, no typedef is needed to define a type." +msgstr "" + +#: src/structs.md:35 +msgid "Unlike in C++, there is no inheritance between structs." +msgstr "" + +#: src/structs.md:36 +msgid "" +"Methods are defined in an `impl` block, which we will see in following " +"slides." +msgstr "" + +#: src/structs.md:37 +msgid "" +"This may be a good time to let people know there are different types of " +"structs. " +msgstr "" + +#: src/structs.md:38 +msgid "" +"Zero-sized structs `e.g., struct Foo;` might be used when implementing a " +"trait on some type but don’t have any data that you want to store in the " +"value itself. " +msgstr "" + +#: src/structs.md:39 +msgid "" +"The next slide will introduce Tuple structs, used when the field names are " +"not important." +msgstr "" + +#: src/structs.md:40 +msgid "" +"The syntax `..peter` allows us to copy the majority of the fields from the " +"old struct without having to explicitly type it all out. It must always be " +"the last element." +msgstr "" + +#: src/structs/tuple-structs.md:3 +#, fuzzy +msgid "If the field names are unimportant, you can use a tuple struct:" +msgstr "" +"Wenn die Feldnamen unwichtig sind, können Sie eine Tupelstruktur verwenden:" + +#: src/structs/tuple-structs.md:5 +msgid "" +"```rust,editable\n" +"struct Point(i32, i32);\n" +"\n" +"fn main() {\n" +" let p = Point(17, 23);\n" +" println!(\"({}, {})\", p.0, p.1);\n" +"}\n" +"```" +msgstr "" + +#: src/structs/tuple-structs.md:14 +#, fuzzy +msgid "This is often used for single-field wrappers (called newtypes):" +msgstr "Dies wird häufig für Einzelfeld-Wrapper (genannt Newtypes) verwendet:" + +#: src/structs/tuple-structs.md:16 +msgid "" +"```rust,editable,compile_fail\n" +"struct PoundsOfForce(f64);\n" +"struct Newtons(f64);\n" +"\n" +"fn compute_thruster_force() -> PoundsOfForce {\n" +" todo!(\"Ask a rocket scientist at NASA\")\n" +"}\n" +"\n" +"fn set_thruster_force(force: Newtons) {\n" +" // ...\n" +"}\n" +"\n" +"fn main() {\n" +" let force = compute_thruster_force();\n" +" set_thruster_force(force);\n" +"}\n" +"\n" +"```" +msgstr "" + +#: src/structs/tuple-structs.md:37 +msgid "" +"Newtypes are a great way to encode additional information about the value in " +"a primitive type, for example:" +msgstr "" + +#: src/structs/tuple-structs.md:38 +msgid "The number is measured in some units: `Newtons` in the example above." +msgstr "" + +#: src/structs/tuple-structs.md:39 +msgid "" +"The value passed some validation when it was created, so you no longer have " +"to validate it again at every use: 'PhoneNumber(String)`or`OddNumber(u32)\\`." +msgstr "" + +#: src/structs/tuple-structs.md:40 +msgid "" +"Demonstrate how to add a `f64` value to a `Newtons` type by accessing the " +"single field in the newtype." +msgstr "" + +#: src/structs/tuple-structs.md:41 +msgid "" +"Rust generally doesn’t like inexplicit things, like automatic unwrapping or " +"for instance using booleans as integers." +msgstr "" + +#: src/structs/tuple-structs.md:42 +msgid "Operator overloading is discussed on Day 3 (generics)." +msgstr "" + +#: src/structs/tuple-structs.md:43 +msgid "" +"The example is a subtle reference to the [Mars Climate Orbiter](https://en." +"wikipedia.org/wiki/Mars_Climate_Orbiter) failure." +msgstr "" + +#: src/structs/field-shorthand.md:3 +#, fuzzy +msgid "" +"If you already have variables with the right names, then you can create the " +"struct using a shorthand:" +msgstr "" +"Wenn Sie bereits Variablen mit den richtigen Namen haben, können Sie die " +"erstellen struct mit einer Abkürzung:" + +#: src/structs/field-shorthand.md:6 +msgid "" +"```rust,editable\n" +"#[derive(Debug)]\n" +"struct Person {\n" +" name: String,\n" +" age: u8,\n" +"}\n" +"\n" +"impl Person {\n" +" fn new(name: String, age: u8) -> Person {\n" +" Person { name, age }\n" +" }\n" +"}\n" +"\n" +"fn main() {\n" +" let peter = Person::new(String::from(\"Peter\"), 27);\n" +" println!(\"{peter:?}\");\n" +"}\n" +"```" +msgstr "" + +#: src/structs/field-shorthand.md:27 +msgid "" +"The `new` function could be written using `Self` as a type, as it is " +"interchangeable with the struct type name" +msgstr "" + +#: src/structs/field-shorthand.md:41 +msgid "" +"Implement the `Default` trait for the struct. Define some fields and use the " +"default values for the other fields." +msgstr "" + +#: src/structs/field-shorthand.md:43 +msgid "" +"```rust,editable\n" +"#[derive(Debug)]\n" +"struct Person {\n" +" name: String,\n" +" age: u8,\n" +"}\n" +"impl Default for Person {\n" +" fn default() -> Person {\n" +" Person {\n" +" name: \"Bot\".to_string(),\n" +" age: 0,\n" +" }\n" +" }\n" +"}\n" +"fn create_default() {\n" +" let tmp = Person {\n" +" ..Person::default()\n" +" };\n" +" let tmp = Person {\n" +" name: \"Sam\".to_string(),\n" +" ..Person::default()\n" +" };\n" +"}\n" +"```" +msgstr "" + +#: src/structs/field-shorthand.md:68 +msgid "Methods are defined in the `impl` block." +msgstr "" + +#: src/structs/field-shorthand.md:69 +msgid "" +"Use struct update syntax to define a new structure using `peter`. Note that " +"the variable `peter` will no longer be accessible afterwards." +msgstr "" + +#: src/structs/field-shorthand.md:70 +msgid "" +"Use `{:#?}` when printing structs to request the `Debug` representation." +msgstr "" + +#: src/methods.md:3 +#, fuzzy +msgid "" +"Rust allows you to associate functions with your new types. You do this with " +"an `impl` block:" +msgstr "" +"Mit Rust können Sie Ihren neuen Typen Funktionen zuordnen. Das machst du mit " +"einem `impl`\\-Block:" + +#: src/methods.md:6 +msgid "" +"```rust,editable\n" +"#[derive(Debug)]\n" +"struct Person {\n" +" name: String,\n" +" age: u8,\n" +"}\n" +"\n" +"impl Person {\n" +" fn say_hello(&self) {\n" +" println!(\"Hello, my name is {}\", self.name);\n" +" }\n" +"}\n" +"\n" +"fn main() {\n" +" let peter = Person {\n" +" name: String::from(\"Peter\"),\n" +" age: 27,\n" +" };\n" +" peter.say_hello();\n" +"}\n" +"```" +msgstr "" + +#: src/methods.md:31 +#, fuzzy +msgid "It can be helpful to introduce methods by comparing them to functions." +msgstr "" +"Es kann hilfreich sein, Methoden einzuführen, indem man sie mit Funktionen " +"vergleicht." + +#: src/methods.md:32 +#, fuzzy +msgid "" +"Methods are called on an instance of a type (such as a struct or enum), the " +"first parameter represents the instance as `self`." +msgstr "" +"Methoden werden für eine Instanz eines Typs aufgerufen (z. B. eine Struktur " +"oder Aufzählung), der erste Parameter repräsentiert die Instanz als „self“." + +#: src/methods.md:33 +#, fuzzy +msgid "" +"Developers may choose to use methods to take advantage of method receiver " +"syntax and to help keep them more organized. By using methods we can keep " +"all the implementation code in one predictable place." +msgstr "" +"Entwickler können sich dafür entscheiden, Methoden zu verwenden, um die " +"Methodenempfängersyntax zu nutzen und sie besser organisiert zu halten. " +"Durch die Verwendung von Methoden können wir den gesamten " +"Implementierungscode an einem vorhersehbaren Ort aufbewahren." + +#: src/methods.md:34 +#, fuzzy +msgid "Point out the use of the keyword `self`, a method receiver." +msgstr "" +"Weisen Sie auf die Verwendung des Schlüsselworts „self“ hin, einem " +"Methodenempfänger." + +#: src/methods.md:35 +#, fuzzy +msgid "" +"Show that it is an abbreviated term for `self: Self` and perhaps show how " +"the struct name could also be used." +msgstr "" +"Zeigen Sie, dass es sich um eine Abkürzung für `self:&Self` handelt und " +"zeigen Sie vielleicht, wie der Strukturname auch verwendet werden könnte." + +#: src/methods.md:36 +#, fuzzy +msgid "" +"Explain that `Self` is a type alias for the type the `impl` block is in and " +"can be used elsewhere in the block." +msgstr "" +"Erklären Sie, dass Self ein Typ-Alias für den Typ ist, in dem sich der " +"„impl“-Block befindet, und an anderer Stelle im Block verwendet werden kann." + +#: src/methods.md:37 +#, fuzzy +msgid "" +"Note how `self` is used like other structs and dot notation can be used to " +"refer to individual fields." +msgstr "" +"Beachten Sie, dass self wie andere Strukturen verwendet wird und die " +"Punktnotation verwendet werden kann, um auf einzelne Felder zu verweisen." + +#: src/methods.md:38 +#, fuzzy +msgid "" +"This might be a good time to demonstrate how the `&self` differs from `self` " +"by modifying the code and trying to run say_hello twice." +msgstr "" +"Dies könnte ein guter Zeitpunkt sein, um zu demonstrieren, wie sich `&self` " +"von `self` unterscheidet, indem Sie den Code ändern und versuchen, say_hello " +"zweimal auszuführen." + +#: src/methods.md:39 +#, fuzzy +msgid "We describe the distinction between method receivers next." +msgstr "" +"Als nächstes beschreiben wir die Unterscheidung zwischen Methodenempfängern." + +#: src/methods/receiver.md:3 +#, fuzzy +msgid "" +"The `&self` above indicates that the method borrows the object immutably. " +"There are other possible receivers for a method:" +msgstr "" +"Das obige `&self` gibt an, dass die Methode das Objekt unveränderlich " +"ausleiht. Dort sind weitere mögliche Empfänger für eine Methode:" + +#: src/methods/receiver.md:6 +#, fuzzy +msgid "" +"`&self`: borrows the object from the caller using a shared and immutable " +"reference. The object can be used again afterwards." +msgstr "" +"`&self`: leiht sich das Objekt vom Aufrufer unter Verwendung eines Shared " +"und Immutable Referenz. Das Objekt kann danach wieder verwendet werden." + +#: src/methods/receiver.md:8 +#, fuzzy +msgid "" +"`&mut self`: borrows the object from the caller using a unique and mutable " +"reference. The object can be used again afterwards." +msgstr "" +"`&mut self`: leiht sich das Objekt vom Aufrufer unter Verwendung eines " +"Unique und Mutable Referenz. Das Objekt kann danach wieder verwendet werden." + +#: src/methods/receiver.md:10 +#, fuzzy +msgid "" +"`self`: takes ownership of the object and moves it away from the caller. The " +"method becomes the owner of the object. The object will be dropped " +"(deallocated) when the method returns, unless its ownership is explicitly " +"transmitted. Complete ownership does not automatically mean mutability." +msgstr "" +"`self`: übernimmt den Besitz des Objekts und verschiebt es vom Aufrufer weg. " +"Der Die Methode wird Eigentümer des Objekts. Das Objekt wird gelöscht " +"(deallocated) wenn die Methode zurückkehrt, es sei denn, ihr Besitz ist " +"explizit übermittelt." + +#: src/methods/receiver.md:14 +#, fuzzy +msgid "`mut self`: same as above, but the method can mutate the object. " +msgstr "" +"`mut self`: wie oben, aber während die Methode das Objekt besitzt, kann sie " +"es mutiere es auch. Vollständiges Eigentum bedeutet nicht automatisch " +"Wandelbarkeit." + +#: src/methods/receiver.md:15 +#, fuzzy +msgid "" +"No receiver: this becomes a static method on the struct. Typically used to " +"create constructors which are called `new` by convention." +msgstr "" +"Kein Empfänger: Dies wird zu einer statischen Methode für die Struktur. " +"Typischerweise gewohnt Erstellen Sie Konstruktoren, die per Konvention " +"\"neu\" genannt werden." + +#: src/methods/receiver.md:18 +#, fuzzy +msgid "" +"Beyond variants on `self`, there are also [special wrapper types](https://" +"doc.rust-lang.org/reference/special-types-and-traits.html) allowed to be " +"receiver types, such as `Box`." +msgstr "" +"Neben Varianten von „self“ gibt es auch [spezielle Wrapper-Typen](https://" +"doc.rust-lang.org/reference/special-types-and-traits.html) dürfen " +"Empfängertypen sein, wie z. B. `Box`." + +#: src/methods/receiver.md:24 +#, fuzzy +msgid "" +"Consider emphasizing \"shared and immutable\" and \"unique and mutable\". " +"These constraints always come together in Rust due to borrow checker rules, " +"and `self` is no exception. It isn't possible to reference a struct from " +"multiple locations and call a mutating (`&mut self`) method on it." +msgstr "" +"Erwägen Sie, die Betonung auf „gemeinsam und unveränderlich“ und " +"„einzigartig und veränderlich“ zu legen. Diese Einschränkungen kommen immer " +"zusammen in Rust aufgrund der Borrow-Checker-Regeln, und `self` ist keine " +"Ausnahme. Es wird nicht möglich sein Verweisen Sie auf eine Struktur von " +"mehreren Stellen und rufen Sie eine Mutationsmethode (`&mut self`) darauf " +"auf." + +#: src/methods/example.md:3 +msgid "" +"```rust,editable\n" +"#[derive(Debug)]\n" +"struct Race {\n" +" name: String,\n" +" laps: Vec,\n" +"}\n" +"\n" +"impl Race {\n" +" fn new(name: &str) -> Race { // No receiver, a static method\n" +" Race { name: String::from(name), laps: Vec::new() }\n" +" }\n" +"\n" +" fn add_lap(&mut self, lap: i32) { // Exclusive borrowed read-write " +"access to self\n" +" self.laps.push(lap);\n" +" }\n" +"\n" +" fn print_laps(&self) { // Shared and read-only borrowed access to self\n" +" println!(\"Recorded {} laps for {}:\", self.laps.len(), self.name);\n" +" for (idx, lap) in self.laps.iter().enumerate() {\n" +" println!(\"Lap {idx}: {lap} sec\");\n" +" }\n" +" }\n" +"\n" +" fn finish(self) { // Exclusive ownership of self\n" +" let total = self.laps.iter().sum::();\n" +" println!(\"Race {} is finished, total lap time: {}\", self.name, " +"total);\n" +" }\n" +"}\n" +"\n" +"fn main() {\n" +" let mut race = Race::new(\"Monaco Grand Prix\");\n" +" race.add_lap(70);\n" +" race.add_lap(68);\n" +" race.print_laps();\n" +" race.add_lap(71);\n" +" race.print_laps();\n" +" race.finish();\n" +" // race.add_lap(42);\n" +"}\n" +"```" +msgstr "" + +#: src/methods/example.md:47 +#, fuzzy +msgid "All four methods here use a different method receiver." +msgstr "Alle vier Methoden hier verwenden einen anderen Methodenempfänger." + +#: src/methods/example.md:48 +#, fuzzy +msgid "" +"You can point out how that changes what the function can do with the " +"variable values and if/how it can be used again in `main`." +msgstr "" +"Sie können darauf hinweisen, wie sich das ändert, was die Funktion mit den " +"Variablenwerten machen kann und ob/wie sie wieder in `main` verwendet werden " +"kann." + +#: src/methods/example.md:49 +#, fuzzy +msgid "" +"You can showcase the error that appears when trying to call `finish` twice." +msgstr "" +"Sie können den Fehler zeigen, der auftritt, wenn Sie versuchen, zweimal " +"„finish“ aufzurufen." + +#: src/methods/example.md:50 +#, fuzzy +msgid "" +"Note that although the method receivers are different, the non-static " +"functions are called the same way in the main body. Rust enables automatic " +"referencing and dereferencing when calling methods. Rust automatically adds " +"in the `&`, `*`, `muts` so that that object matches the method signature." +msgstr "" +"Beachten Sie, dass, obwohl die Methodenempfänger unterschiedlich sind, die " +"nicht statischen Funktionen im Hauptteil auf die gleiche Weise aufgerufen " +"werden. Rust ermöglicht die automatische Referenzierung und Dereferenzierung " +"beim Methodenaufruf. Rust fügt automatisch die `&`, `*`, `muts` hinzu, " +"sodass dieses Objekt mit der Methodensignatur übereinstimmt." + +#: src/methods/example.md:51 +#, fuzzy +msgid "" +"You might point out that `print_laps` is using a vector that is iterated " +"over. We describe vectors in more detail in the afternoon. " +msgstr "" +"Sie könnten darauf hinweisen, dass `print_laps` einen Vektor verwendet, der " +"iteriert wird. Am Nachmittag beschreiben wir Vektoren genauer." + #: src/exercises/day-2/morning.md:1 #, fuzzy msgid "Day 2: Morning Exercises" @@ -7311,14 +7590,138 @@ msgid "We will look at implementing methods in two contexts:" msgstr "Wir werden Implementierungsmethoden in zwei Kontexten betrachten:" #: src/exercises/day-2/morning.md:5 -#, fuzzy -msgid "Simple struct which tracks health statistics." -msgstr "Mehrere Strukturen und Aufzählungen für eine Zeichnungsbibliothek." +msgid "Storing books and querying the collection" +msgstr "" #: src/exercises/day-2/morning.md:7 -msgid "Multiple structs and enums for a drawing library." +msgid "Keeping track of health statistics for patients" msgstr "" +#: src/exercises/day-2/book-library.md:3 +#, fuzzy +msgid "" +"We will learn much more about structs and the `Vec` type tomorrow. For " +"now, you just need to know part of its API:" +msgstr "" +"Wir werden morgen viel mehr über Strukturen und den Typ `Vec` lernen. Zur " +"Zeit, Sie müssen nur einen Teil seiner API kennen:" + +#: src/exercises/day-2/book-library.md:6 +msgid "" +"```rust,editable\n" +"fn main() {\n" +" let mut vec = vec![10, 20];\n" +" vec.push(30);\n" +" let midpoint = vec.len() / 2;\n" +" println!(\"middle value: {}\", vec[midpoint]);\n" +" for item in &vec {\n" +" println!(\"item: {item}\");\n" +" }\n" +"}\n" +"```" +msgstr "" + +#: src/exercises/day-2/book-library.md:18 +#, fuzzy +msgid "" +"Use this to model a library's book collection. Copy the code below to " +" and update the types to make it compile:" +msgstr "" +"Verwenden Sie dies, um eine Bibliotheksanwendung zu erstellen. Kopieren Sie " +"den folgenden Code nach und aktualisieren Sie " +"die Typen, damit es kompiliert wird:" + +#: src/exercises/day-2/book-library.md:21 +msgid "" +"```rust,should_panic\n" +"struct Library {\n" +" books: Vec,\n" +"}\n" +"\n" +"struct Book {\n" +" title: String,\n" +" year: u16,\n" +"}\n" +"\n" +"impl Book {\n" +" // This is a constructor, used below.\n" +" fn new(title: &str, year: u16) -> Book {\n" +" Book {\n" +" title: String::from(title),\n" +" year,\n" +" }\n" +" }\n" +"}\n" +"\n" +"// Implement the methods below. Update the `self` parameter to\n" +"// indicate the method's required level of ownership over the object:\n" +"//\n" +"// - `&self` for shared read-only access,\n" +"// - `&mut self` for unique and mutable access,\n" +"// - `self` for unique access by value.\n" +"impl Library {\n" +" fn new() -> Library {\n" +" todo!(\"Initialize and return a `Library` value\")\n" +" }\n" +"\n" +" //fn len(self) -> usize {\n" +" // todo!(\"Return the length of `self.books`\")\n" +" //}\n" +"\n" +" //fn is_empty(self) -> bool {\n" +" // todo!(\"Return `true` if `self.books` is empty\")\n" +" //}\n" +"\n" +" //fn add_book(self, book: Book) {\n" +" // todo!(\"Add a new book to `self.books`\")\n" +" //}\n" +"\n" +" //fn print_books(self) {\n" +" // todo!(\"Iterate over `self.books` and print each book's title and " +"year\")\n" +" //}\n" +"\n" +" //fn oldest_book(self) -> Option<&Book> {\n" +" // todo!(\"Return a reference to the oldest book (if any)\")\n" +" //}\n" +"}\n" +"\n" +"// This shows the desired behavior. Uncomment the code below and\n" +"// implement the missing methods. You will need to update the\n" +"// method signatures, including the \"self\" parameter! You may\n" +"// also need to update the variable bindings within main.\n" +"fn main() {\n" +" let library = Library::new();\n" +"\n" +" //println!(\"The library is empty: library.is_empty() -> {}\", library." +"is_empty());\n" +" //\n" +" //library.add_book(Book::new(\"Lord of the Rings\", 1954));\n" +" //library.add_book(Book::new(\"Alice's Adventures in Wonderland\", " +"1865));\n" +" //\n" +" //println!(\"The library is no longer empty: library.is_empty() -> {}\", " +"library.is_empty());\n" +" //\n" +" //\n" +" //library.print_books();\n" +" //\n" +" //match library.oldest_book() {\n" +" // Some(book) => println!(\"The oldest book is {}\", book.title),\n" +" // None => println!(\"The library is empty!\"),\n" +" //}\n" +" //\n" +" //println!(\"The library has {} books\", library.len());\n" +" //library.print_books();\n" +"}\n" +"```" +msgstr "" + +#: src/exercises/day-2/book-library.md:102 +#, fuzzy +msgid "[Solution](solutions-afternoon.md#designing-a-library)" +msgstr "[Lösung](solutions-afternoon.md#designing-a-library)" + #: src/exercises/day-2/health-statistics.md:3 #, fuzzy msgid "" @@ -7354,14 +7757,28 @@ msgid "" "// TODO: remove this when you're done with your implementation.\n" "#![allow(unused_variables, dead_code)]\n" "\n" -"struct User {\n" +"pub struct User {\n" " name: String,\n" " age: u32,\n" -" weight: f32,\n" +" height: f32,\n" +" visit_count: usize,\n" +" last_blood_pressure: Option<(u32, u32)>,\n" +"}\n" +"\n" +"pub struct Measurements {\n" +" height: f32,\n" +" blood_pressure: (u32, u32),\n" +"}\n" +"\n" +"pub struct HealthReport<'a> {\n" +" patient_name: &'a str,\n" +" visit_count: u32,\n" +" height_change: f32,\n" +" blood_pressure_change: Option<(i32, i32)>,\n" "}\n" "\n" "impl User {\n" -" pub fn new(name: String, age: u32, weight: f32) -> Self {\n" +" pub fn new(name: String, age: u32, height: f32) -> Self {\n" " unimplemented!()\n" " }\n" "\n" @@ -7373,7 +7790,11 @@ msgid "" " unimplemented!()\n" " }\n" "\n" -" pub fn weight(&self) -> f32 {\n" +" pub fn height(&self) -> f32 {\n" +" unimplemented!()\n" +" }\n" +"\n" +" pub fn doctor_visits(&self) -> u32 {\n" " unimplemented!()\n" " }\n" "\n" @@ -7381,7 +7802,12 @@ msgid "" " unimplemented!()\n" " }\n" "\n" -" pub fn set_weight(&mut self, new_weight: f32) {\n" +" pub fn set_height(&mut self, new_height: f32) {\n" +" unimplemented!()\n" +" }\n" +"\n" +" pub fn visit_doctor(&mut self, measurements: Measurements) -> " +"HealthReport {\n" " unimplemented!()\n" " }\n" "}\n" @@ -7392,9 +7818,9 @@ msgid "" "}\n" "\n" "#[test]\n" -"fn test_weight() {\n" +"fn test_height() {\n" " let bob = User::new(String::from(\"Bob\"), 32, 155.2);\n" -" assert_eq!(bob.weight(), 155.2);\n" +" assert_eq!(bob.height(), 155.2);\n" "}\n" "\n" "#[test]\n" @@ -7404,722 +7830,30 @@ msgid "" " bob.set_age(33);\n" " assert_eq!(bob.age(), 33);\n" "}\n" -"```" -msgstr "" - -#: src/exercises/day-2/points-polygons.md:1 -#, fuzzy -msgid "Polygon Struct" -msgstr "Polygonstruktur" - -#: src/exercises/day-2/points-polygons.md:3 -#, fuzzy -msgid "" -"We will create a `Polygon` struct which contain some points. Copy the code " -"below to and fill in the missing methods to " -"make the tests pass:" -msgstr "" -"Wir werden eine \"Polygon\"-Struktur erstellen, die einige Punkte enthält. " -"Kopieren Sie den Code unten zu und füllen Sie " -"die fehlenden Methoden aus, um die Tests bestehen:" - -#: src/exercises/day-2/points-polygons.md:7 -msgid "" -"```rust\n" -"// TODO: remove this when you're done with your implementation.\n" -"#![allow(unused_variables, dead_code)]\n" "\n" -"pub struct Point {\n" -" // add fields\n" -"}\n" +"#[test]\n" +"fn test_visit() {\n" +" let mut bob = User::new(String::from(\"Bob\"), 32, 155.2);\n" +" assert_eq!(bob.doctor_visits(), 0);\n" +" let report = bob.visit_doctor(Measurements {\n" +" height: 156.1,\n" +" blood_pressure: (120, 80),\n" +" });\n" +" assert_eq!(report.patient_name, \"Bob\");\n" +" assert_eq!(report.visit_count, 1);\n" +" assert_eq!(report.blood_pressure_change, None);\n" "\n" -"impl Point {\n" -" // add methods\n" -"}\n" +" let report = bob.visit_doctor(Measurements {\n" +" height: 156.1,\n" +" blood_pressure: (115, 76),\n" +" });\n" "\n" -"pub struct Polygon {\n" -" // add fields\n" -"}\n" -"\n" -"impl Polygon {\n" -" // add methods\n" -"}\n" -"\n" -"pub struct Circle {\n" -" // add fields\n" -"}\n" -"\n" -"impl Circle {\n" -" // add methods\n" -"}\n" -"\n" -"pub enum Shape {\n" -" Polygon(Polygon),\n" -" Circle(Circle),\n" -"}\n" -"\n" -"#[cfg(test)]\n" -"mod tests {\n" -" use super::*;\n" -"\n" -" fn round_two_digits(x: f64) -> f64 {\n" -" (x * 100.0).round() / 100.0\n" -" }\n" -"\n" -" #[test]\n" -" fn test_point_magnitude() {\n" -" let p1 = Point::new(12, 13);\n" -" assert_eq!(round_two_digits(p1.magnitude()), 17.69);\n" -" }\n" -"\n" -" #[test]\n" -" fn test_point_dist() {\n" -" let p1 = Point::new(10, 10);\n" -" let p2 = Point::new(14, 13);\n" -" assert_eq!(round_two_digits(p1.dist(p2)), 5.00);\n" -" }\n" -"\n" -" #[test]\n" -" fn test_point_add() {\n" -" let p1 = Point::new(16, 16);\n" -" let p2 = p1 + Point::new(-4, 3);\n" -" assert_eq!(p2, Point::new(12, 19));\n" -" }\n" -"\n" -" #[test]\n" -" fn test_polygon_left_most_point() {\n" -" let p1 = Point::new(12, 13);\n" -" let p2 = Point::new(16, 16);\n" -"\n" -" let mut poly = Polygon::new();\n" -" poly.add_point(p1);\n" -" poly.add_point(p2);\n" -" assert_eq!(poly.left_most_point(), Some(p1));\n" -" }\n" -"\n" -" #[test]\n" -" fn test_polygon_iter() {\n" -" let p1 = Point::new(12, 13);\n" -" let p2 = Point::new(16, 16);\n" -"\n" -" let mut poly = Polygon::new();\n" -" poly.add_point(p1);\n" -" poly.add_point(p2);\n" -"\n" -" let points = poly.iter().cloned().collect::>();\n" -" assert_eq!(points, vec![Point::new(12, 13), Point::new(16, 16)]);\n" -" }\n" -"\n" -" #[test]\n" -" fn test_shape_perimeters() {\n" -" let mut poly = Polygon::new();\n" -" poly.add_point(Point::new(12, 13));\n" -" poly.add_point(Point::new(17, 11));\n" -" poly.add_point(Point::new(16, 16));\n" -" let shapes = vec![\n" -" Shape::from(poly),\n" -" Shape::from(Circle::new(Point::new(10, 20), 5)),\n" -" ];\n" -" let perimeters = shapes\n" -" .iter()\n" -" .map(Shape::perimeter)\n" -" .map(round_two_digits)\n" -" .collect::>();\n" -" assert_eq!(perimeters, vec![15.48, 31.42]);\n" -" }\n" -"}\n" -"\n" -"#[allow(dead_code)]\n" -"fn main() {}\n" -"```" -msgstr "" - -#: src/exercises/day-2/points-polygons.md:117 -#, fuzzy -msgid "" -"Since the method signatures are missing from the problem statements, the key " -"part of the exercise is to specify those correctly. You don't have to modify " -"the tests." -msgstr "" -"Da die Methodensignaturen in den Problembeschreibungen fehlen, ist der " -"Schlüsselteil der Übung ist es, diese richtig anzugeben." - -#: src/exercises/day-2/points-polygons.md:120 -#, fuzzy -msgid "Other interesting parts of the exercise:" -msgstr "Weitere interessante Teile der Übung:" - -#: src/exercises/day-2/points-polygons.md:122 -#, fuzzy -msgid "" -"Derive a `Copy` trait for some structs, as in tests the methods sometimes " -"don't borrow their arguments." -msgstr "" -"Leiten Sie ein `Copy`\\-Merkmal für einige Strukturen ab, da die Methoden in " -"Tests ihre Argumente manchmal nicht ausleihen." - -#: src/exercises/day-2/points-polygons.md:123 -#, fuzzy -msgid "" -"Discover that `Add` trait must be implemented for two objects to be addable " -"via \"+\". Note that we do not discuss generics until Day 3." -msgstr "" -"Entdecken Sie, dass die Eigenschaft „Hinzufügen“ implementiert werden muss, " -"damit zwei Objekte über „+“ hinzugefügt werden können." - -#: src/control-flow.md:3 -#, fuzzy -msgid "" -"As we have seen, `if` is an expression in Rust. It is used to conditionally " -"evaluate one of two blocks, but the blocks can have a value which then " -"becomes the value of the `if` expression. Other control flow expressions " -"work similarly in Rust." -msgstr "" -"Wie wir gesehen haben, ist `if` ein Ausdruck in Rust. Es ist bedingt gewohnt " -"einen von zwei Blöcken auswerten, aber die Blöcke können einen Wert haben, " -"der dann wird der Wert des `if`\\-Ausdrucks. Andere " -"Ablaufsteuerungsausdrücke funktionieren ähnlich in Rost." - -#: src/control-flow/blocks.md:3 -#, fuzzy -msgid "" -"A block in Rust has a value and a type: the value is the last expression of " -"the block:" -msgstr "" -"Ein Block in Rust hat einen Wert und einen Typ: Der Wert ist der letzte " -"Ausdruck der Block:" - -#: src/control-flow/blocks.md:6 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let x = {\n" -" let y = 10;\n" -" println!(\"y: {y}\");\n" -" let z = {\n" -" let w = {\n" -" 3 + 4\n" -" };\n" -" println!(\"w: {w}\");\n" -" y * w\n" -" };\n" -" println!(\"z: {z}\");\n" -" z - y\n" -" };\n" -" println!(\"x: {x}\");\n" +" assert_eq!(report.visit_count, 2);\n" +" assert_eq!(report.blood_pressure_change, Some((-5, -4)));\n" "}\n" "```" msgstr "" -#: src/control-flow/blocks.md:25 -#, fuzzy -msgid "" -"The same rule is used for functions: the value of the function body is the " -"return value:" -msgstr "" -"Die gleiche Regel gilt für Funktionen: Der Wert des Funktionskörpers ist der " -"Rückgabewert:" - -#: src/control-flow/blocks.md:28 -msgid "" -"```rust,editable\n" -"fn double(x: i32) -> i32 {\n" -" x + x\n" -"}\n" -"\n" -"fn main() {\n" -" println!(\"doubled: {}\", double(7));\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/blocks.md:38 -msgid "" -"However if the last expression ends with `;`, then the resulting value and " -"type is `()`." -msgstr "" - -#: src/control-flow/blocks.md:43 -#, fuzzy -msgid "" -"The point of this slide is to show that blocks have a type and value in " -"Rust. " -msgstr "" -"Der Zweck dieser Folie ist es zu zeigen, dass Blöcke in Rust einen Typ und " -"einen Wert haben." - -#: src/control-flow/blocks.md:44 -#, fuzzy -msgid "" -"You can show how the value of the block changes by changing the last line in " -"the block. For instance, adding/removing a semicolon or using a `return`." -msgstr "" -"Sie können zeigen, wie sich der Wert des Blocks ändert, indem Sie die letzte " -"Zeile im Block ändern. Zum Beispiel das Hinzufügen/Entfernen eines " -"Semikolons oder die Verwendung eines `Return`." - -#: src/control-flow/if-expressions.md:1 -#, fuzzy -msgid "`if` expressions" -msgstr "`if`\\-Ausdrücke" - -#: src/control-flow/if-expressions.md:3 -msgid "" -"You use [`if` expressions](https://doc.rust-lang.org/reference/expressions/" -"if-expr.html#if-expressions) exactly like `if` statements in other languages:" -msgstr "" - -#: src/control-flow/if-expressions.md:7 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut x = 10;\n" -" if x % 2 == 0 {\n" -" x = x / 2;\n" -" } else {\n" -" x = 3 * x + 1;\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/if-expressions.md:18 -#, fuzzy -msgid "" -"In addition, you can use `if` as an expression. The last expression of each " -"block becomes the value of the `if` expression:" -msgstr "" -"Darüber hinaus können Sie es als Ausdruck verwenden. Das macht dasselbe wie " -"oben:" - -#: src/control-flow/if-expressions.md:22 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut x = 10;\n" -" x = if x % 2 == 0 {\n" -" x / 2\n" -" } else {\n" -" 3 * x + 1\n" -" };\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/if-expressions.md:35 -msgid "" -"Because `if` is an expression and must have a particular type, both of its " -"branch blocks must have the same type. Consider showing what happens if you " -"add `;` after `x / 2` in the second example." -msgstr "" - -#: src/control-flow/if-let-expressions.md:1 -#, fuzzy -msgid "`if let` expressions" -msgstr "`if let`\\-Ausdrücke" - -#: src/control-flow/if-let-expressions.md:3 -msgid "" -"The [`if let` expression](https://doc.rust-lang.org/reference/expressions/if-" -"expr.html#if-let-expressions) lets you execute different code depending on " -"whether a value matches a pattern:" -msgstr "" - -#: src/control-flow/if-let-expressions.md:7 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let arg = std::env::args().next();\n" -" if let Some(value) = arg {\n" -" println!(\"Program name: {value}\");\n" -" } else {\n" -" println!(\"Missing name?\");\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/if-let-expressions.md:18 -#: src/control-flow/while-let-expressions.md:21 -#: src/control-flow/match-expressions.md:23 -#, fuzzy -msgid "" -"See [pattern matching](../pattern-matching.md) for more details on patterns " -"in Rust." -msgstr "" -"Siehe [pattern matching](../pattern-matching.md) für weitere Details zu " -"Mustern in Rost." - -#: src/control-flow/if-let-expressions.md:23 -msgid "" -"`if let` can be more concise than `match`, e.g., when only one case is " -"interesting. In contrast, `match` requires all branches to be covered." -msgstr "" - -#: src/control-flow/if-let-expressions.md:24 -msgid "A common usage is handling `Some` values when working with `Option`." -msgstr "" - -#: src/control-flow/if-let-expressions.md:25 -msgid "" -"Unlike `match`, `if let` does not support guard clauses for pattern matching." -msgstr "" - -#: src/control-flow/if-let-expressions.md:26 -msgid "" -"Since 1.65, a similar [let-else](https://doc.rust-lang.org/rust-by-example/" -"flow_control/let_else.html) construct allows to do a destructuring " -"assignment, or if it fails, have a non-returning block branch (panic/return/" -"break/continue):" -msgstr "" - -#: src/control-flow/if-let-expressions.md:28 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" println!(\"{:?}\", second_word_to_upper(\"foo bar\"));\n" -"}\n" -" \n" -"fn second_word_to_upper(s: &str) -> Option {\n" -" let mut it = s.split(' ');\n" -" let (Some(_), Some(item)) = (it.next(), it.next()) else {\n" -" return None;\n" -" };\n" -" Some(item.to_uppercase())\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/while-expressions.md:1 -#, fuzzy -msgid "`while` loops" -msgstr "`while`\\-Ausdrücke" - -#: src/control-flow/while-expressions.md:3 -msgid "" -"The [`while` keyword](https://doc.rust-lang.org/reference/expressions/loop-" -"expr.html#predicate-loops) works very similar to other languages:" -msgstr "" - -#: src/control-flow/while-expressions.md:6 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut x = 10;\n" -" while x != 1 {\n" -" x = if x % 2 == 0 {\n" -" x / 2\n" -" } else {\n" -" 3 * x + 1\n" -" };\n" -" }\n" -" println!(\"Final x: {x}\");\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/while-let-expressions.md:1 -#, fuzzy -msgid "`while let` loops" -msgstr "`while let`\\-Ausdrücke" - -#: src/control-flow/while-let-expressions.md:3 -#, fuzzy -msgid "" -"Like with `if let`, there is a [`while let`](https://doc.rust-lang.org/" -"reference/expressions/loop-expr.html#predicate-pattern-loops) variant which " -"repeatedly tests a value against a pattern:" -msgstr "" -"Wie bei `if` gibt es eine `while let`\\-Variante, die einen Wert wiederholt " -"testet gegen ein Muster:" - -#: src/control-flow/while-let-expressions.md:6 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let v = vec![10, 20, 30];\n" -" let mut iter = v.into_iter();\n" -"\n" -" while let Some(x) = iter.next() {\n" -" println!(\"x: {x}\");\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/while-let-expressions.md:17 -#, fuzzy -msgid "" -"Here the iterator returned by `v.iter()` will return a `Option` on " -"every call to `next()`. It returns `Some(x)` until it is done, after which " -"it will return `None`. The `while let` lets us keep iterating through all " -"items." -msgstr "" -"Hier gibt der von `v.iter()` zurückgegebene Iterator bei jedem eine " -"`Option` zurück Aufruf von `next()`. Es gibt `Some(x)` zurück, bis es " -"fertig ist, danach wird es gibt \"Keine\" zurück. Das `while let` lässt uns " -"alle Elemente durchlaufen." - -#: src/control-flow/while-let-expressions.md:26 -#, fuzzy -msgid "" -"Point out that the `while let` loop will keep going as long as the value " -"matches the pattern." -msgstr "" -"Weisen Sie darauf hin, dass die „while let“-Schleife so lange läuft, wie der " -"Wert mit dem Muster übereinstimmt." - -#: src/control-flow/while-let-expressions.md:27 -#, fuzzy -msgid "" -"You could rewrite the `while let` loop as an infinite loop with an if " -"statement that breaks when there is no value to unwrap for `iter.next()`. " -"The `while let` provides syntactic sugar for the above scenario." -msgstr "" -"Sie könnten die „while let“-Schleife als Endlosschleife mit einer if-" -"Anweisung umschreiben, die abbricht, wenn es keinen Wert zum Auspacken für " -"„iter.next()“ gibt. Das `while let` liefert syntaktischen Zucker für das " -"obige Szenario." - -#: src/control-flow/for-expressions.md:1 -#, fuzzy -msgid "`for` loops" -msgstr "`for`\\-Schleifen" - -#: src/control-flow/for-expressions.md:3 -#, fuzzy -msgid "" -"The [`for` loop](https://doc.rust-lang.org/std/keyword.for.html) is closely " -"related to the [`while let` loop](while-let-expression.md). It will " -"automatically call `into_iter()` on the expression and then iterate over it:" -msgstr "" -"Der „for“-Ausdruck ist eng verwandt mit dem „while let“-Ausdruck. Es wird " -"Rufen Sie automatisch `into_iter()` für den Ausdruck auf und iterieren Sie " -"dann darüber:" - -#: src/control-flow/for-expressions.md:7 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let v = vec![10, 20, 30];\n" -"\n" -" for x in v {\n" -" println!(\"x: {x}\");\n" -" }\n" -" \n" -" for i in (0..10).step_by(2) {\n" -" println!(\"i: {i}\");\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/for-expressions.md:21 -#, fuzzy -msgid "You can use `break` and `continue` here as usual." -msgstr "Sie können hier wie gewohnt `break` und `continue` verwenden." - -#: src/control-flow/for-expressions.md:25 -#, fuzzy -msgid "Index iteration is not a special syntax in Rust for just that case." -msgstr "" -"Index-Iteration ist in Rust keine spezielle Syntax für genau diesen Fall." - -#: src/control-flow/for-expressions.md:26 -#, fuzzy -msgid "`(0..10)` is a range that implements an `Iterator` trait. " -msgstr "„(0..10)“ ist ein Bereich, der ein „Iterator“-Merkmal implementiert." - -#: src/control-flow/for-expressions.md:27 -#, fuzzy -msgid "" -"`step_by` is a method that returns another `Iterator` that skips every other " -"element. " -msgstr "" -"„step_by“ ist eine Methode, die einen weiteren „Iterator“ zurückgibt, der " -"jedes andere Element überspringt." - -#: src/control-flow/for-expressions.md:28 -msgid "" -"Modify the elements in the vector and explain the compiler errors. Change " -"vector `v` to be mutable and the for loop to `for x in v.iter_mut()`." -msgstr "" - -#: src/control-flow/loop-expressions.md:1 -#, fuzzy -msgid "`loop` expressions" -msgstr "`loop`\\-Ausdrücke" - -#: src/control-flow/loop-expressions.md:3 -msgid "" -"Finally, there is a [`loop` keyword](https://doc.rust-lang.org/reference/" -"expressions/loop-expr.html#infinite-loops) which creates an endless loop." -msgstr "" - -#: src/control-flow/loop-expressions.md:6 -#, fuzzy -msgid "Here you must either `break` or `return` to stop the loop:" -msgstr "" -"Schließlich gibt es noch ein „loop“-Schlüsselwort, das eine Endlosschleife " -"erzeugt. Hier müssen Sie entweder `break` oder `return`, um die Schleife zu " -"stoppen:" - -#: src/control-flow/loop-expressions.md:8 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let mut x = 10;\n" -" loop {\n" -" x = if x % 2 == 0 {\n" -" x / 2\n" -" } else {\n" -" 3 * x + 1\n" -" };\n" -" if x == 1 {\n" -" break;\n" -" }\n" -" }\n" -" println!(\"Final x: {x}\");\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/loop-expressions.md:27 -msgid "Break the `loop` with a value (e.g. `break 8`) and print it out." -msgstr "" - -#: src/control-flow/loop-expressions.md:28 -msgid "" -"Note that `loop` is the only looping construct which returns a non-trivial " -"value. This is because it's guaranteed to be entered at least once (unlike " -"`while` and `for` loops)." -msgstr "" - -#: src/control-flow/match-expressions.md:1 -#, fuzzy -msgid "`match` expressions" -msgstr "`Match`\\-Ausdrücke" - -#: src/control-flow/match-expressions.md:3 -#, fuzzy -msgid "" -"The [`match` keyword](https://doc.rust-lang.org/reference/expressions/match-" -"expr.html) is used to match a value against one or more patterns. In that " -"sense, it works like a series of `if let` expressions:" -msgstr "" -"Das Schlüsselwort „match“ wird verwendet, um einen Wert mit einem oder " -"mehreren Mustern abzugleichen. In In diesem Sinne funktioniert es wie eine " -"Reihe von `if let`\\-Ausdrücken:" - -#: src/control-flow/match-expressions.md:7 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" match std::env::args().next().as_deref() {\n" -" Some(\"cat\") => println!(\"Will do cat things\"),\n" -" Some(\"ls\") => println!(\"Will ls some files\"),\n" -" Some(\"mv\") => println!(\"Let's move some files\"),\n" -" Some(\"rm\") => println!(\"Uh, dangerous!\"),\n" -" None => println!(\"Hmm, no program name?\"),\n" -" _ => println!(\"Unknown program name!\"),\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/match-expressions.md:20 -#, fuzzy -msgid "" -"Like `if let`, each match arm must have the same type. The type is the last " -"expression of the block, if any. In the example above, the type is `()`." -msgstr "" -"Wie bei „if let“ muss jeder Match-Arm denselben Typ haben. Der Typ ist der " -"letzte Ausdruck des Blocks, falls vorhanden. Im obigen Beispiel ist der Typ " -"`()`." - -#: src/control-flow/match-expressions.md:28 -msgid "Save the match expression to a variable and print it out." -msgstr "" - -#: src/control-flow/match-expressions.md:29 -msgid "Remove `.as_deref()` and explain the error." -msgstr "" - -#: src/control-flow/match-expressions.md:30 -msgid "" -"`std::env::args().next()` returns an `Option`, but we cannot match " -"against `String`." -msgstr "" - -#: src/control-flow/match-expressions.md:31 -msgid "" -"`as_deref()` transforms an `Option` to `Option<&T::Target>`. In our case, " -"this turns `Option` into `Option<&str>`." -msgstr "" - -#: src/control-flow/match-expressions.md:32 -msgid "" -"We can now use pattern matching to match against the `&str` inside `Option`." -msgstr "" - -#: src/control-flow/break-continue.md:1 -#, fuzzy -msgid "`break` and `continue`" -msgstr "`break` und `continue`" - -#: src/control-flow/break-continue.md:3 -msgid "" -"If you want to exit a loop early, use [`break`](https://doc.rust-lang.org/" -"reference/expressions/loop-expr.html#break-expressions)," -msgstr "" - -#: src/control-flow/break-continue.md:4 -msgid "" -"If you want to immediately start the next iteration use [`continue`](https://" -"doc.rust-lang.org/reference/expressions/loop-expr.html#continue-expressions)." -msgstr "" - -#: src/control-flow/break-continue.md:7 -#, fuzzy -msgid "" -"Both `continue` and `break` can optionally take a label argument which is " -"used to break out of nested loops:" -msgstr "" -"Wenn Sie eine Schleife vorzeitig verlassen möchten, verwenden Sie `break`, " -"wenn Sie sofort beginnen möchten Verwenden Sie für die nächste Iteration " -"\"Continue\". Sowohl `Continue` als auch `Break` können optional verwendet " -"werden Nehmen Sie ein Label-Argument, das zum Ausbrechen aus verschachtelten " -"Schleifen verwendet wird:" - -#: src/control-flow/break-continue.md:10 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let v = vec![10, 20, 30];\n" -" let mut iter = v.into_iter();\n" -" 'outer: while let Some(x) = iter.next() {\n" -" println!(\"x: {x}\");\n" -" let mut i = 0;\n" -" while i < x {\n" -" println!(\"x: {x}, i: {i}\");\n" -" i += 1;\n" -" if i == 3 {\n" -" break 'outer;\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/control-flow/break-continue.md:28 -#, fuzzy -msgid "" -"In this case we break the outer loop after 3 iterations of the inner loop." -msgstr "" -"In diesem Fall brechen wir die äußere Schleife nach 3 Iterationen der " -"inneren Schleife." - #: src/std.md:3 #, fuzzy msgid "" @@ -8571,6 +8305,14 @@ msgid "" "compiles. Where do you think we might run into issues?" msgstr "" +#: src/std/hashmap.md:64 +msgid "" +"This type has several \"method-specific\" return types, such as `std::" +"collections::hash_map::Keys`. These types often appear in searches of the " +"Rust docs. Show students the docs for this type, and the helpful link back " +"to the `keys` method." +msgstr "" + #: src/std/box.md:1 #, fuzzy msgid "`Box`" @@ -8595,22 +8337,6 @@ msgid "" "```" msgstr "" -#: src/std/box.md:13 -msgid "" -"```bob\n" -" Stack Heap\n" -".- - - - - - -. .- - - - - - -.\n" -": : : :\n" -": five : : :\n" -": +-----+ : : +-----+ :\n" -": | o---|---+-----+-->| 5 | :\n" -": +-----+ : : +-----+ :\n" -": : : :\n" -": : : :\n" -"`- - - - - - -' `- - - - - - -'\n" -"```" -msgstr "" - #: src/std/box.md:26 #, fuzzy msgid "" @@ -8705,9 +8431,9 @@ msgstr "" #: src/std/box-recursive.md:33 msgid "" -"If the `Box` was not used here and we attempted to embed a `List` directly " -"into the `List`, the compiler would not compute a fixed size of the struct " -"in memory, it would look infinite." +"If `Box` was not used and we attempted to embed a `List` directly into the " +"`List`, the compiler would not compute a fixed size of the struct in memory " +"(`List` would be of infinite size)." msgstr "" #: src/std/box-recursive.md:36 @@ -8786,100 +8512,136 @@ msgid "" msgstr "" #: src/std/rc.md:18 -#, fuzzy msgid "" -"If you need to mutate the data inside an `Rc`, you will need to wrap the " -"data in a type such as [`Cell` or `RefCell`](../concurrency/shared_state/arc." -"md)." -msgstr "" -"Wenn Sie die Daten innerhalb eines „Rc“ mutieren müssen, müssen Sie die " -"Daten einschließen ein Typ wie [`Cell` oder `RefCell`](../concurrency/" -"shared_state/arc.md). Siehe [`Arc`](https://doc.rust-lang.org/std/sync/" -"struct.Mutex.html), wenn Sie sich in einem Multithreading befinden Kontext." - -#: src/std/rc.md:20 -msgid "" -"See [`Arc`](https://doc.rust-lang.org/std/sync/struct.Mutex.html) if you are " -"in a multi-threaded context." +"See [`Arc`](../concurrency/shared_state/arc.md) and [`Mutex`](https://doc." +"rust-lang.org/std/sync/struct.Mutex.html) if you are in a multi-threaded " +"context." msgstr "" -#: src/std/rc.md:21 +#: src/std/rc.md:19 msgid "" "You can _downgrade_ a shared pointer into a [`Weak`](https://doc.rust-lang." "org/std/rc/struct.Weak.html) pointer to create cycles that will get dropped." msgstr "" -#: src/std/rc.md:31 +#: src/std/rc.md:29 msgid "" "`Rc`'s count ensures that its contained value is valid for as long as there " "are references." msgstr "" -#: src/std/rc.md:32 -msgid "Like C++'s `std::shared_ptr`." +#: src/std/rc.md:30 +msgid "`Rc` in Rust is like `std::shared_ptr` in C++." msgstr "" -#: src/std/rc.md:33 +#: src/std/rc.md:31 msgid "" "`Rc::clone` is cheap: it creates a pointer to the same allocation and " "increases the reference count. Does not make a deep clone and can generally " "be ignored when looking for performance issues in code." msgstr "" -#: src/std/rc.md:34 +#: src/std/rc.md:32 msgid "" "`make_mut` actually clones the inner value if necessary (\"clone-on-write\") " "and returns a mutable reference." msgstr "" -#: src/std/rc.md:35 +#: src/std/rc.md:33 msgid "Use `Rc::strong_count` to check the reference count." msgstr "" -#: src/std/rc.md:36 -msgid "" -"Compare the different datatypes mentioned. `Box` enables (im)mutable borrows " -"that are enforced at compile time. `RefCell` enables (im)mutable borrows " -"that are enforced at run time and will panic if it fails at runtime." -msgstr "" - -#: src/std/rc.md:37 +#: src/std/rc.md:34 msgid "" "`Rc::downgrade` gives you a _weakly reference-counted_ object to create " -"cycles that will be dropped properly (likely in combination with `RefCell`)." +"cycles that will be dropped properly (likely in combination with `RefCell`, " +"on the next slide)." msgstr "" -#: src/std/rc.md:41 +#: src/std/cell.md:1 +msgid "`Cell` and `RefCell`" +msgstr "" + +#: src/std/cell.md:3 +#, fuzzy +msgid "" +"[`Cell`](https://doc.rust-lang.org/std/cell/struct.Cell.html) and [`RefCell`]" +"(https://doc.rust-lang.org/std/cell/struct.RefCell.html) implement what Rust " +"calls _interior mutability:_ mutation of values in an immutable context." +msgstr "Mit `Read` und `BufRead` können Sie über `u8`\\-Quellen abstrahieren:" + +#: src/std/cell.md:8 +msgid "" +"`Cell` is typically used for simple types, as it requires copying or moving " +"values. More complex interior types typically use `RefCell`, which tracks " +"shared and exclusive references at runtime and panics if they are misused." +msgstr "" + +#: src/std/cell.md:12 msgid "" "```rust,editable\n" -"use std::rc::{Rc, Weak};\n" "use std::cell::RefCell;\n" +"use std::rc::Rc;\n" "\n" -"#[derive(Debug)]\n" +"#[derive(Debug, Default)]\n" "struct Node {\n" " value: i64,\n" -" parent: Option>>,\n" " children: Vec>>,\n" "}\n" "\n" +"impl Node {\n" +" fn new(value: i64) -> Rc> {\n" +" Rc::new(RefCell::new(Node { value, ..Node::default() }))\n" +" }\n" +"\n" +" fn sum(&self) -> i64 {\n" +" self.value + self.children.iter().map(|c| c.borrow().sum()).sum::" +"()\n" +" }\n" +"}\n" +"\n" "fn main() {\n" -" let mut root = Rc::new(RefCell::new(Node {\n" -" value: 42,\n" -" parent: None,\n" -" children: vec![],\n" -" }));\n" -" let child = Rc::new(RefCell::new(Node {\n" -" value: 43,\n" -" children: vec![],\n" -" parent: Some(Rc::downgrade(&root))\n" -" }));\n" -" root.borrow_mut().children.push(child);\n" +" let root = Node::new(1);\n" +" root.borrow_mut().children.push(Node::new(5));\n" +" let subtree = Node::new(10);\n" +" subtree.borrow_mut().children.push(Node::new(11));\n" +" subtree.borrow_mut().children.push(Node::new(12));\n" +" root.borrow_mut().children.push(subtree);\n" "\n" " println!(\"graph: {root:#?}\");\n" +" println!(\"graph sum: {}\", root.borrow().sum());\n" "}\n" "```" msgstr "" +#: src/std/cell.md:47 +msgid "" +"If we were using `Cell` instead of `RefCell` in this example, we would have " +"to move the `Node` out of the `Rc` to push children, then move it back in. " +"This is safe because there's always one, un-referenced value in the cell, " +"but it's not ergonomic." +msgstr "" + +#: src/std/cell.md:48 +msgid "" +"To do anything with a Node, you must call a `RefCell` method, usually " +"`borrow` or `borrow_mut`." +msgstr "" + +#: src/std/cell.md:49 +msgid "" +"Demonstrate that reference loops can be created by adding `root` to `subtree." +"children` (don't try to print it!)." +msgstr "" + +#: src/std/cell.md:50 +msgid "" +"To demonstrate a runtime panic, add a `fn inc(&mut self)` that increments " +"`self.value` and calls the same method on its children. This will panic in " +"the presence of the reference loop, with `thread 'main' panicked at 'already " +"borrowed: BorrowMutError'`." +msgstr "" + #: src/modules.md:3 #, fuzzy msgid "We have seen how `impl` blocks let us namespace functions to a type." @@ -9051,81 +8813,41 @@ msgid "" "will typically see something like this at the top of each module:" msgstr "" -#: src/modules/paths.md:16 -msgid "" -"```rust,editable\n" -"use std::collections::HashSet;\n" -"use std::mem::transmute;\n" -"```" -msgstr "" - #: src/modules/filesystem.md:3 -#, fuzzy -msgid "The module content can be omitted:" -msgstr "Der Modulinhalt kann weggelassen werden:" - -#: src/modules/filesystem.md:5 msgid "" -"```rust,editable,compile_fail\n" -"mod garden;\n" -"```" +"Omitting the module content will tell Rust to look for it in another file:" msgstr "" #: src/modules/filesystem.md:9 -#, fuzzy -msgid "The `garden` module content is found at:" -msgstr "Die Inhalte des Moduls „Garten“ finden Sie unter:" - -#: src/modules/filesystem.md:11 -#, fuzzy -msgid "`src/garden.rs` (modern Rust 2018 style)" -msgstr "`src/garden.rs` (moderner Rust 2018-Stil)" +msgid "" +"This tells rust that the `garden` module content is found at `src/garden." +"rs`. Similarly, a `garden::vegetables` module can be found at `src/garden/" +"vegetables.rs`." +msgstr "" #: src/modules/filesystem.md:12 #, fuzzy -msgid "`src/garden/mod.rs` (older Rust 2015 style)" -msgstr "`src/garden/mod.rs` (älterer Rust 2015-Stil)" - -#: src/modules/filesystem.md:14 -#, fuzzy -msgid "Similarly, a `garden::vegetables` module can be found at:" -msgstr "" -"In ähnlicher Weise kann ein `garden::vegetables`\\-Modul gefunden werden " -"unter:" - -#: src/modules/filesystem.md:16 -#, fuzzy -msgid "`src/garden/vegetables.rs` (modern Rust 2018 style)" -msgstr "`src/garden/vegetables.rs` (moderner Rust 2018-Stil)" - -#: src/modules/filesystem.md:17 -#, fuzzy -msgid "`src/garden/vegetables/mod.rs` (older Rust 2015 style)" -msgstr "`src/garden/vegetables/mod.rs` (älterer Rust 2015 Stil)" - -#: src/modules/filesystem.md:19 -#, fuzzy msgid "The `crate` root is in:" msgstr "Die „Kiste“-Wurzel befindet sich in:" -#: src/modules/filesystem.md:21 +#: src/modules/filesystem.md:14 #, fuzzy msgid "`src/lib.rs` (for a library crate)" msgstr "`src/lib.rs` (für eine Bibliothekskiste)" -#: src/modules/filesystem.md:22 +#: src/modules/filesystem.md:15 #, fuzzy msgid "`src/main.rs` (for a binary crate)" msgstr "`src/main.rs` (für eine Binärkiste)" -#: src/modules/filesystem.md:24 +#: src/modules/filesystem.md:17 msgid "" "Modules defined in files can be documented, too, using \"inner doc " "comments\". These document the item that contains them -- in this case, a " "module." msgstr "" -#: src/modules/filesystem.md:27 +#: src/modules/filesystem.md:20 msgid "" "```rust,editable,compile_fail\n" "//! This module implements the garden, including a highly performant " @@ -9144,48 +8866,37 @@ msgid "" "```" msgstr "" -#: src/modules/filesystem.md:44 +#: src/modules/filesystem.md:37 msgid "" -"The change from `module/mod.rs` to `module.rs` doesn't preclude the use of " -"submodules in Rust 2018. (It was mandatory in Rust 2015.)" +"Before Rust 2018, modules needed to be located at `module/mod.rs` instead of " +"`module.rs`, and this is still a working alternative for editions after 2018." msgstr "" -#: src/modules/filesystem.md:47 -msgid "The following is valid:" -msgstr "" - -#: src/modules/filesystem.md:49 +#: src/modules/filesystem.md:39 msgid "" -"```ignore\n" -"src/\n" -"├── main.rs\n" -"├── top_module.rs\n" -"└── top_module/\n" -" └── sub_module.rs\n" -"```" +"The main reason to introduce `filename.rs` as alternative to `filename/mod." +"rs` was because many files named `mod.rs` can be hard to distinguish in IDEs." msgstr "" -#: src/modules/filesystem.md:57 +#: src/modules/filesystem.md:42 +msgid "Deeper nesting can use folders, even if the main module is a file:" +msgstr "" + +#: src/modules/filesystem.md:52 msgid "" -"The main reason for the change is to prevent many files named `mod.rs`, " -"which can be hard to distinguish in IDEs." +"The place rust will look for modules can be changed with a compiler " +"directive:" msgstr "" -#: src/modules/filesystem.md:60 -msgid "" -"Rust will look for modules in `modulename/mod.rs` and `modulename.rs`, but " -"this can be changed with a compiler directive:" -msgstr "" - -#: src/modules/filesystem.md:63 +#: src/modules/filesystem.md:54 msgid "" "```rust,ignore\n" "#[path = \"some/path.rs\"]\n" -"mod some_module { }\n" +"mod some_module;\n" "```" msgstr "" -#: src/modules/filesystem.md:68 +#: src/modules/filesystem.md:59 msgid "" "This is useful, for example, if you would like to place tests for a module " "in a file named `some_module_test.rs`, similar to the convention in Go." @@ -9203,103 +8914,198 @@ msgstr "" "Die Übungen für diesen Nachmittag konzentrieren sich auf Strings und " "Iteratoren." -#: src/exercises/day-2/luhn.md:3 +#: src/exercises/day-2/iterators-and-ownership.md:3 #, fuzzy msgid "" -"The [Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm) is used " -"to validate credit card numbers. The algorithm takes a string as input and " -"does the following to validate the credit card number:" +"The ownership model of Rust affects many APIs. An example of this is the " +"[`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html) and " +"[`IntoIterator`](https://doc.rust-lang.org/std/iter/trait.IntoIterator.html) " +"traits." msgstr "" -"Dazu dient der [Luhn-Algorithmus](https://en.wikipedia.org/wiki/" -"Luhn_algorithm). Kreditkartennummern validieren. Der Algorithmus nimmt eine " -"Zeichenfolge als Eingabe und führt die aus Folgendes, um die " -"Kreditkartennummer zu validieren:" +"Das Eigentumsmodell von Rust betrifft viele APIs. Ein Beispiel hierfür ist " +"die [`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html) und " +"[`IntoIterator`](https://doc.rust-lang.org/std/iter/trait.IntoIterator.html) " +"Züge." -#: src/exercises/day-2/luhn.md:7 -msgid "Ignore all spaces. Reject number with less than two digits." -msgstr "" +#: src/exercises/day-2/iterators-and-ownership.md:8 src/bare-metal/no_std.md:28 +#, fuzzy +msgid "`Iterator`" +msgstr "`Iterator`" -#: src/exercises/day-2/luhn.md:9 -msgid "" -"Moving from right to left, double every second digit: for the number `1234`, " -"we double `3` and `1`." -msgstr "" - -#: src/exercises/day-2/luhn.md:12 -msgid "" -"After doubling a digit, sum the digits. So doubling `7` becomes `14` which " -"becomes `5`." -msgstr "" - -#: src/exercises/day-2/luhn.md:15 -msgid "Sum all the undoubled and doubled digits." -msgstr "" - -#: src/exercises/day-2/luhn.md:17 -msgid "The credit card number is valid if the sum ends with `0`." -msgstr "" - -#: src/exercises/day-2/luhn.md:19 +#: src/exercises/day-2/iterators-and-ownership.md:10 #, fuzzy msgid "" -"Copy the following code to and implement the " -"function:" +"Traits are like interfaces: they describe behavior (methods) for a type. The " +"`Iterator` trait simply says that you can call `next` until you get `None` " +"back:" msgstr "" -"Kopieren Sie den folgenden Code nach und " -"implementieren Sie die Funktion:" +"Merkmale sind wie Schnittstellen: Sie beschreiben das Verhalten (Methoden) " +"für einen Typ. Der Das `Iterator`\\-Merkmal sagt einfach, dass Sie `next` " +"aufrufen können, bis Sie `None` zurückbekommen:" -#: src/exercises/day-2/luhn.md:23 +#: src/exercises/day-2/iterators-and-ownership.md:20 +#, fuzzy +msgid "You use this trait like this:" +msgstr "Sie verwenden diese Eigenschaft wie folgt:" + +#: src/exercises/day-2/iterators-and-ownership.md:22 msgid "" -"```rust\n" -"// TODO: remove this when you're done with your implementation.\n" -"#![allow(unused_variables, dead_code)]\n" +"```rust,editable\n" +"fn main() {\n" +" let v: Vec = vec![10, 20, 30];\n" +" let mut iter = v.iter();\n" "\n" -"pub fn luhn(cc_number: &str) -> bool {\n" -" unimplemented!()\n" +" println!(\"v[0]: {:?}\", iter.next());\n" +" println!(\"v[1]: {:?}\", iter.next());\n" +" println!(\"v[2]: {:?}\", iter.next());\n" +" println!(\"No more items: {:?}\", iter.next());\n" "}\n" -"\n" -"#[test]\n" -"fn test_non_digit_cc_number() {\n" -" assert!(!luhn(\"foo\"));\n" -"}\n" -"\n" -"#[test]\n" -"fn test_empty_cc_number() {\n" -" assert!(!luhn(\"\"));\n" -" assert!(!luhn(\" \"));\n" -" assert!(!luhn(\" \"));\n" -" assert!(!luhn(\" \"));\n" -"}\n" -"\n" -"#[test]\n" -"fn test_single_digit_cc_number() {\n" -" assert!(!luhn(\"0\"));\n" -"}\n" -"\n" -"#[test]\n" -"fn test_two_digit_cc_number() {\n" -" assert!(luhn(\" 0 0 \"));\n" -"}\n" -"\n" -"#[test]\n" -"fn test_valid_cc_number() {\n" -" assert!(luhn(\"4263 9826 4026 9299\"));\n" -" assert!(luhn(\"4539 3195 0343 6467\"));\n" -" assert!(luhn(\"7992 7398 713\"));\n" -"}\n" -"\n" -"#[test]\n" -"fn test_invalid_cc_number() {\n" -" assert!(!luhn(\"4223 9826 4026 9299\"));\n" -" assert!(!luhn(\"4539 3195 0343 6476\"));\n" -" assert!(!luhn(\"8273 1232 7352 0569\"));\n" -"}\n" -"\n" -"#[allow(dead_code)]\n" -"fn main() {}\n" "```" msgstr "" +#: src/exercises/day-2/iterators-and-ownership.md:34 +#, fuzzy +msgid "What is the type returned by the iterator? Test your answer here:" +msgstr "Welchen Typ gibt der Iterator zurück? Testen Sie Ihre Antwort hier:" + +#: src/exercises/day-2/iterators-and-ownership.md:36 +msgid "" +"```rust,editable,compile_fail\n" +"fn main() {\n" +" let v: Vec = vec![10, 20, 30];\n" +" let mut iter = v.iter();\n" +"\n" +" let v0: Option<..> = iter.next();\n" +" println!(\"v0: {v0:?}\");\n" +"}\n" +"```" +msgstr "" + +#: src/exercises/day-2/iterators-and-ownership.md:46 +#, fuzzy +msgid "Why is this type used?" +msgstr "Warum wird dieser Typ verwendet?" + +#: src/exercises/day-2/iterators-and-ownership.md:48 +#, fuzzy +msgid "`IntoIterator`" +msgstr "`IntoIterator`" + +#: src/exercises/day-2/iterators-and-ownership.md:50 +#, fuzzy +msgid "" +"The `Iterator` trait tells you how to _iterate_ once you have created an " +"iterator. The related trait `IntoIterator` tells you how to create the " +"iterator:" +msgstr "" +"Die Eigenschaft „Iterator“ sagt Ihnen, wie Sie _iteraten_, sobald Sie eine " +"erstellt haben Iterator. Die zugehörige Eigenschaft `IntoIterator` sagt " +"Ihnen, wie Sie den Iterator erstellen:" + +#: src/exercises/day-2/iterators-and-ownership.md:62 +#, fuzzy +msgid "" +"The syntax here means that every implementation of `IntoIterator` must " +"declare two types:" +msgstr "" +"Die Syntax hier bedeutet, dass jede Implementierung von `IntoIterator` muss " +"deklarieren Sie zwei Arten:" + +#: src/exercises/day-2/iterators-and-ownership.md:65 +#, fuzzy +msgid "`Item`: the type we iterate over, such as `i8`," +msgstr "`Item`: der Typ, über den wir iterieren, wie z. B. `i8`," + +#: src/exercises/day-2/iterators-and-ownership.md:66 +#, fuzzy +msgid "`IntoIter`: the `Iterator` type returned by the `into_iter` method." +msgstr "" +"`IntoIter`: der `Iterator`\\-Typ, der von der `into_iter`\\-Methode " +"zurückgegeben wird." + +#: src/exercises/day-2/iterators-and-ownership.md:68 +#, fuzzy +msgid "" +"Note that `IntoIter` and `Item` are linked: the iterator must have the same " +"`Item` type, which means that it returns `Option`" +msgstr "" +"Beachten Sie, dass „IntoIter“ und „Item“ verknüpft sind: Der Iterator muss " +"dasselbe haben `Item`\\-Typ, was bedeutet, dass es `Option` zurückgibt" + +#: src/exercises/day-2/iterators-and-ownership.md:71 +#, fuzzy +msgid "Like before, what is the type returned by the iterator?" +msgstr "Welchen Typ gibt der Iterator wie zuvor zurück?" + +#: src/exercises/day-2/iterators-and-ownership.md:73 +msgid "" +"```rust,editable,compile_fail\n" +"fn main() {\n" +" let v: Vec = vec![String::from(\"foo\"), String::" +"from(\"bar\")];\n" +" let mut iter = v.into_iter();\n" +"\n" +" let v0: Option<..> = iter.next();\n" +" println!(\"v0: {v0:?}\");\n" +"}\n" +"```" +msgstr "" + +#: src/exercises/day-2/iterators-and-ownership.md:83 +#, fuzzy +msgid "`for` Loops" +msgstr "`for`\\-Schleifen" + +#: src/exercises/day-2/iterators-and-ownership.md:85 +#, fuzzy +msgid "" +"Now that we know both `Iterator` and `IntoIterator`, we can build `for` " +"loops. They call `into_iter()` on an expression and iterates over the " +"resulting iterator:" +msgstr "" +"Jetzt, da wir sowohl „Iterator“ als auch „IntoIterator“ kennen, können wir " +"„for“-Schleifen bauen. Sie rufen `into_iter()` für einen Ausdruck auf und " +"iterieren über das Ergebnis Iterator:" + +#: src/exercises/day-2/iterators-and-ownership.md:89 +msgid "" +"```rust,editable\n" +"fn main() {\n" +" let v: Vec = vec![String::from(\"foo\"), String::" +"from(\"bar\")];\n" +"\n" +" for word in &v {\n" +" println!(\"word: {word}\");\n" +" }\n" +"\n" +" for word in v {\n" +" println!(\"word: {word}\");\n" +" }\n" +"}\n" +"```" +msgstr "" + +#: src/exercises/day-2/iterators-and-ownership.md:103 +#, fuzzy +msgid "What is the type of `word` in each loop?" +msgstr "Was ist die Art von „Wort“ in jeder Schleife?" + +#: src/exercises/day-2/iterators-and-ownership.md:105 +#, fuzzy +msgid "" +"Experiment with the code above and then consult the documentation for [`impl " +"IntoIterator for &Vec`](https://doc.rust-lang.org/std/vec/struct.Vec." +"html#impl-IntoIterator-for-%26'a+Vec%3CT,+A%3E) and [`impl IntoIterator for " +"Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html#impl-IntoIterator-" +"for-Vec%3CT,+A%3E) to check your answers." +msgstr "" +"Experimentieren Sie mit dem obigen Code und konsultieren Sie dann die " +"Dokumentation für [`impl IntoIterator für &Vec`](https://doc.rust-lang." +"org/std/vec/struct.Vec.html#impl-IntoIterator-for-" +"%26%27a%20Vec%3CT%2C%20A%3E) und [`impl IntoIterator for Vec`](https://" +"doc.rust-lang.org/std/vec/struct.Vec.html#impl-IntoIterator-for-" +"Vec%3CT%2C%20A%3E) um Ihre Antworten zu überprüfen." + #: src/exercises/day-2/strings-iterators.md:3 #, fuzzy msgid "" @@ -9412,8 +9218,8 @@ msgstr "" #: src/generics.md:3 #, fuzzy msgid "" -"Rust support generics, which lets you abstract an algorithm (such as " -"sorting) over the types used in the algorithm." +"Rust support generics, which lets you abstract algorithms or data structures " +"(such as sorting or a binary tree) over the types used or stored." msgstr "" "Rust unterstützt Generika, mit denen Sie einen Algorithmus abstrahieren " "können (z. B. Sortieren) über die im Algorithmus verwendeten Typen." @@ -9522,41 +9328,11 @@ msgstr "" "Basierend auf den Aufrufseiten wird generischer Code in nicht generischen " "Code umgewandelt:" -#: src/generics/monomorphization.md:5 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let integer = Some(5);\n" -" let float = Some(5.0);\n" -"}\n" -"```" -msgstr "" - #: src/generics/monomorphization.md:12 #, fuzzy msgid "behaves as if you wrote" msgstr "verhält sich so, als hättest du geschrieben" -#: src/generics/monomorphization.md:14 -msgid "" -"```rust,editable\n" -"enum Option_i32 {\n" -" Some(i32),\n" -" None,\n" -"}\n" -"\n" -"enum Option_f64 {\n" -" Some(f64),\n" -" None,\n" -"}\n" -"\n" -"fn main() {\n" -" let integer = Option_i32::Some(5);\n" -" let float = Option_f64::Some(5.0);\n" -"}\n" -"```" -msgstr "" - #: src/generics/monomorphization.md:31 #, fuzzy msgid "" @@ -9769,11 +9545,17 @@ msgid "" msgstr "" #: src/traits/deriving-traits.md:3 -#, fuzzy -msgid "You can let the compiler derive a number of traits:" -msgstr "Sie können den Compiler eine Reihe von Merkmalen ableiten lassen:" +msgid "" +"Rust derive macros work by automatically generating code that implements the " +"specified traits for a data structure." +msgstr "" #: src/traits/deriving-traits.md:5 +#, fuzzy +msgid "You can let the compiler derive a number of traits as follows:" +msgstr "Sie können den Compiler eine Reihe von Merkmalen ableiten lassen:" + +#: src/traits/deriving-traits.md:7 msgid "" "```rust,editable\n" "#[derive(Debug, Clone, PartialEq, Eq, Default)]\n" @@ -9802,9 +9584,9 @@ msgstr "" msgid "" "```rust,editable\n" "trait Equals {\n" -" fn equal(&self, other: &Self) -> bool;\n" -" fn not_equal(&self, other: &Self) -> bool {\n" -" !self.equal(other)\n" +" fn equals(&self, other: &Self) -> bool;\n" +" fn not_equals(&self, other: &Self) -> bool {\n" +" !self.equals(other)\n" " }\n" "}\n" "\n" @@ -9812,7 +9594,7 @@ msgid "" "struct Centimeter(i16);\n" "\n" "impl Equals for Centimeter {\n" -" fn equal(&self, other: &Centimeter) -> bool {\n" +" fn equals(&self, other: &Centimeter) -> bool {\n" " self.0 == other.0\n" " }\n" "}\n" @@ -9820,8 +9602,8 @@ msgid "" "fn main() {\n" " let a = Centimeter(10);\n" " let b = Centimeter(20);\n" -" println!(\"{a:?} equals {b:?}: {}\", a.equal(&b));\n" -" println!(\"{a:?} not_equals {b:?}: {}\", a.not_equal(&b));\n" +" println!(\"{a:?} equals {b:?}: {}\", a.equals(&b));\n" +" println!(\"{a:?} not_equals {b:?}: {}\", a.not_equals(&b));\n" "}\n" "```" msgstr "" @@ -9834,47 +9616,21 @@ msgid "" msgstr "" #: src/traits/default-methods.md:35 -msgid "Move method `not_equal` to a new trait `NotEqual`." +msgid "Move method `not_equals` to a new trait `NotEquals`." msgstr "" #: src/traits/default-methods.md:37 -msgid "Make `NotEqual` a super trait for `Equal`." -msgstr "" - -#: src/traits/default-methods.md:38 -msgid "" -"```rust,editable,compile_fail\n" -"trait NotEqual: Equals {\n" -" fn not_equal(&self, other: &Self) -> bool {\n" -" !self.equal(other)\n" -" }\n" -"}\n" -"```" +msgid "Make `Equals` a super trait for `NotEquals`." msgstr "" #: src/traits/default-methods.md:46 -msgid "Provide a blanket implementation of `NotEqual` for `Equal`." -msgstr "" - -#: src/traits/default-methods.md:47 -msgid "" -"```rust,editable,compile_fail\n" -"trait NotEqual {\n" -" fn not_equal(&self, other: &Self) -> bool;\n" -"}\n" -"\n" -"impl NotEqual for T where T: Equals {\n" -" fn not_equal(&self, other: &Self) -> bool {\n" -" !self.equal(other)\n" -" }\n" -"}\n" -"```" +msgid "Provide a blanket implementation of `NotEquals` for `Equals`." msgstr "" #: src/traits/default-methods.md:58 msgid "" -"With the blanket implementation, you no longer need `NotEqual` as a super " -"trait for `Equal`." +"With the blanket implementation, you no longer need `Equals` as a super " +"trait for `NotEqual`." msgstr "" #: src/traits/trait-bounds.md:3 @@ -9922,18 +9678,6 @@ msgstr "" msgid "Show a `where` clause, students will encounter it when reading code." msgstr "" -#: src/traits/trait-bounds.md:37 -msgid "" -"```rust,ignore\n" -"fn duplicate(a: T) -> (T, T)\n" -"where\n" -" T: Clone,\n" -"{\n" -" (a.clone(), a.clone())\n" -"}\n" -"```" -msgstr "" - #: src/traits/trait-bounds.md:46 #, fuzzy msgid "It declutters the function signature if you have many parameters." @@ -10172,19 +9916,6 @@ msgid "" msgstr "" "Mit „FromIterator“ können Sie eine Sammlung aus einem „Iterator“ erstellen." -#: src/traits/from-iterator.md:5 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let primes = vec![2, 3, 5, 7];\n" -" let prime_squares = primes\n" -" .into_iter()\n" -" .map(|prime| prime * prime)\n" -" .collect::>();\n" -"}\n" -"```" -msgstr "" - #: src/traits/from-iterator.md:17 #, fuzzy msgid "" @@ -10436,12 +10167,12 @@ msgid "" "}\n" "\n" "fn main() {\n" -" let default_struct: Derived = Default::default();\n" +" let default_struct = Derived::default();\n" " println!(\"{default_struct:#?}\");\n" "\n" " let almost_default_struct = Derived {\n" " y: \"Y is set!\".into(),\n" -" ..Default::default()\n" +" ..Derived::default()\n" " };\n" " println!(\"{almost_default_struct:#?}\");\n" "\n" @@ -10459,7 +10190,7 @@ msgstr "" #: src/traits/default.md:41 msgid "" -"Derived implementation will produce an instance where all fields are set to " +"A derived implementation will produce a value where all fields are set to " "their default values." msgstr "" @@ -10483,6 +10214,13 @@ msgid "" "provides convenience methods that use it." msgstr "" +#: src/traits/default.md:46 +msgid "" +"the `..` syntax is called [struct update syntax](https://doc.rust-lang.org/" +"book/ch05-01-defining-structs.html#creating-instances-from-other-instances-" +"with-struct-update-syntax)" +msgstr "" + #: src/traits/operators.md:1 #, fuzzy msgid "`Add`, `Mul`, ..." @@ -10592,43 +10330,53 @@ msgid "" "\n" "fn main() {\n" " let add_3 = |x| x + 3;\n" -" let mul_5 = |x| x * 5;\n" -"\n" " println!(\"add_3: {}\", apply_with_log(add_3, 10));\n" -" println!(\"mul_5: {}\", apply_with_log(mul_5, 20));\n" +" println!(\"add_3: {}\", apply_with_log(add_3, 20));\n" +"\n" +" let mut v = Vec::new();\n" +" let mut accumulate = |x: i32| {\n" +" v.push(x);\n" +" v.iter().sum::()\n" +" };\n" +" println!(\"accumulate: {}\", apply_with_log(&mut accumulate, 4));\n" +" println!(\"accumulate: {}\", apply_with_log(&mut accumulate, 5));\n" +"\n" +" let multiply_sum = |x| x * v.into_iter().sum::();\n" +" println!(\"multiply_sum: {}\", apply_with_log(multiply_sum, 3));\n" "}\n" "```" msgstr "" -#: src/traits/closures.md:25 +#: src/traits/closures.md:34 #, fuzzy msgid "" -"If you have an `FnOnce`, you may only call it once. It might consume " -"captured values." -msgstr "" -"Wenn Sie ein `FnOnce` haben, können Sie es nur einmal aufrufen. Es kann " -"erfasste Werte verbrauchen." - -#: src/traits/closures.md:27 -#, fuzzy -msgid "" -"An `FnMut` might mutate captured values, so you can call it multiple times " -"but not concurrently." -msgstr "" -"Ein `FnMut` kann erfasste Werte mutieren, sodass Sie es mehrmals, aber nicht " -"gleichzeitig aufrufen können." - -#: src/traits/closures.md:29 -#, fuzzy -msgid "" -"An `Fn` neither consumes nor mutates captured values, or perhaps captures " -"nothing at all, so it can be called multiple times concurrently." +"An `Fn` (e.g. `add_3`) neither consumes nor mutates captured values, or " +"perhaps captures nothing at all. It can be called multiple times " +"concurrently." msgstr "" "Ein „Fn“ verbraucht oder mutiert erfasste Werte nicht oder erfasst " "vielleicht gar nichts, also kann es das mehrmals gleichzeitig aufgerufen " "werden." -#: src/traits/closures.md:32 +#: src/traits/closures.md:37 +#, fuzzy +msgid "" +"An `FnMut` (e.g. `accumulate`) might mutate captured values. You can call it " +"multiple times, but not concurrently." +msgstr "" +"Ein `FnMut` kann erfasste Werte mutieren, sodass Sie es mehrmals, aber nicht " +"gleichzeitig aufrufen können." + +#: src/traits/closures.md:40 +#, fuzzy +msgid "" +"If you have an `FnOnce` (e.g. `multiply_sum`), you may only call it once. It " +"might consume captured values." +msgstr "" +"Wenn Sie ein `FnOnce` haben, können Sie es nur einmal aufrufen. Es kann " +"erfasste Werte verbrauchen." + +#: src/traits/closures.md:43 #, fuzzy msgid "" "`FnMut` is a subtype of `FnOnce`. `Fn` is a subtype of `FnMut` and `FnOnce`. " @@ -10640,10 +10388,31 @@ msgstr "" "verlangt wird, und Sie können ein „Fn“ überall dort verwenden, wo ein " "„FnMut“ oder „FnOnce“ steht ist angesagt." -#: src/traits/closures.md:36 -#, fuzzy -msgid "`move` closures only implement `FnOnce`." -msgstr "`move`\\-Closures implementieren nur `FnOnce`." +#: src/traits/closures.md:47 +msgid "" +"The compiler also infers `Copy` (e.g. for `add_3`) and `Clone` (e.g. " +"`multiply_sum`), depending on what the closure captures." +msgstr "" + +#: src/traits/closures.md:50 +msgid "" +"By default, closures will capture by reference if they can. The `move` " +"keyword makes them capture by value." +msgstr "" + +#: src/traits/closures.md:52 +msgid "" +"```rust,editable\n" +"fn make_greeter(prefix: String) -> impl Fn(&str) {\n" +" return move |name| println!(\"{} {}\", prefix, name)\n" +"}\n" +"\n" +"fn main() {\n" +" let hi = make_greeter(\"Hi\".to_string());\n" +" hi(\"there\");\n" +"}\n" +"```" +msgstr "" #: src/exercises/day-3/morning.md:1 #, fuzzy @@ -10652,11 +10421,17 @@ msgstr "Tag 3: Morgengymnastik" #: src/exercises/day-3/morning.md:3 #, fuzzy -msgid "We will design a classical GUI library traits and trait objects." +msgid "We will design a classical GUI library using traits and trait objects." msgstr "" "Wir werden Traits und Trait-Objekte einer klassischen GUI-Bibliothek " "entwerfen." +#: src/exercises/day-3/morning.md:5 +msgid "" +"We will also look at enum dispatch with an exercise involving points and " +"polygons." +msgstr "" + #: src/exercises/day-3/simple-gui.md:3 #, fuzzy msgid "" @@ -10826,19 +10601,6 @@ msgstr "" msgid "The output of the above program can be something simple like this:" msgstr "Die Ausgabe des obigen Programms kann so einfach sein:" -#: src/exercises/day-3/simple-gui.md:132 -msgid "" -"```text\n" -"========\n" -"Rust GUI Demo 1.23\n" -"========\n" -"\n" -"This is a small text GUI demo.\n" -"\n" -"| Click me! |\n" -"```" -msgstr "" - #: src/exercises/day-3/simple-gui.md:142 #, fuzzy msgid "" @@ -10873,20 +10635,166 @@ msgstr "" "Mit solchen Ausrichtungstricks können Sie beispielsweise eine Ausgabe wie " "diese erzeugen:" -#: src/exercises/day-3/simple-gui.md:158 +#: src/exercises/day-3/points-polygons.md:1 +#, fuzzy +msgid "Polygon Struct" +msgstr "Polygonstruktur" + +#: src/exercises/day-3/points-polygons.md:3 +#, fuzzy msgid "" -"```text\n" -"+--------------------------------+\n" -"| Rust GUI Demo 1.23 |\n" -"+================================+\n" -"| This is a small text GUI demo. |\n" -"| +-----------+ |\n" -"| | Click me! | |\n" -"| +-----------+ |\n" -"+--------------------------------+\n" +"We will create a `Polygon` struct which contain some points. Copy the code " +"below to and fill in the missing methods to " +"make the tests pass:" +msgstr "" +"Wir werden eine \"Polygon\"-Struktur erstellen, die einige Punkte enthält. " +"Kopieren Sie den Code unten zu und füllen Sie " +"die fehlenden Methoden aus, um die Tests bestehen:" + +#: src/exercises/day-3/points-polygons.md:7 +msgid "" +"```rust\n" +"// TODO: remove this when you're done with your implementation.\n" +"#![allow(unused_variables, dead_code)]\n" +"\n" +"pub struct Point {\n" +" // add fields\n" +"}\n" +"\n" +"impl Point {\n" +" // add methods\n" +"}\n" +"\n" +"pub struct Polygon {\n" +" // add fields\n" +"}\n" +"\n" +"impl Polygon {\n" +" // add methods\n" +"}\n" +"\n" +"pub struct Circle {\n" +" // add fields\n" +"}\n" +"\n" +"impl Circle {\n" +" // add methods\n" +"}\n" +"\n" +"pub enum Shape {\n" +" Polygon(Polygon),\n" +" Circle(Circle),\n" +"}\n" +"\n" +"#[cfg(test)]\n" +"mod tests {\n" +" use super::*;\n" +"\n" +" fn round_two_digits(x: f64) -> f64 {\n" +" (x * 100.0).round() / 100.0\n" +" }\n" +"\n" +" #[test]\n" +" fn test_point_magnitude() {\n" +" let p1 = Point::new(12, 13);\n" +" assert_eq!(round_two_digits(p1.magnitude()), 17.69);\n" +" }\n" +"\n" +" #[test]\n" +" fn test_point_dist() {\n" +" let p1 = Point::new(10, 10);\n" +" let p2 = Point::new(14, 13);\n" +" assert_eq!(round_two_digits(p1.dist(p2)), 5.00);\n" +" }\n" +"\n" +" #[test]\n" +" fn test_point_add() {\n" +" let p1 = Point::new(16, 16);\n" +" let p2 = p1 + Point::new(-4, 3);\n" +" assert_eq!(p2, Point::new(12, 19));\n" +" }\n" +"\n" +" #[test]\n" +" fn test_polygon_left_most_point() {\n" +" let p1 = Point::new(12, 13);\n" +" let p2 = Point::new(16, 16);\n" +"\n" +" let mut poly = Polygon::new();\n" +" poly.add_point(p1);\n" +" poly.add_point(p2);\n" +" assert_eq!(poly.left_most_point(), Some(p1));\n" +" }\n" +"\n" +" #[test]\n" +" fn test_polygon_iter() {\n" +" let p1 = Point::new(12, 13);\n" +" let p2 = Point::new(16, 16);\n" +"\n" +" let mut poly = Polygon::new();\n" +" poly.add_point(p1);\n" +" poly.add_point(p2);\n" +"\n" +" let points = poly.iter().cloned().collect::>();\n" +" assert_eq!(points, vec![Point::new(12, 13), Point::new(16, 16)]);\n" +" }\n" +"\n" +" #[test]\n" +" fn test_shape_perimeters() {\n" +" let mut poly = Polygon::new();\n" +" poly.add_point(Point::new(12, 13));\n" +" poly.add_point(Point::new(17, 11));\n" +" poly.add_point(Point::new(16, 16));\n" +" let shapes = vec![\n" +" Shape::from(poly),\n" +" Shape::from(Circle::new(Point::new(10, 20), 5)),\n" +" ];\n" +" let perimeters = shapes\n" +" .iter()\n" +" .map(Shape::perimeter)\n" +" .map(round_two_digits)\n" +" .collect::>();\n" +" assert_eq!(perimeters, vec![15.48, 31.42]);\n" +" }\n" +"}\n" +"\n" +"#[allow(dead_code)]\n" +"fn main() {}\n" "```" msgstr "" +#: src/exercises/day-3/points-polygons.md:117 +#, fuzzy +msgid "" +"Since the method signatures are missing from the problem statements, the key " +"part of the exercise is to specify those correctly. You don't have to modify " +"the tests." +msgstr "" +"Da die Methodensignaturen in den Problembeschreibungen fehlen, ist der " +"Schlüsselteil der Übung ist es, diese richtig anzugeben." + +#: src/exercises/day-3/points-polygons.md:120 +#, fuzzy +msgid "Other interesting parts of the exercise:" +msgstr "Weitere interessante Teile der Übung:" + +#: src/exercises/day-3/points-polygons.md:122 +#, fuzzy +msgid "" +"Derive a `Copy` trait for some structs, as in tests the methods sometimes " +"don't borrow their arguments." +msgstr "" +"Leiten Sie ein `Copy`\\-Merkmal für einige Strukturen ab, da die Methoden in " +"Tests ihre Argumente manchmal nicht ausleihen." + +#: src/exercises/day-3/points-polygons.md:123 +#, fuzzy +msgid "" +"Discover that `Add` trait must be implemented for two objects to be addable " +"via \"+\". Note that we do not discuss generics until Day 3." +msgstr "" +"Entdecken Sie, dass die Eigenschaft „Hinzufügen“ implementiert werden muss, " +"damit zwei Objekte über „+“ hinzugefügt werden können." + #: src/error-handling.md:3 #, fuzzy msgid "Error handling in Rust is done using explicit control flow:" @@ -10958,19 +10866,21 @@ msgid "" "```rust,editable\n" "use std::panic;\n" "\n" -"let result = panic::catch_unwind(|| {\n" -" println!(\"hello!\");\n" -"});\n" -"assert!(result.is_ok());\n" -"\n" -"let result = panic::catch_unwind(|| {\n" -" panic!(\"oh no!\");\n" -"});\n" -"assert!(result.is_err());\n" +"fn main() {\n" +" let result = panic::catch_unwind(|| {\n" +" println!(\"hello!\");\n" +" });\n" +" assert!(result.is_ok());\n" +" \n" +" let result = panic::catch_unwind(|| {\n" +" panic!(\"oh no!\");\n" +" });\n" +" assert!(result.is_err());\n" +"}\n" "```" msgstr "" -#: src/error-handling/panic-unwind.md:19 +#: src/error-handling/panic-unwind.md:21 #, fuzzy msgid "" "This can be useful in servers which should keep running even if a single " @@ -10979,7 +10889,7 @@ msgstr "" "Dies kann bei Servern nützlich sein, die auch bei einem einzigen " "weiterlaufen sollen Anfrage stürzt ab." -#: src/error-handling/panic-unwind.md:21 +#: src/error-handling/panic-unwind.md:23 #, fuzzy msgid "This does not work if `panic = 'abort'` is set in your `Cargo.toml`." msgstr "" @@ -11003,11 +10913,11 @@ msgstr "" #: src/error-handling/result.md:6 msgid "" "```rust,editable\n" -"use std::fs::File;\n" +"use std::fs;\n" "use std::io::Read;\n" "\n" "fn main() {\n" -" let file = File::open(\"diary.txt\");\n" +" let file = fs::File::open(\"diary.txt\");\n" " match file {\n" " Ok(mut file) => {\n" " let mut contents = String::new();\n" @@ -11061,39 +10971,22 @@ msgstr "" "Der Try-Operator `?` wird verwendet, um Fehler an den Aufrufer " "zurückzugeben. Es lässt dich drehen das gemeine" -#: src/error-handling/try-operator.md:6 -msgid "" -"```rust,ignore\n" -"match some_expression {\n" -" Ok(value) => value,\n" -" Err(err) => return Err(err),\n" -"}\n" -"```" -msgstr "" - #: src/error-handling/try-operator.md:13 #, fuzzy msgid "into the much simpler" msgstr "ins viel einfachere" -#: src/error-handling/try-operator.md:15 -msgid "" -"```rust,ignore\n" -"some_expression?\n" -"```" -msgstr "" - #: src/error-handling/try-operator.md:19 #, fuzzy -msgid "We can use this to simplify our error handing code:" +msgid "We can use this to simplify our error handling code:" msgstr "" "Wir können dies verwenden, um unseren Fehlerbehandlungscode zu vereinfachen:" #: src/error-handling/try-operator.md:21 msgid "" "```rust,editable\n" -"use std::fs;\n" -"use std::io::{self, Read};\n" +"use std::{fs, io};\n" +"use std::io::Read;\n" "\n" "fn read_username(path: &str) -> Result {\n" " let username_file_result = fs::File::open(path);\n" @@ -11134,6 +11027,24 @@ msgstr "" "Verwenden Sie den `fs::write`\\-Aufruf, um die verschiedenen Szenarien zu " "testen: keine Datei, leere Datei, Datei mit Benutzername." +#: src/error-handling/try-operator.md:52 +msgid "" +"The return type of the function has to be compatible with the nested " +"functions it calls. For instance, a function returning a `Result` " +"can only apply the `?` operator on a function returning a `Result`. It cannot apply the `?` operator on a function returning an " +"`Option` or `Result` unless `OtherErr` implements " +"`From`. Reciprocally, a function returning an `Option` can only " +"apply the `?` operator on a function returning an `Option`." +msgstr "" + +#: src/error-handling/try-operator.md:57 +msgid "" +"You can convert incompatible types into one another with the different " +"`Option` and `Result` methods such as `Option::ok_or`, `Result::ok`, " +"`Result::err`." +msgstr "" + #: src/error-handling/converting-error-types.md:3 #, fuzzy msgid "" @@ -11143,28 +11054,11 @@ msgstr "" "Die effektive Erweiterung von „?“ ist etwas komplizierter als zuvor " "angedeutet:" -#: src/error-handling/converting-error-types.md:5 -msgid "" -"```rust,ignore\n" -"expression?\n" -"```" -msgstr "" - #: src/error-handling/converting-error-types.md:9 #, fuzzy msgid "works the same as" msgstr "funktioniert genauso wie" -#: src/error-handling/converting-error-types.md:11 -msgid "" -"```rust,ignore\n" -"match expression {\n" -" Ok(value) => value,\n" -" Err(err) => return Err(From::from(err)),\n" -"}\n" -"```" -msgstr "" - #: src/error-handling/converting-error-types.md:18 #, fuzzy msgid "" @@ -11224,13 +11118,19 @@ msgid "" msgstr "" #: src/error-handling/converting-error-types-example.md:55 +msgid "" +"It is good practice for all error types that don't need to be `no_std` to " +"implement `std::error::Error`, which requires `Debug` and `Display`. The " +"`Error` crate for `core` is only available in [nightly](https://github.com/" +"rust-lang/rust/issues/103765), so not fully `no_std` compatible yet." +msgstr "" + +#: src/error-handling/converting-error-types-example.md:57 #, fuzzy msgid "" -"It is good practice for all error types to implement `std::error::Error`, " -"which requires `Debug` and `Display`. It's generally helpful for them to " -"implement `Clone` and `Eq` too where possible, to make life easier for tests " -"and consumers of your library. In this case we can't easily do so, because " -"`io::Error` doesn't implement them." +"It's generally helpful for them to implement `Clone` and `Eq` too where " +"possible, to make life easier for tests and consumers of your library. In " +"this case we can't easily do so, because `io::Error` doesn't implement them." msgstr "" "Es ist eine gute Praxis für alle Fehlertypen, `std::error::Error` zu " "implementieren, was `Debug` und erfordert \"Anzeigen\". Es ist im " @@ -11264,7 +11164,7 @@ msgid "" "}\n" "\n" "fn read_username(path: &str) -> Result {\n" -" let mut username = String::with_capacity(100);\n" +" let mut username = String::new();\n" " fs::File::open(path)?.read_to_string(&mut username)?;\n" " if username.is_empty() {\n" " return Err(ReadUsernameError::EmptyUsername(String::from(path)));\n" @@ -11315,7 +11215,7 @@ msgstr "" #: src/error-handling/dynamic-errors.md:6 msgid "" "```rust,editable,compile_fail\n" -"use std::fs::{self, File};\n" +"use std::fs;\n" "use std::io::Read;\n" "use thiserror::Error;\n" "use std::error::Error;\n" @@ -11325,8 +11225,8 @@ msgid "" "struct EmptyUsernameError(String);\n" "\n" "fn read_username(path: &str) -> Result> {\n" -" let mut username = String::with_capacity(100);\n" -" File::open(path)?.read_to_string(&mut username)?;\n" +" let mut username = String::new();\n" +" fs::File::open(path)?.read_to_string(&mut username)?;\n" " if username.is_empty() {\n" " return Err(EmptyUsernameError(String::from(path)).into());\n" " }\n" @@ -11582,18 +11482,6 @@ msgstr "" msgid "Create a `.rs` file under `tests/`:" msgstr "Erstellen Sie eine `.rs`\\-Datei unter `tests/`:" -#: src/testing/integration-tests.md:7 -msgid "" -"```rust,ignore\n" -"use my_library::init;\n" -"\n" -"#[test]\n" -"fn test_init() {\n" -" assert!(init().is_ok());\n" -"}\n" -"```" -msgstr "" - #: src/testing/integration-tests.md:16 #, fuzzy msgid "These tests only have access to the public API of your crate." @@ -12146,7 +12034,19 @@ msgstr "" "Lassen Sie uns einen sicheren Wrapper zum Lesen von Verzeichnisinhalten " "erstellen!" -#: src/exercises/day-3/afternoon.md:7 +#: src/exercises/day-3/afternoon.md:5 +msgid "" +"For this exercise, we suggest using a local dev environment instead of the " +"Playground. This will allow you to run your binary on your own machine." +msgstr "" + +#: src/exercises/day-3/afternoon.md:8 +msgid "" +"To get started, follow the [running locally](../../cargo/running-locally.md) " +"instructions." +msgstr "" + +#: src/exercises/day-3/afternoon.md:14 #, fuzzy msgid "" "After looking at the exercise, you can look at the [solution](solutions-" @@ -12306,7 +12206,7 @@ msgid "" "mod ffi {\n" " use std::os::raw::{c_char, c_int};\n" " #[cfg(not(target_os = \"macos\"))]\n" -" use std::os::raw::{c_long, c_ulong, c_ushort};\n" +" use std::os::raw::{c_long, c_ulong, c_ushort, c_uchar};\n" "\n" " // Opaque type. See https://doc.rust-lang.org/nomicon/ffi.html.\n" " #[repr(C)]\n" @@ -12316,23 +12216,25 @@ msgid "" "PhantomPinned)>,\n" " }\n" "\n" -" // Layout as per readdir(3) and definitions in /usr/include/x86_64-linux-" -"gnu.\n" +" // Layout according to the Linux man page for readdir(3), where ino_t " +"and\n" +" // off_t are resolved according to the definitions in\n" +" // /usr/include/x86_64-linux-gnu/{sys/types.h, bits/typesizes.h}.\n" " #[cfg(not(target_os = \"macos\"))]\n" " #[repr(C)]\n" " pub struct dirent {\n" -" pub d_ino: c_long,\n" -" pub d_off: c_ulong,\n" +" pub d_ino: c_ulong,\n" +" pub d_off: c_long,\n" " pub d_reclen: c_ushort,\n" -" pub d_type: c_char,\n" +" pub d_type: c_uchar,\n" " pub d_name: [c_char; 256],\n" " }\n" "\n" -" // Layout as per man entry for dirent\n" -" #[cfg(target_os = \"macos\")]\n" +" // Layout according to the macOS man page for dir(5).\n" +" #[cfg(all(target_os = \"macos\"))]\n" " #[repr(C)]\n" " pub struct dirent {\n" -" pub d_ino: u64,\n" +" pub d_fileno: u64,\n" " pub d_seekoff: u64,\n" " pub d_reclen: u16,\n" " pub d_namlen: u16,\n" @@ -12342,7 +12244,22 @@ msgid "" "\n" " extern \"C\" {\n" " pub fn opendir(s: *const c_char) -> *mut DIR;\n" +"\n" +" #[cfg(not(all(target_os = \"macos\", target_arch = \"x86_64\")))]\n" " pub fn readdir(s: *mut DIR) -> *const dirent;\n" +"\n" +" // See https://github.com/rust-lang/libc/issues/414 and the section " +"on\n" +" // _DARWIN_FEATURE_64_BIT_INODE in the macOS man page for stat(2).\n" +" //\n" +" // \"Platforms that existed before these updates were available\" " +"refers\n" +" // to macOS (as opposed to iOS / wearOS / etc.) on Intel and " +"PowerPC.\n" +" #[cfg(all(target_os = \"macos\", target_arch = \"x86_64\"))]\n" +" #[link_name = \"readdir$INODE64\"]\n" +" pub fn readdir(s: *mut DIR) -> *const dirent;\n" +"\n" " pub fn closedir(s: *mut DIR) -> c_int;\n" " }\n" "}\n" @@ -12427,15 +12344,6 @@ msgstr "" "Stell sicher dass du hast Greifen Sie auf eines zu oder erstellen Sie ein " "neues mit:" -#: src/android/setup.md:6 -msgid "" -"```shell\n" -"$ source build/envsetup.sh\n" -"$ lunch aosp_cf_x86_64_phone-userdebug\n" -"$ acloud create\n" -"```" -msgstr "" - #: src/android/setup.md:12 #, fuzzy msgid "" @@ -12622,10 +12530,9 @@ msgstr "Sie können die Binärdatei jetzt erstellen, pushen und ausführen:" #: src/android/build-rules/binary.md:29 msgid "" "```shell\n" -"$ m hello_rust\n" -"$ adb push \"$ANDROID_PRODUCT_OUT/system/bin/hello_rust /data/local/tmp\"\n" -"$ adb shell /data/local/tmp/hello_rust\n" -"Hello from Rust!\n" +"m hello_rust\n" +"adb push \"$ANDROID_PRODUCT_OUT/system/bin/hello_rust /data/local/tmp\"\n" +"adb shell /data/local/tmp/hello_rust\n" "```" msgstr "" @@ -12724,12 +12631,10 @@ msgstr "Sie erstellen, pushen und führen die Binärdatei wie zuvor aus:" #: src/android/build-rules/library.md:61 msgid "" "```shell\n" -"$ m hello_rust_with_dep\n" -"$ adb push \"$ANDROID_PRODUCT_OUT/system/bin/hello_rust_with_dep /data/local/" +"m hello_rust_with_dep\n" +"adb push \"$ANDROID_PRODUCT_OUT/system/bin/hello_rust_with_dep /data/local/" "tmp\"\n" -"$ adb shell /data/local/tmp/hello_rust_with_dep\n" -"Hello Bob, it is very\n" -"nice to meet you!\n" +"adb shell /data/local/tmp/hello_rust_with_dep\n" "```" msgstr "" @@ -12769,19 +12674,6 @@ msgid "" msgstr "" "_birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl_:" -#: src/android/aidl/interface.md:7 -msgid "" -"```java\n" -"package com.example.birthdayservice;\n" -"\n" -"/** Birthday service interface. */\n" -"interface IBirthdayService {\n" -" /** Generate a Happy Birthday message. */\n" -" String wishHappyBirthday(String name, int years);\n" -"}\n" -"```" -msgstr "" - #: src/android/aidl/interface.md:17 #, fuzzy msgid "_birthday_service/aidl/Android.bp_:" @@ -12941,10 +12833,10 @@ msgstr "Wir können den Dienst jetzt erstellen, pushen und starten:" #: src/android/aidl/deploy.md:5 msgid "" "```shell\n" -"$ m birthday_server\n" -"$ adb push \"$ANDROID_PRODUCT_OUT/system/bin/birthday_server /data/local/" +"m birthday_server\n" +"adb push \"$ANDROID_PRODUCT_OUT/system/bin/birthday_server /data/local/" "tmp\"\n" -"$ adb shell /data/local/tmp/birthday_server\n" +"adb shell /data/local/tmp/birthday_server\n" "```" msgstr "" @@ -12954,35 +12846,11 @@ msgid "In another terminal, check that the service runs:" msgstr "" "Überprüfen Sie in einem anderen Terminal, ob der Dienst ausgeführt wird:" -#: src/android/aidl/deploy.md:13 -msgid "" -"```shell\n" -"$ adb shell service check birthdayservice\n" -"Service birthdayservice: found\n" -"```" -msgstr "" - -#: src/android/aidl/deploy.md:18 +#: src/android/aidl/deploy.md:21 #, fuzzy msgid "You can also call the service with `service call`:" msgstr "Sie können den Service auch mit `Service Call` aufrufen:" -#: src/android/aidl/deploy.md:20 -msgid "" -"```shell\n" -"$ $ adb shell service call birthdayservice 1 s16 Bob i32 24\n" -"Result: Parcel(\n" -" 0x00000000: 00000000 00000036 00610048 00700070 '....6...H.a.p.p.'\n" -" 0x00000010: 00200079 00690042 00740072 00640068 'y. .B.i.r.t.h.d.'\n" -" 0x00000020: 00790061 00420020 0062006f 0020002c 'a.y. .B.o.b.,. .'\n" -" 0x00000030: 006f0063 0067006e 00610072 00750074 'c.o.n.g.r.a.t.u.'\n" -" 0x00000040: 0061006c 00690074 006e006f 00200073 'l.a.t.i.o.n.s. .'\n" -" 0x00000050: 00690077 00680074 00740020 00650068 'w.i.t.h. .t.h.e.'\n" -" 0x00000060: 00320020 00200034 00650079 00720061 ' .2.4. .y.e.a.r.'\n" -" 0x00000070: 00210073 00000000 's.!..... ')\n" -"```" -msgstr "" - #: src/android/aidl/client.md:1 #, fuzzy msgid "AIDL Client" @@ -13064,11 +12932,10 @@ msgstr "Erstellen, pushen und führen Sie den Client auf Ihrem Gerät aus:" #: src/android/aidl/client.md:56 msgid "" "```shell\n" -"$ m birthday_client\n" -"$ adb push \"$ANDROID_PRODUCT_OUT/system/bin/birthday_client /data/local/" +"m birthday_client\n" +"adb push \"$ANDROID_PRODUCT_OUT/system/bin/birthday_client /data/local/" "tmp\"\n" -"$ adb shell /data/local/tmp/birthday_client Charlie 60\n" -"Happy Birthday Charlie, congratulations with the 60 years!\n" +"adb shell /data/local/tmp/birthday_client Charlie 60\n" "```" msgstr "" @@ -13081,19 +12948,6 @@ msgstr "" "Lassen Sie uns die API um mehr Funktionalität erweitern: Wir möchten, dass " "Kunden a angeben Liste der Zeilen für die Geburtstagskarte:" -#: src/android/aidl/changing.md:6 -msgid "" -"```java\n" -"package com.example.birthdayservice;\n" -"\n" -"/** Birthday service interface. */\n" -"interface IBirthdayService {\n" -" /** Generate a Happy Birthday message. */\n" -" String wishHappyBirthday(String name, int years, in String[] text);\n" -"}\n" -"```" -msgstr "" - #: src/android/logging.md:3 #, fuzzy msgid "" @@ -13161,10 +13015,10 @@ msgstr "" #: src/android/logging.md:44 msgid "" "```shell\n" -"$ m hello_rust_logs\n" -"$ adb push \"$ANDROID_PRODUCT_OUT/system/bin/hello_rust_logs /data/local/" +"m hello_rust_logs\n" +"adb push \"$ANDROID_PRODUCT_OUT/system/bin/hello_rust_logs /data/local/" "tmp\"\n" -"$ adb shell /data/local/tmp/hello_rust_logs\n" +"adb shell /data/local/tmp/hello_rust_logs\n" "```" msgstr "" @@ -13173,18 +13027,6 @@ msgstr "" msgid "The logs show up in `adb logcat`:" msgstr "Die Protokolle werden in `adb logcat` angezeigt:" -#: src/android/logging.md:52 -msgid "" -"```shell\n" -"$ adb logcat -s rust\n" -"09-08 08:38:32.454 2420 2420 D rust: hello_rust_logs: Starting program.\n" -"09-08 08:38:32.454 2420 2420 I rust: hello_rust_logs: Things are going " -"fine.\n" -"09-08 08:38:32.454 2420 2420 E rust: hello_rust_logs: Something went " -"wrong!\n" -"```" -msgstr "" - #: src/android/interoperability.md:3 #, fuzzy msgid "" @@ -13295,18 +13137,6 @@ msgstr "Erstellen Sie zunächst eine kleine C-Bibliothek:" msgid "_interoperability/bindgen/libbirthday.h_:" msgstr "_interoperability/bindgen/libbirthday.h_:" -#: src/android/interoperability/with-c/bindgen.md:10 -msgid "" -"```c\n" -"typedef struct card {\n" -" const char* name;\n" -" int years;\n" -"} card;\n" -"\n" -"void print_card(const card* card);\n" -"```" -msgstr "" - #: src/android/interoperability/with-c/bindgen.md:19 #, fuzzy msgid "_interoperability/bindgen/libbirthday.c_:" @@ -13434,10 +13264,10 @@ msgstr "" #: src/android/interoperability/with-c/bindgen.md:100 msgid "" "```shell\n" -"$ m print_birthday_card\n" -"$ adb push \"$ANDROID_PRODUCT_OUT/system/bin/print_birthday_card /data/local/" +"m print_birthday_card\n" +"adb push \"$ANDROID_PRODUCT_OUT/system/bin/print_birthday_card /data/local/" "tmp\"\n" -"$ adb shell /data/local/tmp/print_birthday_card\n" +"adb shell /data/local/tmp/print_birthday_card\n" "```" msgstr "" @@ -13463,13 +13293,6 @@ msgid "" "```" msgstr "" -#: src/android/interoperability/with-c/bindgen.md:122 -msgid "" -"```shell\n" -"$ atest libbirthday_bindgen_test\n" -"```" -msgstr "" - #: src/android/interoperability/with-c/rust.md:1 #, fuzzy msgid "Calling Rust" @@ -13583,10 +13406,10 @@ msgstr "" #: src/android/interoperability/with-c/rust.md:75 msgid "" "```shell\n" -"$ m analyze_numbers\n" -"$ adb push \"$ANDROID_PRODUCT_OUT/system/bin/analyze_numbers /data/local/" +"m analyze_numbers\n" +"adb push \"$ANDROID_PRODUCT_OUT/system/bin/analyze_numbers /data/local/" "tmp\"\n" -"$ adb shell /data/local/tmp/analyze_numbers\n" +"adb shell /data/local/tmp/analyze_numbers\n" "```" msgstr "" @@ -13625,6 +13448,42 @@ msgstr "" "Ein vollständiges Beispiel für die Verwendung finden Sie im \\[CXX-" "Tutorial\\] [2](https://cxx.rs/tutorial.html)." +#: src/android/interoperability/cpp.md:14 +msgid "" +"At this point, the instructor should switch to the [CXX tutorial](https://" +"cxx.rs/tutorial.html)." +msgstr "" + +#: src/android/interoperability/cpp.md:16 +msgid "Walk the students through the tutorial step by step." +msgstr "" + +#: src/android/interoperability/cpp.md:18 +msgid "" +"Highlight how CXX presents a clean interface without unsafe code in _both " +"languages_." +msgstr "" + +#: src/android/interoperability/cpp.md:20 +msgid "" +"Show the correspondence between [Rust and C++ types](https://cxx.rs/bindings." +"html):" +msgstr "" + +#: src/android/interoperability/cpp.md:22 +msgid "" +"Explain how a Rust `String` cannot map to a C++ `std::string` (the latter " +"does not uphold the UTF-8 invariant). Show that despite being different " +"types, `rust::String` in C++ can be easily constructed from a C++ `std::" +"string`, making it very ergonomic to use." +msgstr "" + +#: src/android/interoperability/cpp.md:28 +msgid "" +"Explain that a Rust function returning `Result` becomes a function " +"which throws a `E` exception in C++ (and vice versa)." +msgstr "" + #: src/android/interoperability/java.md:1 #, fuzzy msgid "Interoperability with Java" @@ -13740,15 +13599,6 @@ msgstr "" "Schließlich können Sie die Binärdatei erstellen, synchronisieren und " "ausführen:" -#: src/android/interoperability/java.md:75 -msgid "" -"```shell\n" -"$ m helloworld_jni\n" -"$ adb sync # requires adb root && adb remount\n" -"$ adb shell /system/bin/helloworld_jni\n" -"```" -msgstr "" - #: src/exercises/android/morning.md:3 #, fuzzy msgid "" @@ -13829,18 +13679,6 @@ msgid "" "To get started, install some tools we'll need later. On gLinux or Debian:" msgstr "" -#: src/bare-metal.md:22 -msgid "" -"```bash\n" -"sudo apt install gcc-aarch64-linux-gnu gdb-multiarch libudev-dev picocom pkg-" -"config qemu-system-arm\n" -"rustup update\n" -"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n" -"rustup component add llvm-tools-preview\n" -"cargo install cargo-binutils cargo-embed\n" -"```" -msgstr "" - #: src/bare-metal.md:30 msgid "" "And give users in the `plugdev` group access to the micro:bit programmer:" @@ -13860,19 +13698,6 @@ msgstr "" msgid "On MacOS:" msgstr "" -#: src/bare-metal.md:40 -msgid "" -"```bash\n" -"xcode-select --install\n" -"brew install gdb picocom qemu\n" -"brew install --cask gcc-aarch64-embedded\n" -"rustup update\n" -"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n" -"rustup component add llvm-tools-preview\n" -"cargo install cargo-binutils cargo-embed\n" -"```" -msgstr "" - #: src/bare-metal/no_std.md:1 msgid "`no_std`" msgstr "" @@ -13985,21 +13810,6 @@ msgstr "" msgid "A minimal `no_std` program" msgstr "" -#: src/bare-metal/minimal.md:3 -msgid "" -"```rust,editable,compile_fail\n" -"#![no_main]\n" -"#![no_std]\n" -"\n" -"use core::panic::PanicInfo;\n" -"\n" -"#[panic_handler]\n" -"fn panic(_panic: &PanicInfo) -> ! {\n" -" loop {}\n" -"}\n" -"```" -msgstr "" - #: src/bare-metal/minimal.md:17 msgid "This will compile to an empty binary." msgstr "" @@ -14102,25 +13912,6 @@ msgid "" "Cortex M microcontrollers." msgstr "" -#: src/bare-metal/microcontrollers.md:5 -msgid "" -"```rust,editable,compile_fail\n" -"#![no_main]\n" -"#![no_std]\n" -"\n" -"extern crate panic_halt as _;\n" -"\n" -"mod interrupts;\n" -"\n" -"use cortex_m_rt::entry;\n" -"\n" -"#[entry]\n" -"fn main() -> ! {\n" -" loop {}\n" -"}\n" -"```" -msgstr "" - #: src/bare-metal/microcontrollers.md:21 msgid "" "Next we'll look at how to access peripherals, with increasing levels of " @@ -14221,13 +14012,6 @@ msgstr "" msgid "Run the example with:" msgstr "" -#: src/bare-metal/microcontrollers/mmio.md:68 -msgid "" -"```sh\n" -"cargo embed --bin mmio\n" -"```" -msgstr "" - #: src/bare-metal/microcontrollers/pacs.md:1 msgid "Peripheral Access Crates" msgstr "" @@ -14311,13 +14095,6 @@ msgid "" "pac -- -d --no-show-raw-insn` to see the resulting binary." msgstr "" -#: src/bare-metal/microcontrollers/pacs.md:61 -msgid "" -"```sh\n" -"cargo embed --bin pac\n" -"```" -msgstr "" - #: src/bare-metal/microcontrollers/hals.md:1 msgid "HAL crates" msgstr "" @@ -14374,13 +14151,6 @@ msgid "" "STM32, GD32, nRF, NXP, MSP430, AVR and PIC microcontrollers." msgstr "" -#: src/bare-metal/microcontrollers/hals.md:45 -msgid "" -"```sh\n" -"cargo embed --bin hal\n" -"```" -msgstr "" - #: src/bare-metal/microcontrollers/board-support.md:1 #, fuzzy msgid "Board support crates" @@ -14392,30 +14162,6 @@ msgid "" "board for convenience." msgstr "" -#: src/bare-metal/microcontrollers/board-support.md:5 -msgid "" -"```rust,editable,compile_fail\n" -"#![no_main]\n" -"#![no_std]\n" -"\n" -"extern crate panic_halt as _;\n" -"\n" -"use cortex_m_rt::entry;\n" -"use microbit::hal::prelude::*;\n" -"use microbit::Board;\n" -"\n" -"#[entry]\n" -"fn main() -> ! {\n" -" let mut board = Board::take().unwrap();\n" -"\n" -" board.display_pins.col1.set_low().unwrap();\n" -" board.display_pins.row1.set_high().unwrap();\n" -"\n" -" loop {}\n" -"}\n" -"```" -msgstr "" - #: src/bare-metal/microcontrollers/board-support.md:28 msgid "" "In this case the board support crate is just providing more useful names, " @@ -14432,13 +14178,6 @@ msgstr "" msgid "`microbit-v2` includes a simple driver for the LED matrix." msgstr "" -#: src/bare-metal/microcontrollers/board-support.md:36 -msgid "" -"```sh\n" -"cargo embed --bin board_support\n" -"```" -msgstr "" - #: src/bare-metal/microcontrollers/type-state.md:1 msgid "The type state pattern" msgstr "" @@ -14670,13 +14409,6 @@ msgstr "" msgid "In one terminal under `src/bare-metal/microcontrollers/examples/`:" msgstr "" -#: src/bare-metal/microcontrollers/debugging.md:15 -msgid "" -"```sh\n" -"cargo embed --bin board_support debug\n" -"```" -msgstr "" - #: src/bare-metal/microcontrollers/debugging.md:19 #, fuzzy msgid "In another terminal in the same directory:" @@ -14695,18 +14427,6 @@ msgstr "" msgid "In GDB, try running:" msgstr "" -#: src/bare-metal/microcontrollers/debugging.md:29 -msgid "" -"```gdb\n" -"b src/bin/board_support.rs:29\n" -"b src/bin/board_support.rs:30\n" -"b src/bin/board_support.rs:32\n" -"c\n" -"c\n" -"c\n" -"```" -msgstr "" - #: src/bare-metal/microcontrollers/other-projects.md:1 #: src/bare-metal/aps/other-projects.md:1 msgid "Other projects" @@ -14956,25 +14676,11 @@ msgstr "" msgid "See the serial output on Linux with:" msgstr "" -#: src/exercises/bare-metal/compass.md:114 -msgid "" -"```sh\n" -"picocom --baud 115200 --imap lfcrlf /dev/ttyACM0\n" -"```" -msgstr "" - #: src/exercises/bare-metal/compass.md:118 msgid "" "Or on Mac OS something like (the device name may be slightly different):" msgstr "" -#: src/exercises/bare-metal/compass.md:120 -msgid "" -"```sh\n" -"picocom --baud 115200 --imap lfcrlf /dev/tty.usbmodem14502\n" -"```" -msgstr "" - #: src/exercises/bare-metal/compass.md:124 msgid "Use Ctrl+A Ctrl+Q to quit picocom." msgstr "" @@ -15005,6 +14711,154 @@ msgid "" "hardware, but is designed purely for virtual machines." msgstr "" +#: src/bare-metal/aps/entry-point.md:3 +msgid "" +"Before we can start running Rust code, we need to do some initialisation." +msgstr "" + +#: src/bare-metal/aps/entry-point.md:5 +msgid "" +"```armasm\n" +".section .init.entry, \"ax\"\n" +".global entry\n" +"entry:\n" +" /*\n" +" * Load and apply the memory management configuration, ready to enable " +"MMU and\n" +" * caches.\n" +" */\n" +" adrp x30, idmap\n" +" msr ttbr0_el1, x30\n" +"\n" +" mov_i x30, .Lmairval\n" +" msr mair_el1, x30\n" +"\n" +" mov_i x30, .Ltcrval\n" +" /* Copy the supported PA range into TCR_EL1.IPS. */\n" +" mrs x29, id_aa64mmfr0_el1\n" +" bfi x30, x29, #32, #4\n" +"\n" +" msr tcr_el1, x30\n" +"\n" +" mov_i x30, .Lsctlrval\n" +"\n" +" /*\n" +" * Ensure everything before this point has completed, then invalidate " +"any\n" +" * potentially stale local TLB entries before they start being used.\n" +" */\n" +" isb\n" +" tlbi vmalle1\n" +" ic iallu\n" +" dsb nsh\n" +" isb\n" +"\n" +" /*\n" +" * Configure sctlr_el1 to enable MMU and cache and don't proceed until " +"this\n" +" * has completed.\n" +" */\n" +" msr sctlr_el1, x30\n" +" isb\n" +"\n" +" /* Disable trapping floating point access in EL1. */\n" +" mrs x30, cpacr_el1\n" +" orr x30, x30, #(0x3 << 20)\n" +" msr cpacr_el1, x30\n" +" isb\n" +"\n" +" /* Zero out the bss section. */\n" +" adr_l x29, bss_begin\n" +" adr_l x30, bss_end\n" +"0: cmp x29, x30\n" +" b.hs 1f\n" +" stp xzr, xzr, [x29], #16\n" +" b 0b\n" +"\n" +"1: /* Prepare the stack. */\n" +" adr_l x30, boot_stack_end\n" +" mov sp, x30\n" +"\n" +" /* Set up exception vector. */\n" +" adr x30, vector_table_el1\n" +" msr vbar_el1, x30\n" +"\n" +" /* Call into Rust code. */\n" +" bl main\n" +"\n" +" /* Loop forever waiting for interrupts. */\n" +"2: wfi\n" +" b 2b\n" +"```" +msgstr "" + +#: src/bare-metal/aps/entry-point.md:77 +msgid "" +"This is the same as it would be for C: initialising the processor state, " +"zeroing the BSS, and setting up the stack pointer." +msgstr "" + +#: src/bare-metal/aps/entry-point.md:79 +msgid "" +"The BSS (block starting symbol, for historical reasons) is the part of the " +"object file which containing statically allocated variables which are " +"initialised to zero. They are omitted from the image, to avoid wasting space " +"on zeroes. The compiler assumes that the loader will take care of zeroing " +"them." +msgstr "" + +#: src/bare-metal/aps/entry-point.md:83 +msgid "" +"The BSS may already be zeroed, depending on how memory is initialised and " +"the image is loaded, but we zero it to be sure." +msgstr "" + +#: src/bare-metal/aps/entry-point.md:85 +msgid "" +"We need to enable the MMU and cache before reading or writing any memory. If " +"we don't:" +msgstr "" + +#: src/bare-metal/aps/entry-point.md:86 +msgid "" +"Unaligned accesses will fault. We build the Rust code for the `aarch64-" +"unknown-none` target which sets `+strict-align` to prevent the compiler " +"generating unaligned accesses, so it should be fine in this case, but this " +"is not necessarily the case in general." +msgstr "" + +#: src/bare-metal/aps/entry-point.md:89 +msgid "" +"If it were running in a VM, this can lead to cache coherency issues. The " +"problem is that the VM is accessing memory directly with the cache disabled, " +"while the host has cacheable aliases to the same memory. Even if the host " +"doesn't explicitly access the memory, speculative accesses can lead to cache " +"fills, and then changes from one or the other will get lost when the cache " +"is cleaned or the VM enables the cache. (Cache is keyed by physical address, " +"not VA or IPA.)" +msgstr "" + +#: src/bare-metal/aps/entry-point.md:94 +msgid "" +"For simplicity, we just use a hardcoded pagetable (see `idmap.S`) which " +"identity maps the first 1 GiB of address space for devices, the next 1 GiB " +"for DRAM, and another 1 GiB higher up for more devices. This matches the " +"memory layout that QEMU uses." +msgstr "" + +#: src/bare-metal/aps/entry-point.md:97 +msgid "" +"We also set up the exception vector (`vbar_el1`), which we'll see more about " +"later." +msgstr "" + +#: src/bare-metal/aps/entry-point.md:98 +msgid "" +"All examples this afternoon assume we will be running at exception level 1 " +"(EL1). If you need to run at a different exception level you'll need to " +"modify `entry.S` accordingly." +msgstr "" + #: src/bare-metal/aps/inline-assembly.md:1 msgid "Inline assembly" msgstr "" @@ -15506,43 +15360,6 @@ msgid "" "We can use a struct to represent the memory layout of the UART's registers." msgstr "" -#: src/bare-metal/aps/better-uart/registers.md:5 -msgid "" -"```rust,editable,compile_fail\n" -"#[repr(C, align(4))]\n" -"struct Registers {\n" -" dr: u16,\n" -" _reserved0: [u8; 2],\n" -" rsr: ReceiveStatus,\n" -" _reserved1: [u8; 19],\n" -" fr: Flags,\n" -" _reserved2: [u8; 6],\n" -" ilpr: u8,\n" -" _reserved3: [u8; 3],\n" -" ibrd: u16,\n" -" _reserved4: [u8; 2],\n" -" fbrd: u8,\n" -" _reserved5: [u8; 3],\n" -" lcr_h: u8,\n" -" _reserved6: [u8; 3],\n" -" cr: u16,\n" -" _reserved7: [u8; 3],\n" -" ifls: u8,\n" -" _reserved8: [u8; 3],\n" -" imsc: u16,\n" -" _reserved9: [u8; 2],\n" -" ris: u16,\n" -" _reserved10: [u8; 2],\n" -" mis: u16,\n" -" _reserved11: [u8; 2],\n" -" icr: u16,\n" -" _reserved12: [u8; 2],\n" -" dmacr: u8,\n" -" _reserved13: [u8; 3],\n" -"}\n" -"```" -msgstr "" - #: src/bare-metal/aps/better-uart/registers.md:41 msgid "" "[`#[repr(C)]`](https://doc.rust-lang.org/reference/type-layout.html#the-c-" @@ -15668,9 +15485,9 @@ msgid "" " writeln!(uart, \"main({x0:#x}, {x1:#x}, {x2:#x}, {x3:#x})\").unwrap();\n" "\n" " loop {\n" -" if let Some(b) = uart.read_byte() {\n" -" uart.write_byte(b);\n" -" match b {\n" +" if let Some(byte) = uart.read_byte() {\n" +" uart.write_byte(byte);\n" +" match byte {\n" " b'\\r' => {\n" " uart.write_byte(b'\\n');\n" " }\n" @@ -15814,6 +15631,98 @@ msgid "" "examples`." msgstr "" +#: src/bare-metal/aps/exceptions.md:3 +msgid "" +"AArch64 defines an exception vector table with 16 entries, for 4 types of " +"exceptions (synchronous, IRQ, FIQ, SError) from 4 states (current EL with " +"SP0, current EL with SPx, lower EL using AArch64, lower EL using AArch32). " +"We implement this in assembly to save volatile registers to the stack before " +"calling into Rust code:" +msgstr "" + +#: src/bare-metal/aps/exceptions.md:8 +msgid "" +"```rust,editable,compile_fail\n" +"use log::error;\n" +"use smccc::psci::system_off;\n" +"use smccc::Hvc;\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn sync_exception_current(_elr: u64, _spsr: u64) {\n" +" error!(\"sync_exception_current\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn irq_current(_elr: u64, _spsr: u64) {\n" +" error!(\"irq_current\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn fiq_current(_elr: u64, _spsr: u64) {\n" +" error!(\"fiq_current\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn serr_current(_elr: u64, _spsr: u64) {\n" +" error!(\"serr_current\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn sync_lower(_elr: u64, _spsr: u64) {\n" +" error!(\"sync_lower\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn irq_lower(_elr: u64, _spsr: u64) {\n" +" error!(\"irq_lower\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn fiq_lower(_elr: u64, _spsr: u64) {\n" +" error!(\"fiq_lower\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn serr_lower(_elr: u64, _spsr: u64) {\n" +" error!(\"serr_lower\");\n" +" system_off::().unwrap();\n" +"}\n" +"```" +msgstr "" + +#: src/bare-metal/aps/exceptions.md:64 +msgid "EL is exception level; all our examples this afternoon run in EL1." +msgstr "" + +#: src/bare-metal/aps/exceptions.md:65 +msgid "" +"For simplicity we aren't distinguishing between SP0 and SPx for the current " +"EL exceptions, or between AArch32 and AArch64 for the lower EL exceptions." +msgstr "" + +#: src/bare-metal/aps/exceptions.md:67 +msgid "" +"For this example we just log the exception and power down, as we don't " +"expect any of them to actually happen." +msgstr "" + +#: src/bare-metal/aps/exceptions.md:69 +msgid "" +"We can think of exception handlers and our main execution context more or " +"less like different threads. [`Send` and `Sync`](../../concurrency/send-sync." +"md) will control what we can share between them, just like with threads. For " +"example, if we want to share some value between exception handlers and the " +"rest of the program, and it's `Send` but not `Sync`, then we'll need to wrap " +"it in something like a `Mutex` and put it in a static." +msgstr "" + #: src/bare-metal/aps/other-projects.md:3 msgid "[oreboot](https://github.com/oreboot/oreboot)" msgstr "" @@ -15842,18 +15751,45 @@ msgid "" "exception handling, page tables" msgstr "" -#: src/bare-metal/aps/other-projects.md:9 -msgid "Not all very well written, so beware." +#: src/bare-metal/aps/other-projects.md:10 +msgid "" +"Some dodginess around cache maintenance and initialisation in Rust, not " +"necessarily a good example to copy for production code." msgstr "" -#: src/bare-metal/aps/other-projects.md:10 +#: src/bare-metal/aps/other-projects.md:12 msgid "[`cargo-call-stack`](https://crates.io/crates/cargo-call-stack)" msgstr "" -#: src/bare-metal/aps/other-projects.md:11 +#: src/bare-metal/aps/other-projects.md:13 msgid "Static analysis to determine maximum stack usage." msgstr "" +#: src/bare-metal/aps/other-projects.md:17 +msgid "" +"The RaspberryPi OS tutorial runs Rust code before the MMU and caches are " +"enabled. This will read and write memory (e.g. the stack). However:" +msgstr "" + +#: src/bare-metal/aps/other-projects.md:19 +msgid "" +"Without the MMU and cache, unaligned accesses will fault. It builds with " +"`aarch64-unknown-none` which sets `+strict-align` to prevent the compiler " +"generating unaligned accesses so it should be alright, but this is not " +"necessarily the case in general." +msgstr "" + +#: src/bare-metal/aps/other-projects.md:22 +msgid "" +"If it were running in a VM, this can lead to cache coherency issues. The " +"problem is that the VM is accessing memory directly with the cache disabled, " +"while the host has cacheable aliases to the same memory. Even if the host " +"doesn't explicitly access the memory, speculative accesses can lead to cache " +"fills, and then changes from one or the other will get lost. Again this is " +"alright in this particular case (running directly on the hardware with no " +"hypervisor), but isn't a good pattern in general." +msgstr "" + #: src/bare-metal/useful-crates.md:3 msgid "" "We'll go over a few crates which solve some common problems in bare-metal " @@ -15871,43 +15807,6 @@ msgid "" "types." msgstr "" -#: src/bare-metal/useful-crates/zerocopy.md:6 -msgid "" -"```rust,editable,compile_fail\n" -"use zerocopy::AsBytes;\n" -"\n" -"#[repr(u32)]\n" -"#[derive(AsBytes, Debug, Default)]\n" -"enum RequestType {\n" -" #[default]\n" -" In = 0,\n" -" Out = 1,\n" -" Flush = 4,\n" -"}\n" -"\n" -"#[repr(C)]\n" -"#[derive(AsBytes, Debug, Default)]\n" -"struct VirtioBlockRequest {\n" -" request_type: RequestType,\n" -" reserved: u32,\n" -" sector: u64,\n" -"}\n" -"\n" -"fn main() {\n" -" let request = VirtioBlockRequest {\n" -" request_type: RequestType::Flush,\n" -" sector: 42,\n" -" ..Default::default()\n" -" };\n" -"\n" -" assert_eq!(\n" -" request.as_bytes(),\n" -" &[4, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0]\n" -" );\n" -"}\n" -"```" -msgstr "" - #: src/bare-metal/useful-crates/zerocopy.md:40 msgid "" "This is not suitable for MMIO (as it doesn't use volatile reads and writes), " @@ -17419,17 +17318,20 @@ msgid "" "```rust,editable,compile_fail\n" "use std::thread;\n" "\n" -"fn main() {\n" +"fn foo() {\n" " let s = String::from(\"Hello\");\n" -"\n" " thread::spawn(|| {\n" " println!(\"Length: {}\", s.len());\n" " });\n" "}\n" +"\n" +"fn main() {\n" +" foo();\n" +"}\n" "```" msgstr "" -#: src/concurrency/scoped-threads.md:17 +#: src/concurrency/scoped-threads.md:20 #, fuzzy msgid "" "However, you can use a [scoped thread](https://doc.rust-lang.org/std/thread/" @@ -17438,7 +17340,7 @@ msgstr "" "Sie können dafür jedoch einen [Scoped Thread](https://doc.rust-lang.org/std/" "thread/fn.scope.html) verwenden:" -#: src/concurrency/scoped-threads.md:19 +#: src/concurrency/scoped-threads.md:22 msgid "" "```rust,editable\n" "use std::thread;\n" @@ -17455,7 +17357,7 @@ msgid "" "```" msgstr "" -#: src/concurrency/scoped-threads.md:37 +#: src/concurrency/scoped-threads.md:40 #, fuzzy msgid "" "The reason for that is that when the `thread::scope` function completes, all " @@ -17465,7 +17367,7 @@ msgstr "" "garantiert alle Threads verbunden sind, sodass sie geliehene Daten " "zurückgeben können." -#: src/concurrency/scoped-threads.md:38 +#: src/concurrency/scoped-threads.md:41 #, fuzzy msgid "" "Normal Rust borrowing rules apply: you can either borrow mutably by one " @@ -17563,7 +17465,8 @@ msgstr "" #: src/concurrency/channels/bounded.md:3 #, fuzzy -msgid "Bounded and synchronous channels make `send` block the current thread:" +msgid "" +"With bounded (synchronous) channels, `send` can block the current thread:" msgstr "" "Gebundene und synchrone Kanäle sorgen dafür, dass der aktuelle Thread durch " "„Senden“ blockiert wird:" @@ -17595,6 +17498,25 @@ msgid "" "```" msgstr "" +#: src/concurrency/channels/bounded.md:31 +msgid "" +"Calling `send` will block the current thread until there is space in the " +"channel for the new message. The thread can be blocked indefinitely if there " +"is nobody who reads from the channel." +msgstr "" + +#: src/concurrency/channels/bounded.md:32 +msgid "" +"A call to `send` will abort with an error (that is why it returns `Result`) " +"if the channel is closed. A channel is closed when the receiver is dropped." +msgstr "" + +#: src/concurrency/channels/bounded.md:33 +msgid "" +"A bounded channel with a size of zero is called a \"rendezvous channel\". " +"Every send will block the current thread until another thread calls `read`." +msgstr "" + #: src/concurrency/send-sync.md:1 #, fuzzy msgid "`Send` and `Sync`" @@ -17951,7 +17873,7 @@ msgstr "" #, fuzzy msgid "" "`Arc` implements `Clone` whether or not `T` does. It implements `Send` " -"and `Sync` iff `T` implements them both." +"and `Sync` if and only if `T` implements them both." msgstr "" "`Arc` implementiert `Clone` unabhängig davon, ob `T` dies tut oder nicht. " "Es implementiert `Send` und `Sync` iff `T` setzt sie beide um." @@ -18055,7 +17977,9 @@ msgstr "" #: src/concurrency/shared_state/mutex.md:35 #, fuzzy -msgid "`Mutex` implements both `Send` and `Sync` iff `T` implements `Send`." +msgid "" +"`Mutex` implements both `Send` and `Sync` iff (if and only if) `T` " +"implements `Send`." msgstr "" "`Mutex` implementiert sowohl `Send` als auch `Sync`, wenn `T` `Send` " "implementiert." @@ -18280,7 +18204,7 @@ msgid "" "\n" " // Create philosophers\n" "\n" -" // Make them think and eat\n" +" // Make each of them think and eat 100 times\n" "\n" " // Output their thoughts\n" "}\n" @@ -18325,15 +18249,6 @@ msgstr "" "reqwest/). Erstelle eine neue Frachtprojekt und `reqwest` es als " "Abhängigkeit mit:" -#: src/exercises/concurrency/link-checker.md:11 -msgid "" -"```shell\n" -"$ cargo new link-checker\n" -"$ cd link-checker\n" -"$ cargo add --features blocking,rustls-tls reqwest\n" -"```" -msgstr "" - #: src/exercises/concurrency/link-checker.md:17 #, fuzzy msgid "" @@ -18353,13 +18268,6 @@ msgstr "" "Sie benötigen auch eine Möglichkeit, Links zu finden. Dafür können wir " "[`scraper`](https://docs.rs/scraper/) verwenden:" -#: src/exercises/concurrency/link-checker.md:22 -msgid "" -"```shell\n" -"$ cargo add scraper\n" -"```" -msgstr "" - #: src/exercises/concurrency/link-checker.md:26 #, fuzzy msgid "" @@ -18369,13 +18277,6 @@ msgstr "" "Schließlich brauchen wir eine Möglichkeit, mit Fehlern umzugehen. Wir " "verwenden [`thiserror`](https://docs.rs/thiserror/) für Das:" -#: src/exercises/concurrency/link-checker.md:29 -msgid "" -"```shell\n" -"$ cargo add thiserror\n" -"```" -msgstr "" - #: src/exercises/concurrency/link-checker.md:33 #, fuzzy msgid "" @@ -18418,8 +18319,7 @@ msgstr "Ihre `src/main.rs`\\-Datei sollte in etwa so aussehen:" #: src/exercises/concurrency/link-checker.md:57 msgid "" "```rust,compile_fail\n" -"use reqwest::blocking::{get, Response};\n" -"use reqwest::Url;\n" +"use reqwest::{blocking::Client, Url};\n" "use scraper::{Html, Selector};\n" "use thiserror::Error;\n" "\n" @@ -18427,34 +18327,57 @@ msgid "" "enum Error {\n" " #[error(\"request error: {0}\")]\n" " ReqwestError(#[from] reqwest::Error),\n" +" #[error(\"bad http response: {0}\")]\n" +" BadResponse(String),\n" "}\n" "\n" -"fn extract_links(response: Response) -> Result, Error> {\n" -" let base_url = response.url().to_owned();\n" -" let document = response.text()?;\n" -" let html = Html::parse_document(&document);\n" -" let selector = Selector::parse(\"a\").unwrap();\n" +"#[derive(Debug)]\n" +"struct CrawlCommand {\n" +" url: Url,\n" +" extract_links: bool,\n" +"}\n" "\n" -" let mut valid_urls = Vec::new();\n" -" for element in html.select(&selector) {\n" -" if let Some(href) = element.value().attr(\"href\") {\n" -" match base_url.join(href) {\n" -" Ok(url) => valid_urls.push(url),\n" -" Err(err) => {\n" -" println!(\"On {base_url}: could not parse {href:?}: " -"{err} (ignored)\",);\n" -" }\n" +"fn visit_page(client: &Client, command: &CrawlCommand) -> Result, " +"Error> {\n" +" println!(\"Checking {:#}\", command.url);\n" +" let response = client.get(command.url.clone()).send()?;\n" +" if !response.status().is_success() {\n" +" return Err(Error::BadResponse(response.status().to_string()));\n" +" }\n" +"\n" +" let mut link_urls = Vec::new();\n" +" if !command.extract_links {\n" +" return Ok(link_urls);\n" +" }\n" +"\n" +" let base_url = response.url().to_owned();\n" +" let body_text = response.text()?;\n" +" let document = Html::parse_document(&body_text);\n" +"\n" +" let selector = Selector::parse(\"a\").unwrap();\n" +" let href_values = document\n" +" .select(&selector)\n" +" .filter_map(|element| element.value().attr(\"href\"));\n" +" for href in href_values {\n" +" match base_url.join(href) {\n" +" Ok(link_url) => {\n" +" link_urls.push(link_url);\n" +" }\n" +" Err(err) => {\n" +" println!(\"On {base_url:#}: ignored unparsable {href:?}: " +"{err}\");\n" " }\n" " }\n" " }\n" -"\n" -" Ok(valid_urls)\n" +" Ok(link_urls)\n" "}\n" "\n" "fn main() {\n" +" let client = Client::new();\n" " let start_url = Url::parse(\"https://www.google.org\").unwrap();\n" -" let response = get(start_url).unwrap();\n" -" match extract_links(response) {\n" +" let crawl_command = CrawlCommand{ url: start_url, extract_links: " +"true };\n" +" match visit_page(&client, &crawl_command) {\n" " Ok(links) => println!(\"Links: {links:#?}\"),\n" " Err(err) => println!(\"Could not extract links: {err:#}\"),\n" " }\n" @@ -18462,19 +18385,12 @@ msgid "" "```" msgstr "" -#: src/exercises/concurrency/link-checker.md:100 +#: src/exercises/concurrency/link-checker.md:120 #, fuzzy msgid "Run the code in `src/main.rs` with" msgstr "Führen Sie den Code in `src/main.rs` mit aus" -#: src/exercises/concurrency/link-checker.md:102 -msgid "" -"```shell\n" -"$ cargo run\n" -"```" -msgstr "" - -#: src/exercises/concurrency/link-checker.md:108 +#: src/exercises/concurrency/link-checker.md:128 #, fuzzy msgid "" "Use threads to check the links in parallel: send the URLs to be checked to a " @@ -18484,7 +18400,7 @@ msgstr "" "prüfenden URLs an a Channel und lass ein paar Threads parallel die URLs " "prüfen." -#: src/exercises/concurrency/link-checker.md:110 +#: src/exercises/concurrency/link-checker.md:130 #, fuzzy msgid "" "Extend this to recursively extract links from all pages on the `www.google." @@ -18625,25 +18541,6 @@ msgid "" "doc.rust-lang.org/std/task/enum.Poll.html)." msgstr "" -#: src/async/futures.md:8 -msgid "" -"```rust\n" -"use std::pin::Pin;\n" -"use std::task::Context;\n" -"\n" -"pub trait Future {\n" -" type Output;\n" -" fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll;\n" -"}\n" -"\n" -"pub enum Poll {\n" -" Ready(T),\n" -" Pending,\n" -"}\n" -"```" -msgstr "" - #: src/async/futures.md:23 msgid "" "An async function returns an `impl Future`. It's also possible (but " @@ -18692,19 +18589,19 @@ msgstr "" #: src/async/runtimes.md:7 msgid "" -"[Tokio](https://tokio.rs/) - performant, with a well-developed ecosystem of " +"[Tokio](https://tokio.rs/): performant, with a well-developed ecosystem of " "functionality like [Hyper](https://hyper.rs/) for HTTP or [Tonic](https://" "github.com/hyperium/tonic) for gRPC." msgstr "" #: src/async/runtimes.md:10 msgid "" -"[async-std](https://async.rs/) - aims to be a \"std for async\", and " -"includes a basic runtime in `async::task`." +"[async-std](https://async.rs/): aims to be a \"std for async\", and includes " +"a basic runtime in `async::task`." msgstr "" #: src/async/runtimes.md:12 -msgid "[smol](https://docs.rs/smol/latest/smol/) - simple and lightweight" +msgid "[smol](https://docs.rs/smol/latest/smol/): simple and lightweight" msgstr "" #: src/async/runtimes.md:14 @@ -18801,12 +18698,10 @@ msgid "Try awaiting the task returned from `tokio::spawn`." msgstr "" #: src/async/tasks.md:3 -msgid "" -"Runtimes have the concept of a \"task\", similar to a thread but much less " -"resource-intensive." +msgid "Rust has a task system, which is a form of lightweight threading." msgstr "" -#: src/async/tasks.md:6 +#: src/async/tasks.md:5 msgid "" "A task has a single top-level future which the executor polls to make " "progress. That future may have one or more nested futures that its `poll` " @@ -18815,7 +18710,7 @@ msgid "" "and an I/O operation." msgstr "" -#: src/async/tasks.md:11 +#: src/async/tasks.md:10 msgid "" "```rust,compile_fail\n" "use tokio::io::{self, AsyncReadExt, AsyncWriteExt};\n" @@ -18859,25 +18754,25 @@ msgid "" "```" msgstr "" -#: src/async/tasks.md:53 src/async/control-flow/join.md:36 +#: src/async/tasks.md:52 src/async/control-flow/join.md:36 msgid "" "Copy this example into your prepared `src/main.rs` and run it from there." msgstr "" -#: src/async/tasks.md:55 +#: src/async/tasks.md:54 msgid "" "Ask students to visualize what the state of the example server would be with " "a few connected clients. What tasks exist? What are their Futures?" msgstr "" -#: src/async/tasks.md:58 +#: src/async/tasks.md:57 msgid "" "This is the first time we've seen an `async` block. This is similar to a " "closure, but does not take any arguments. Its return value is a Future, " "similar to an `async fn`. " msgstr "" -#: src/async/tasks.md:62 +#: src/async/tasks.md:61 msgid "" "Refactor the async block into a function, and improve the error handling " "using `?`." @@ -18885,8 +18780,7 @@ msgstr "" #: src/async/channels.md:3 msgid "" -"Several crates have support for `async`/`await`. For instance `tokio` " -"channels:" +"Several crates have support for asynchronous channels. For instance `tokio`:" msgstr "" #: src/async/channels.md:5 @@ -18914,7 +18808,7 @@ msgid "" " println!(\"Sent {} pings so far.\", i + 1);\n" " }\n" "\n" -" std::mem::drop(sender);\n" +" drop(sender);\n" " ping_handler_task.await.expect(\"Something went wrong in ping handler " "task.\");\n" "}\n" @@ -19038,12 +18932,13 @@ msgstr "" #: src/async/control-flow/select.md:8 msgid "" -"This is usually a macro, similar to match, with each arm of the form " -"`pattern = future => statement`. When the future is ready, the statement is " -"executed with the variable bound to the future's result." +"Similar to a match statement, the body of `select!` has a number of arms, " +"each of the form `pattern = future => statement`. When the `future` is " +"ready, the `statement` is executed with the variables in `pattern` bound to " +"the `future`'s result." msgstr "" -#: src/async/control-flow/select.md:12 +#: src/async/control-flow/select.md:13 msgid "" "```rust,editable,compile_fail\n" "use tokio::sync::mpsc::{self, Receiver};\n" @@ -19093,32 +18988,36 @@ msgid "" "```" msgstr "" -#: src/async/control-flow/select.md:61 +#: src/async/control-flow/select.md:62 msgid "" "In this example, we have a race between a cat and a dog. " "`first_animal_to_finish_race` listens to both channels and will pick " "whichever arrives first. Since the dog takes 50ms, it wins against the cat " -"that take 500ms seconds." +"that take 500ms." msgstr "" -#: src/async/control-flow/select.md:66 +#: src/async/control-flow/select.md:67 msgid "" "You can use `oneshot` channels in this example as the channels are supposed " "to receive only one `send`." msgstr "" -#: src/async/control-flow/select.md:69 +#: src/async/control-flow/select.md:70 msgid "" "Try adding a deadline to the race, demonstrating selecting different sorts " "of futures." msgstr "" -#: src/async/control-flow/select.md:72 +#: src/async/control-flow/select.md:73 msgid "" -"Note that `select!` moves the values it is given. It is easiest to use when " -"every execution of `select!` creates new futures. An alternative is to pass " -"`&mut future` instead of the future itself, but this can lead to issues, " -"further discussed in the pinning slide." +"Note that `select!` drops unmatched branches, which cancels their futures. " +"It is easiest to use when every execution of `select!` creates new futures." +msgstr "" + +#: src/async/control-flow/select.md:76 +msgid "" +"An alternative is to pass `&mut future` instead of the future itself, but " +"this can lead to issues, further discussed in the pinning slide." msgstr "" #: src/async/pitfalls.md:1 @@ -19142,7 +19041,11 @@ msgid "[Pin](pitfalls/pin.md)" msgstr "" #: src/async/pitfalls.md:7 -msgid "[Async Traits](pitfall/async-traits.md)" +msgid "[Async Traits](pitfalls/async-traits.md)" +msgstr "" + +#: src/async/pitfalls.md:8 +msgid "[Cancellation](pitfalls/cancellation.md)" msgstr "" #: src/async/pitfalls/blocking-executor.md:1 @@ -19315,19 +19218,6 @@ msgid "" "Instead, add a `timeout_fut` containing that future outside of the `loop`:" msgstr "" -#: src/async/pitfalls/pin.md:79 -msgid "" -"```rust,compile_fail\n" -"let mut timeout_fut = sleep(Duration::from_millis(100));\n" -"loop {\n" -" select! {\n" -" ..,\n" -" _ = timeout_fut => { println!(..); },\n" -" }\n" -"}\n" -"```" -msgstr "" - #: src/async/pitfalls/pin.md:88 msgid "" "This still doesn't work. Follow the compiler errors, adding `&mut` to the " @@ -19335,19 +19225,6 @@ msgid "" "pin`:" msgstr "" -#: src/async/pitfalls/pin.md:92 -msgid "" -"```rust,compile_fail\n" -"let mut timeout_fut = Box::pin(sleep(Duration::from_millis(100)));\n" -"loop {\n" -" select! {\n" -" ..,\n" -" _ = &mut timeout_fut => { println!(..); },\n" -" }\n" -"}\n" -"```" -msgstr "" - #: src/async/pitfalls/pin.md:102 msgid "" "This compiles, but once the timeout expires it is `Poll::Ready` on every " @@ -19449,6 +19326,155 @@ msgid "" "time and adding it to the Vec." msgstr "" +#: src/async/pitfalls/cancellation.md:3 +msgid "" +"Dropping a future implies it can never be polled again. This is called " +"_cancellation_ and it can occur at any `await` point. Care is needed to " +"ensure the system works correctly even when futures are cancelled. For " +"example, it shouldn't deadlock or lose data." +msgstr "" + +#: src/async/pitfalls/cancellation.md:8 +msgid "" +"```rust,editable,compile_fail\n" +"use std::io::{self, ErrorKind};\n" +"use std::time::Duration;\n" +"use tokio::io::{AsyncReadExt, AsyncWriteExt, DuplexStream};\n" +"\n" +"struct LinesReader {\n" +" stream: DuplexStream,\n" +"}\n" +"\n" +"impl LinesReader {\n" +" fn new(stream: DuplexStream) -> Self {\n" +" Self { stream }\n" +" }\n" +"\n" +" async fn next(&mut self) -> io::Result> {\n" +" let mut bytes = Vec::new();\n" +" let mut buf = [0];\n" +" while self.stream.read(&mut buf[..]).await? != 0 {\n" +" bytes.push(buf[0]);\n" +" if buf[0] == b'\\n' {\n" +" break;\n" +" }\n" +" }\n" +" if bytes.is_empty() {\n" +" return Ok(None)\n" +" }\n" +" let s = String::from_utf8(bytes)\n" +" .map_err(|_| io::Error::new(ErrorKind::InvalidData, \"not " +"UTF-8\"))?;\n" +" Ok(Some(s))\n" +" }\n" +"}\n" +"\n" +"async fn slow_copy(source: String, mut dest: DuplexStream) -> std::io::" +"Result<()> {\n" +" for b in source.bytes() {\n" +" dest.write_u8(b).await?;\n" +" tokio::time::sleep(Duration::from_millis(10)).await\n" +" }\n" +" Ok(())\n" +"}\n" +"\n" +"#[tokio::main]\n" +"async fn main() -> std::io::Result<()> {\n" +" let (client, server) = tokio::io::duplex(5);\n" +" let handle = tokio::spawn(slow_copy(\"hi\\nthere\\n\".to_owned(), " +"client));\n" +"\n" +" let mut lines = LinesReader::new(server);\n" +" let mut interval = tokio::time::interval(Duration::from_millis(60));\n" +" loop {\n" +" tokio::select! {\n" +" _ = interval.tick() => println!(\"tick!\"),\n" +" line = lines.next() => if let Some(l) = line? {\n" +" print!(\"{}\", l)\n" +" } else {\n" +" break\n" +" },\n" +" }\n" +" }\n" +" handle.await.unwrap()?;\n" +" Ok(())\n" +"}\n" +"```" +msgstr "" + +#: src/async/pitfalls/cancellation.md:72 +msgid "" +"The compiler doesn't help with cancellation-safety. You need to read API " +"documentation and consider what state your `async fn` holds." +msgstr "" + +#: src/async/pitfalls/cancellation.md:75 +msgid "" +"Unlike `panic` and `?`, cancellation is part of normal control flow (vs " +"error-handling)." +msgstr "" + +#: src/async/pitfalls/cancellation.md:78 +msgid "The example loses parts of the string." +msgstr "" + +#: src/async/pitfalls/cancellation.md:80 +msgid "" +"Whenever the `tick()` branch finishes first, `next()` and its `buf` are " +"dropped." +msgstr "" + +#: src/async/pitfalls/cancellation.md:82 +msgid "" +"`LinesReader` can be made cancellation-safe by making `buf` part of the " +"struct:" +msgstr "" + +#: src/async/pitfalls/cancellation.md:83 +msgid "" +"```rust,compile_fail\n" +"struct LinesReader {\n" +" stream: DuplexStream,\n" +" bytes: Vec,\n" +" buf: [u8; 1],\n" +"}\n" +"\n" +"impl LinesReader {\n" +" fn new(stream: DuplexStream) -> Self {\n" +" Self { stream, bytes: Vec::new(), buf: [0] }\n" +" }\n" +" async fn next(&mut self) -> io::Result> {\n" +" // prefix buf and bytes with self.\n" +" // ...\n" +" let raw = std::mem::take(&mut self.bytes);\n" +" let s = String::from_utf8(raw)\n" +" // ...\n" +" }\n" +"}\n" +"```" +msgstr "" + +#: src/async/pitfalls/cancellation.md:104 +msgid "" +"[`Interval::tick`](https://docs.rs/tokio/latest/tokio/time/struct.Interval." +"html#method.tick) is cancellation-safe because it keeps track of whether a " +"tick has been 'delivered'." +msgstr "" + +#: src/async/pitfalls/cancellation.md:107 +msgid "" +"[`AsyncReadExt::read`](https://docs.rs/tokio/latest/tokio/io/trait." +"AsyncReadExt.html#method.read) is cancellation-safe because it either " +"returns or doesn't read data." +msgstr "" + +#: src/async/pitfalls/cancellation.md:110 +msgid "" +"[`AsyncBufReadExt::read_line`](https://docs.rs/tokio/latest/tokio/io/trait." +"AsyncBufReadExt.html#method.read_line) is similar to the example and _isn't_ " +"cancellation-safe. See its documentation for details and alternatives." +msgstr "" + #: src/exercises/concurrency/afternoon.md:3 msgid "" "To practice your Async Rust skills, we have again two exercises for you:" @@ -19581,7 +19607,7 @@ msgstr "" msgid "" "For this, we use [a broadcast channel](https://docs.rs/tokio/latest/tokio/" "sync/broadcast/fn.channel.html) on the server, and [`tokio_websockets`]" -"(https://docs.rs/tokio-websockets/0.3.2/tokio_websockets/) for the " +"(https://docs.rs/tokio-websockets/0.4.0/tokio_websockets/) for the " "communication between the client and the server." msgstr "" @@ -19602,10 +19628,11 @@ msgid "" "edition = \"2021\"\n" "\n" "[dependencies]\n" -"futures-util = \"0.3.28\"\n" +"futures-util = { version = \"0.3.28\", features = [\"sink\"] }\n" "http = \"0.2.9\"\n" "tokio = { version = \"1.28.1\", features = [\"full\"] }\n" -"tokio-websockets = \"0.3.2\"\n" +"tokio-websockets = { version = \"0.4.0\", features = [\"client\", " +"\"fastrand\", \"server\", \"sha1_smol\"] }\n" "```" msgstr "" @@ -19616,15 +19643,15 @@ msgstr "" #: src/exercises/concurrency/chat-app.md:33 msgid "" "You are going to need the following functions from `tokio` and " -"[`tokio_websockets`](https://docs.rs/tokio-websockets/0.3.2/" +"[`tokio_websockets`](https://docs.rs/tokio-websockets/0.4.0/" "tokio_websockets/). Spend a few minutes to familiarize yourself with the " "API. " msgstr "" #: src/exercises/concurrency/chat-app.md:37 msgid "" -"[WebsocketStream::next()](https://docs.rs/tokio-websockets/0.3.2/" -"tokio_websockets/proto/struct.WebsocketStream.html#method.next): for " +"[StreamExt::next()](https://docs.rs/futures-util/0.3.28/futures_util/stream/" +"trait.StreamExt.html#method.next) implemented by `WebsocketStream`: for " "asynchronously reading messages from a Websocket Stream." msgstr "" @@ -19637,7 +19664,7 @@ msgstr "" #: src/exercises/concurrency/chat-app.md:41 msgid "" -"[BufReader::read_line()](https://docs.rs/tokio/latest/tokio/io/struct.Lines." +"[Lines::next_line()](https://docs.rs/tokio/latest/tokio/io/struct.Lines." "html#method.next_line): for asynchronously reading user messages from the " "standard input." msgstr "" @@ -19672,7 +19699,7 @@ msgid "" msgstr "" #: src/exercises/concurrency/chat-app.md:59 -#: src/exercises/concurrency/solutions-afternoon.md:117 +#: src/exercises/concurrency/solutions-afternoon.md:99 #, fuzzy msgid "`src/bin/server.rs`:" msgstr "_hello_rust/src/main.rs_:" @@ -19681,6 +19708,7 @@ msgstr "_hello_rust/src/main.rs_:" msgid "" "```rust,compile_fail\n" "use futures_util::sink::SinkExt;\n" +"use futures_util::stream::StreamExt;\n" "use std::error::Error;\n" "use std::net::SocketAddr;\n" "use tokio::net::{TcpListener, TcpStream};\n" @@ -19719,15 +19747,16 @@ msgid "" "```" msgstr "" -#: src/exercises/concurrency/chat-app.md:102 -#: src/exercises/concurrency/solutions-afternoon.md:202 +#: src/exercises/concurrency/chat-app.md:103 +#: src/exercises/concurrency/solutions-afternoon.md:166 #, fuzzy msgid "`src/bin/client.rs`:" msgstr "_hello_rust/src/main.rs_:" -#: src/exercises/concurrency/chat-app.md:106 +#: src/exercises/concurrency/chat-app.md:107 msgid "" "```rust,compile_fail\n" +"use futures_util::stream::StreamExt;\n" "use futures_util::SinkExt;\n" "use http::Uri;\n" "use tokio::io::{AsyncBufReadExt, BufReader};\n" @@ -19735,13 +19764,13 @@ msgid "" "\n" "#[tokio::main]\n" "async fn main() -> Result<(), tokio_websockets::Error> {\n" -" let mut ws_stream = ClientBuilder::from_uri(Uri::" -"from_static(\"ws://127.0.0.1:2000\"))\n" -" .connect()\n" -" .await?;\n" +" let (mut ws_stream, _) =\n" +" ClientBuilder::from_uri(Uri::from_static(\"ws://127.0.0.1:2000\"))\n" +" .connect()\n" +" .await?;\n" "\n" " let stdin = tokio::io::stdin();\n" -" let mut stdin = BufReader::new(stdin);\n" +" let mut stdin = BufReader::new(stdin).lines();\n" "\n" "\n" " // TODO: For a hint, see the description of the task below.\n" @@ -19750,49 +19779,35 @@ msgid "" "```" msgstr "" -#: src/exercises/concurrency/chat-app.md:127 +#: src/exercises/concurrency/chat-app.md:130 #, fuzzy msgid "Running the binaries" msgstr "Ablauf des Kurses" -#: src/exercises/concurrency/chat-app.md:128 +#: src/exercises/concurrency/chat-app.md:131 msgid "Run the server with:" msgstr "" -#: src/exercises/concurrency/chat-app.md:130 -msgid "" -"```shell\n" -"$ cargo run --bin server\n" -"```" -msgstr "" - -#: src/exercises/concurrency/chat-app.md:134 +#: src/exercises/concurrency/chat-app.md:137 msgid "and the client with:" msgstr "" -#: src/exercises/concurrency/chat-app.md:136 -msgid "" -"```shell\n" -"$ cargo run --bin client\n" -"```" -msgstr "" - -#: src/exercises/concurrency/chat-app.md:142 +#: src/exercises/concurrency/chat-app.md:145 msgid "Implement the `handle_connection` function in `src/bin/server.rs`." msgstr "" -#: src/exercises/concurrency/chat-app.md:143 +#: src/exercises/concurrency/chat-app.md:146 msgid "" "Hint: Use `tokio::select!` for concurrently performing two tasks in a " "continuous loop. One task receives messages from the client and broadcasts " "them. The other sends messages received by the server to the client." msgstr "" -#: src/exercises/concurrency/chat-app.md:146 +#: src/exercises/concurrency/chat-app.md:149 msgid "Complete the main function in `src/bin/client.rs`." msgstr "" -#: src/exercises/concurrency/chat-app.md:147 +#: src/exercises/concurrency/chat-app.md:150 msgid "" "Hint: As before, use `tokio::select!` in a continuous loop for concurrently " "performing two tasks: (1) reading user messages from standard input and " @@ -19800,7 +19815,7 @@ msgid "" "displaying them for the user." msgstr "" -#: src/exercises/concurrency/chat-app.md:151 +#: src/exercises/concurrency/chat-app.md:154 msgid "" "Optional: Once you are done, change the code to broadcast messages to all " "clients, but the sender of the message." @@ -20048,17 +20063,18 @@ msgstr "" #, fuzzy msgid "" "The material of Comprehensive Rust is licensed under the terms of the Apache " -"2.0 license, please see [`LICENSE`](../LICENSE) for details." +"2.0 license, please see [`LICENSE`](https://github.com/google/comprehensive-" +"rust/blob/main/LICENSE) for details." msgstr "" "Das Material von Comprehensive Rust ist unter den Bedingungen von Apache 2.0 " "lizenziert Lizenz finden Sie unter [`LICENSE`](../LICENSE) für Einzelheiten." -#: src/credits.md:10 +#: src/credits.md:12 #, fuzzy msgid "Rust by Example" msgstr "Rost zum Beispiel" -#: src/credits.md:12 +#: src/credits.md:14 #, fuzzy msgid "" "Some examples and exercises have been copied and adapted from [Rust by " @@ -20070,12 +20086,12 @@ msgstr "" "lang.org/rust-by-example/). Bitte sehen Sie sich ... an `third_party/rust-by-" "example/`\\-Verzeichnis für Details, einschließlich der Lizenz Bedingungen." -#: src/credits.md:17 +#: src/credits.md:19 #, fuzzy msgid "Rust on Exercism" msgstr "Rost auf Übung" -#: src/credits.md:19 +#: src/credits.md:21 #, fuzzy msgid "" "Some exercises have been copied and adapted from [Rust on Exercism](https://" @@ -20086,12 +20102,12 @@ msgstr "" "rust). Bitte sehen Sie sich ... an `third_party/rust-on-exercism/`\\-" "Verzeichnis für Details, einschließlich der Lizenz Bedingungen." -#: src/credits.md:24 +#: src/credits.md:26 #, fuzzy msgid "CXX" msgstr "\\##CXX" -#: src/credits.md:26 +#: src/credits.md:28 #, fuzzy msgid "" "The [Interoperability with C++](android/interoperability/cpp.md) section " @@ -20118,16 +20134,6 @@ msgstr "" "com/google/comprehensive-rust/discussions) zu stellen. Lass uns wissen wenn " "Du eine andere oder bessere Lösung als die hier vorgestellte hast." -#: src/exercises/solutions.md:10 -msgid "" -"**Note:** Please ignore the `// ANCHOR: label` and `// ANCHOR_END: label` " -"comments you see in the solutions. They are there to make it possible to re-" -"use parts of the solutions as the exercises." -msgstr "" -"**Hinweis:** Bitte ignoriere `// ANCHOR: label` und `// ANCHOR_END: label` " -"Kommentare, die Du in den Lösungen siehst. Sie sind da, um es zu ermöglichen " -"Teile der Lösungen als Aufgaben wiederverwenden." - #: src/exercises/day-1/solutions-morning.md:1 #, fuzzy msgid "Day 1 Morning Exercises" @@ -20141,23 +20147,7 @@ msgstr "([zurück zur Übung](for-loops.md))" #: src/exercises/day-1/solutions-morning.md:7 msgid "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: transpose\n" "fn transpose(matrix: [[i32; 3]; 3]) -> [[i32; 3]; 3] {\n" -" // ANCHOR_END: transpose\n" " let mut result = [[0; 3]; 3];\n" " for i in 0..3 {\n" " for j in 0..3 {\n" @@ -20167,15 +20157,12 @@ msgid "" " return result;\n" "}\n" "\n" -"// ANCHOR: pretty_print\n" "fn pretty_print(matrix: &[[i32; 3]; 3]) {\n" -" // ANCHOR_END: pretty_print\n" " for row in matrix {\n" " println!(\"{row:?}\");\n" " }\n" "}\n" "\n" -"// ANCHOR: tests\n" "#[test]\n" "fn test_transpose() {\n" " let matrix = [\n" @@ -20193,9 +20180,7 @@ msgid "" " ]\n" " );\n" "}\n" -"// ANCHOR_END: tests\n" "\n" -"// ANCHOR: main\n" "fn main() {\n" " let matrix = [\n" " [101, 102, 103], // <-- the comment makes rustfmt add a newline\n" @@ -20213,11 +20198,11 @@ msgid "" "```" msgstr "" -#: src/exercises/day-1/solutions-morning.md:78 +#: src/exercises/day-1/solutions-morning.md:57 msgid "Bonus question" msgstr "" -#: src/exercises/day-1/solutions-morning.md:80 +#: src/exercises/day-1/solutions-morning.md:59 #, fuzzy msgid "" "It requires more advanced concepts. It might seem that we could use a slice-" @@ -20231,7 +20216,7 @@ msgstr "" "handhaben. Dies bricht jedoch schnell zusammen: Der Rückgabetyp kann nicht " "`&[&[i32]]` sein, da er die von Ihnen zurückgegebenen Daten besitzen muss." -#: src/exercises/day-1/solutions-morning.md:82 +#: src/exercises/day-1/solutions-morning.md:61 msgid "" "You can attempt to use something like `Vec>`, but this doesn't work " "out-of-the-box either: it's hard to convert from `Vec>` to " @@ -20242,14 +20227,14 @@ msgstr "" "`&[&[i32]] umzuwandeln. ` also kannst Du jetzt auch `pretty_print` nicht " "einfach verwenden." -#: src/exercises/day-1/solutions-morning.md:84 +#: src/exercises/day-1/solutions-morning.md:63 msgid "" "Once we get to traits and generics, we'll be able to use the [`std::convert::" "AsRef`](https://doc.rust-lang.org/std/convert/trait.AsRef.html) trait to " "abstract over anything that can be referenced as a slice." msgstr "" -#: src/exercises/day-1/solutions-morning.md:86 +#: src/exercises/day-1/solutions-morning.md:65 msgid "" "```rust\n" "use std::convert::AsRef;\n" @@ -20279,7 +20264,7 @@ msgid "" "```" msgstr "" -#: src/exercises/day-1/solutions-morning.md:113 +#: src/exercises/day-1/solutions-morning.md:92 #, fuzzy msgid "" "In addition, the type itself would not enforce that the child slices are of " @@ -20296,27 +20281,112 @@ msgstr "Tag 1 Nachmittagsübungen" #: src/exercises/day-1/solutions-afternoon.md:5 #, fuzzy -msgid "([back to exercise](book-library.md))" -msgstr "([zurück zur Übung](book-library.md))" +msgid "([back to exercise](luhn.md))" +msgstr "([zurück zur Übung](luhn.md))" #: src/exercises/day-1/solutions-afternoon.md:7 msgid "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" +"pub fn luhn(cc_number: &str) -> bool {\n" +" let mut digits_seen = 0;\n" +" let mut sum = 0;\n" +" for (i, ch) in cc_number.chars().rev().filter(|&ch| ch != ' ')." +"enumerate() {\n" +" match ch.to_digit(10) {\n" +" Some(d) => {\n" +" sum += if i % 2 == 1 {\n" +" let dd = d * 2;\n" +" dd / 10 + dd % 10\n" +" } else {\n" +" d\n" +" };\n" +" digits_seen += 1;\n" +" }\n" +" None => return false,\n" +" }\n" +" }\n" "\n" -"// ANCHOR: setup\n" +" if digits_seen < 2 {\n" +" return false;\n" +" }\n" +"\n" +" sum % 10 == 0\n" +"}\n" +"\n" +"fn main() {\n" +" let cc_number = \"1234 5678 1234 5670\";\n" +" println!(\n" +" \"Is {cc_number} a valid credit card number? {}\",\n" +" if luhn(cc_number) { \"yes\" } else { \"no\" }\n" +" );\n" +"}\n" +"\n" +"#[test]\n" +"fn test_non_digit_cc_number() {\n" +" assert!(!luhn(\"foo\"));\n" +" assert!(!luhn(\"foo 0 0\"));\n" +"}\n" +"\n" +"#[test]\n" +"fn test_empty_cc_number() {\n" +" assert!(!luhn(\"\"));\n" +" assert!(!luhn(\" \"));\n" +" assert!(!luhn(\" \"));\n" +" assert!(!luhn(\" \"));\n" +"}\n" +"\n" +"#[test]\n" +"fn test_single_digit_cc_number() {\n" +" assert!(!luhn(\"0\"));\n" +"}\n" +"\n" +"#[test]\n" +"fn test_two_digit_cc_number() {\n" +" assert!(luhn(\" 0 0 \"));\n" +"}\n" +"\n" +"#[test]\n" +"fn test_valid_cc_number() {\n" +" assert!(luhn(\"4263 9826 4026 9299\"));\n" +" assert!(luhn(\"4539 3195 0343 6467\"));\n" +" assert!(luhn(\"7992 7398 713\"));\n" +"}\n" +"\n" +"#[test]\n" +"fn test_invalid_cc_number() {\n" +" assert!(!luhn(\"4223 9826 4026 9299\"));\n" +" assert!(!luhn(\"4539 3195 0343 6476\"));\n" +" assert!(!luhn(\"8273 1232 7352 0569\"));\n" +"}\n" +"```" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:80 +#, fuzzy +msgid "Pattern matching" +msgstr "Musterabgleich" + +#: src/exercises/day-1/solutions-afternoon.md:82 +msgid "TBD." +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:1 +#, fuzzy +msgid "Day 2 Morning Exercises" +msgstr "Tag 2 Morgengymnastik" + +#: src/exercises/day-2/solutions-morning.md:3 +msgid "Designing a Library" +msgstr "Entwerfen einer Bibliothek" + +#: src/exercises/day-2/solutions-morning.md:5 +#, fuzzy +msgid "([back to exercise](book-library.md))" +msgstr "([zurück zur Übung](book-library.md))" + +#: src/exercises/day-2/solutions-morning.md:7 +msgid "" +"```rust\n" "struct Library {\n" " books: Vec,\n" "}\n" @@ -20343,58 +20413,45 @@ msgid "" "// - `&mut self` for unique and mutable access,\n" "// - `self` for unique access by value.\n" "impl Library {\n" -" // ANCHOR_END: setup\n" "\n" -" // ANCHOR: Library_new\n" " fn new() -> Library {\n" -" // ANCHOR_END: Library_new\n" " Library { books: Vec::new() }\n" " }\n" "\n" -" // ANCHOR: Library_len\n" " //fn len(self) -> usize {\n" " // todo!(\"Return the length of `self.books`\")\n" " //}\n" -" // ANCHOR_END: Library_len\n" " fn len(&self) -> usize {\n" " self.books.len()\n" " }\n" "\n" -" // ANCHOR: Library_is_empty\n" " //fn is_empty(self) -> bool {\n" " // todo!(\"Return `true` if `self.books` is empty\")\n" " //}\n" -" // ANCHOR_END: Library_is_empty\n" " fn is_empty(&self) -> bool {\n" " self.books.is_empty()\n" " }\n" "\n" -" // ANCHOR: Library_add_book\n" " //fn add_book(self, book: Book) {\n" " // todo!(\"Add a new book to `self.books`\")\n" " //}\n" -" // ANCHOR_END: Library_add_book\n" " fn add_book(&mut self, book: Book) {\n" " self.books.push(book)\n" " }\n" "\n" -" // ANCHOR: Library_print_books\n" " //fn print_books(self) {\n" -" // todo!(\"Iterate over `self.books` and each book's title and " +" // todo!(\"Iterate over `self.books` and print each book's title and " "year\")\n" " //}\n" -" // ANCHOR_END: Library_print_books\n" " fn print_books(&self) {\n" " for book in &self.books {\n" " println!(\"{}, published in {}\", book.title, book.year);\n" " }\n" " }\n" "\n" -" // ANCHOR: Library_oldest_book\n" " //fn oldest_book(self) -> Option<&Book> {\n" " // todo!(\"Return a reference to the oldest book (if any)\")\n" " //}\n" -" // ANCHOR_END: Library_oldest_book\n" " fn oldest_book(&self) -> Option<&Book> {\n" " // Using a closure and a built-in method:\n" " // self.books.iter().min_by_key(|book| book.year)\n" @@ -20411,7 +20468,6 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: main\n" "// This shows the desired behavior. Uncomment the code below and\n" "// implement the missing methods. You will need to update the\n" "// method signatures, including the \"self\" parameter! You may\n" @@ -20419,13 +20475,15 @@ msgid "" "fn main() {\n" " let library = Library::new();\n" "\n" -" //println!(\"The library is empty: {}\", library.is_empty());\n" +" //println!(\"The library is empty: library.is_empty() -> {}\", library." +"is_empty());\n" " //\n" " //library.add_book(Book::new(\"Lord of the Rings\", 1954));\n" " //library.add_book(Book::new(\"Alice's Adventures in Wonderland\", " "1865));\n" " //\n" -" //println!(\"The library is no longer empty: {}\", library.is_empty());\n" +" //println!(\"The library is no longer empty: library.is_empty() -> {}\", " +"library.is_empty());\n" " //\n" " //\n" " //library.print_books();\n" @@ -20438,7 +20496,6 @@ msgid "" " //println!(\"The library has {} books\", library.len());\n" " //library.print_books();\n" "}\n" -"// ANCHOR_END: main\n" "\n" "#[test]\n" "fn test_library_len() {\n" @@ -20494,44 +20551,254 @@ msgid "" "```" msgstr "" -#: src/exercises/day-2/solutions-morning.md:1 +#: src/exercises/day-2/solutions-afternoon.md:1 #, fuzzy -msgid "Day 2 Morning Exercises" -msgstr "Tag 2 Morgengymnastik" +msgid "Day 2 Afternoon Exercises" +msgstr "Tag 2 Nachmittagsübungen" -#: src/exercises/day-2/solutions-morning.md:5 +#: src/exercises/day-2/solutions-afternoon.md:5 +#, fuzzy +msgid "([back to exercise](strings-iterators.md))" +msgstr "([zurück zur Übung](strings-iterators.md))" + +#: src/exercises/day-2/solutions-afternoon.md:7 +msgid "" +"```rust\n" +"pub fn prefix_matches(prefix: &str, request_path: &str) -> bool {\n" +"\n" +" let mut request_segments = request_path.split('/');\n" +"\n" +" for prefix_segment in prefix.split('/') {\n" +" let Some(request_segment) = request_segments.next() else {\n" +" return false;\n" +" };\n" +" if request_segment != prefix_segment && prefix_segment != \"*\" {\n" +" return false;\n" +" }\n" +" }\n" +" true\n" +"\n" +" // Alternatively, Iterator::zip() lets us iterate simultaneously over " +"prefix\n" +" // and request segments. The zip() iterator is finished as soon as one " +"of\n" +" // the source iterators is finished, but we need to iterate over all " +"request\n" +" // segments. A neat trick that makes zip() work is to use map() and " +"chain()\n" +" // to produce an iterator that returns Some(str) for each pattern " +"segments,\n" +" // and then returns None indefinitely.\n" +"}\n" +"\n" +"#[test]\n" +"fn test_matches_without_wildcard() {\n" +" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers\"));\n" +" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/" +"abc-123\"));\n" +" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/abc/" +"books\"));\n" +"\n" +" assert!(!prefix_matches(\"/v1/publishers\", \"/v1\"));\n" +" assert!(!prefix_matches(\"/v1/publishers\", \"/v1/publishersBooks\"));\n" +" assert!(!prefix_matches(\"/v1/publishers\", \"/v1/parent/" +"publishers\"));\n" +"}\n" +"\n" +"#[test]\n" +"fn test_matches_with_wildcard() {\n" +" assert!(prefix_matches(\n" +" \"/v1/publishers/*/books\",\n" +" \"/v1/publishers/foo/books\"\n" +" ));\n" +" assert!(prefix_matches(\n" +" \"/v1/publishers/*/books\",\n" +" \"/v1/publishers/bar/books\"\n" +" ));\n" +" assert!(prefix_matches(\n" +" \"/v1/publishers/*/books\",\n" +" \"/v1/publishers/foo/books/book1\"\n" +" ));\n" +"\n" +" assert!(!prefix_matches(\"/v1/publishers/*/books\", \"/v1/" +"publishers\"));\n" +" assert!(!prefix_matches(\n" +" \"/v1/publishers/*/books\",\n" +" \"/v1/publishers/foo/booksByAuthor\"\n" +" ));\n" +"}\n" +"\n" +"fn main() {}\n" +"```" +msgstr "" + +#: src/exercises/day-3/solutions-morning.md:1 +#, fuzzy +msgid "Day 3 Morning Exercise" +msgstr "Tag 3 Morgengymnastik" + +#: src/exercises/day-3/solutions-morning.md:5 +#, fuzzy +msgid "([back to exercise](simple-gui.md))" +msgstr "([zurück zur Übung](simple-gui.md))" + +#: src/exercises/day-3/solutions-morning.md:7 +msgid "" +"```rust\n" +"pub trait Widget {\n" +" /// Natural width of `self`.\n" +" fn width(&self) -> usize;\n" +"\n" +" /// Draw the widget into a buffer.\n" +" fn draw_into(&self, buffer: &mut dyn std::fmt::Write);\n" +"\n" +" /// Draw the widget on standard output.\n" +" fn draw(&self) {\n" +" let mut buffer = String::new();\n" +" self.draw_into(&mut buffer);\n" +" println!(\"{buffer}\");\n" +" }\n" +"}\n" +"\n" +"pub struct Label {\n" +" label: String,\n" +"}\n" +"\n" +"impl Label {\n" +" fn new(label: &str) -> Label {\n" +" Label {\n" +" label: label.to_owned(),\n" +" }\n" +" }\n" +"}\n" +"\n" +"pub struct Button {\n" +" label: Label,\n" +" callback: Box,\n" +"}\n" +"\n" +"impl Button {\n" +" fn new(label: &str, callback: Box) -> Button {\n" +" Button {\n" +" label: Label::new(label),\n" +" callback,\n" +" }\n" +" }\n" +"}\n" +"\n" +"pub struct Window {\n" +" title: String,\n" +" widgets: Vec>,\n" +"}\n" +"\n" +"impl Window {\n" +" fn new(title: &str) -> Window {\n" +" Window {\n" +" title: title.to_owned(),\n" +" widgets: Vec::new(),\n" +" }\n" +" }\n" +"\n" +" fn add_widget(&mut self, widget: Box) {\n" +" self.widgets.push(widget);\n" +" }\n" +"\n" +" fn inner_width(&self) -> usize {\n" +" std::cmp::max(\n" +" self.title.chars().count(),\n" +" self.widgets.iter().map(|w| w.width()).max().unwrap_or(0),\n" +" )\n" +" }\n" +"}\n" +"\n" +"\n" +"impl Widget for Window {\n" +" fn width(&self) -> usize {\n" +" // Add 4 paddings for borders\n" +" self.inner_width() + 4\n" +" }\n" +"\n" +" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n" +" let mut inner = String::new();\n" +" for widget in &self.widgets {\n" +" widget.draw_into(&mut inner);\n" +" }\n" +"\n" +" let inner_width = self.inner_width();\n" +"\n" +" // TODO: after learning about error handling, you can change\n" +" // draw_into to return Result<(), std::fmt::Error>. Then use\n" +" // the ?-operator here instead of .unwrap().\n" +" writeln!(buffer, \"+-{:- usize {\n" +" self.label.width() + 8 // add a bit of padding\n" +" }\n" +"\n" +" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n" +" let width = self.width();\n" +" let mut label = String::new();\n" +" self.label.draw_into(&mut label);\n" +"\n" +" writeln!(buffer, \"+{:- usize {\n" +" self.label\n" +" .lines()\n" +" .map(|line| line.chars().count())\n" +" .max()\n" +" .unwrap_or(0)\n" +" }\n" +"\n" +" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n" +" writeln!(buffer, \"{}\", &self.label).unwrap();\n" +" }\n" +"}\n" +"\n" +"fn main() {\n" +" let mut window = Window::new(\"Rust GUI Demo 1.23\");\n" +" window.add_widget(Box::new(Label::new(\"This is a small text GUI demo." +"\")));\n" +" window.add_widget(Box::new(Button::new(\n" +" \"Click me!\",\n" +" Box::new(|| println!(\"You clicked the button!\")),\n" +" )));\n" +" window.draw();\n" +"}\n" +"```" +msgstr "" + +#: src/exercises/day-3/solutions-morning.md:147 #, fuzzy msgid "([back to exercise](points-polygons.md))" msgstr "([zurück zur Übung](points-polygons.md))" -#: src/exercises/day-2/solutions-morning.md:7 +#: src/exercises/day-3/solutions-morning.md:149 msgid "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" "#[derive(Debug, Copy, Clone, PartialEq, Eq)]\n" -"// ANCHOR: Point\n" "pub struct Point {\n" -" // ANCHOR_END: Point\n" " x: i32,\n" " y: i32,\n" "}\n" "\n" -"// ANCHOR: Point-impl\n" "impl Point {\n" -" // ANCHOR_END: Point-impl\n" " pub fn new(x: i32, y: i32) -> Point {\n" " Point { x, y }\n" " }\n" @@ -20567,15 +20834,11 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: Polygon\n" "pub struct Polygon {\n" -" // ANCHOR_END: Polygon\n" " points: Vec,\n" "}\n" "\n" -"// ANCHOR: Polygon-impl\n" "impl Polygon {\n" -" // ANCHOR_END: Polygon-impl\n" " pub fn new() -> Polygon {\n" " Polygon { points: Vec::new() }\n" " }\n" @@ -20605,19 +20868,26 @@ msgid "" " }\n" " result += last_point.dist(self.points[0]);\n" " result\n" +" // Alternatively, Iterator::zip() lets us iterate over the points as " +"pairs\n" +" // but we need to pair each point with the next one, and the last " +"point\n" +" // with the first point. The zip() iterator is finished as soon as " +"one of \n" +" // the source iterators is finished, a neat trick is to combine " +"Iterator::cycle\n" +" // with Iterator::skip to create the second iterator for the zip and " +"using map \n" +" // and sum to calculate the total length.\n" " }\n" "}\n" "\n" -"// ANCHOR: Circle\n" "pub struct Circle {\n" -" // ANCHOR_END: Circle\n" " center: Point,\n" " radius: i32,\n" "}\n" "\n" -"// ANCHOR: Circle-impl\n" "impl Circle {\n" -" // ANCHOR_END: Circle-impl\n" " pub fn new(center: Point, radius: i32) -> Circle {\n" " Circle { center, radius }\n" " }\n" @@ -20631,12 +20901,10 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: Shape\n" "pub enum Shape {\n" " Polygon(Polygon),\n" " Circle(Circle),\n" "}\n" -"// ANCHOR_END: Shape\n" "\n" "impl From for Shape {\n" " fn from(poly: Polygon) -> Self {\n" @@ -20659,7 +20927,6 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: unit-tests\n" "#[cfg(test)]\n" "mod tests {\n" " use super::*;\n" @@ -20730,385 +20997,11 @@ msgid "" " assert_eq!(perimeters, vec![15.48, 31.42]);\n" " }\n" "}\n" -"// ANCHOR_END: unit-tests\n" "\n" "fn main() {}\n" "```" msgstr "" -#: src/exercises/day-2/solutions-afternoon.md:1 -#, fuzzy -msgid "Day 2 Afternoon Exercises" -msgstr "Tag 2 Nachmittagsübungen" - -#: src/exercises/day-2/solutions-afternoon.md:5 -#, fuzzy -msgid "([back to exercise](luhn.md))" -msgstr "([zurück zur Übung](luhn.md))" - -#: src/exercises/day-2/solutions-afternoon.md:7 -msgid "" -"```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: luhn\n" -"pub fn luhn(cc_number: &str) -> bool {\n" -" // ANCHOR_END: luhn\n" -" let mut digits_seen = 0;\n" -" let mut sum = 0;\n" -" for (i, ch) in cc_number.chars().rev().filter(|&ch| ch != ' ')." -"enumerate() {\n" -" match ch.to_digit(10) {\n" -" Some(d) => {\n" -" sum += if i % 2 == 1 {\n" -" let dd = d * 2;\n" -" dd / 10 + dd % 10\n" -" } else {\n" -" d\n" -" };\n" -" digits_seen += 1;\n" -" }\n" -" None => return false,\n" -" }\n" -" }\n" -"\n" -" if digits_seen < 2 {\n" -" return false;\n" -" }\n" -"\n" -" sum % 10 == 0\n" -"}\n" -"\n" -"fn main() {\n" -" let cc_number = \"1234 5678 1234 5670\";\n" -" println!(\n" -" \"Is {cc_number} a valid credit card number? {}\",\n" -" if luhn(cc_number) { \"yes\" } else { \"no\" }\n" -" );\n" -"}\n" -"\n" -"// ANCHOR: unit-tests\n" -"#[test]\n" -"fn test_non_digit_cc_number() {\n" -" assert!(!luhn(\"foo\"));\n" -"}\n" -"\n" -"#[test]\n" -"fn test_empty_cc_number() {\n" -" assert!(!luhn(\"\"));\n" -" assert!(!luhn(\" \"));\n" -" assert!(!luhn(\" \"));\n" -" assert!(!luhn(\" \"));\n" -"}\n" -"\n" -"#[test]\n" -"fn test_single_digit_cc_number() {\n" -" assert!(!luhn(\"0\"));\n" -"}\n" -"\n" -"#[test]\n" -"fn test_two_digit_cc_number() {\n" -" assert!(luhn(\" 0 0 \"));\n" -"}\n" -"\n" -"#[test]\n" -"fn test_valid_cc_number() {\n" -" assert!(luhn(\"4263 9826 4026 9299\"));\n" -" assert!(luhn(\"4539 3195 0343 6467\"));\n" -" assert!(luhn(\"7992 7398 713\"));\n" -"}\n" -"\n" -"#[test]\n" -"fn test_invalid_cc_number() {\n" -" assert!(!luhn(\"4223 9826 4026 9299\"));\n" -" assert!(!luhn(\"4539 3195 0343 6476\"));\n" -" assert!(!luhn(\"8273 1232 7352 0569\"));\n" -"}\n" -"// ANCHOR_END: unit-tests\n" -"```" -msgstr "" - -#: src/exercises/day-2/solutions-afternoon.md:99 -#, fuzzy -msgid "([back to exercise](strings-iterators.md))" -msgstr "([zurück zur Übung](strings-iterators.md))" - -#: src/exercises/day-2/solutions-afternoon.md:101 -msgid "" -"```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: prefix_matches\n" -"pub fn prefix_matches(prefix: &str, request_path: &str) -> bool {\n" -" // ANCHOR_END: prefix_matches\n" -" let prefixes = prefix.split('/');\n" -" let request_paths = request_path\n" -" .split('/')\n" -" .map(|p| Some(p))\n" -" .chain(std::iter::once(None));\n" -"\n" -" for (prefix, request_path) in prefixes.zip(request_paths) {\n" -" match request_path {\n" -" Some(request_path) => {\n" -" if (prefix != \"*\") && (prefix != request_path) {\n" -" return false;\n" -" }\n" -" }\n" -" None => return false,\n" -" }\n" -" }\n" -" true\n" -"}\n" -"\n" -"// ANCHOR: unit-tests\n" -"#[test]\n" -"fn test_matches_without_wildcard() {\n" -" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers\"));\n" -" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/" -"abc-123\"));\n" -" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/abc/" -"books\"));\n" -"\n" -" assert!(!prefix_matches(\"/v1/publishers\", \"/v1\"));\n" -" assert!(!prefix_matches(\"/v1/publishers\", \"/v1/publishersBooks\"));\n" -" assert!(!prefix_matches(\"/v1/publishers\", \"/v1/parent/" -"publishers\"));\n" -"}\n" -"\n" -"#[test]\n" -"fn test_matches_with_wildcard() {\n" -" assert!(prefix_matches(\n" -" \"/v1/publishers/*/books\",\n" -" \"/v1/publishers/foo/books\"\n" -" ));\n" -" assert!(prefix_matches(\n" -" \"/v1/publishers/*/books\",\n" -" \"/v1/publishers/bar/books\"\n" -" ));\n" -" assert!(prefix_matches(\n" -" \"/v1/publishers/*/books\",\n" -" \"/v1/publishers/foo/books/book1\"\n" -" ));\n" -"\n" -" assert!(!prefix_matches(\"/v1/publishers/*/books\", \"/v1/" -"publishers\"));\n" -" assert!(!prefix_matches(\n" -" \"/v1/publishers/*/books\",\n" -" \"/v1/publishers/foo/booksByAuthor\"\n" -" ));\n" -"}\n" -"// ANCHOR_END: unit-tests\n" -"\n" -"fn main() {}\n" -"```" -msgstr "" - -#: src/exercises/day-3/solutions-morning.md:1 -#, fuzzy -msgid "Day 3 Morning Exercise" -msgstr "Tag 3 Morgengymnastik" - -#: src/exercises/day-3/solutions-morning.md:5 -#, fuzzy -msgid "([back to exercise](simple-gui.md))" -msgstr "([zurück zur Übung](simple-gui.md))" - -#: src/exercises/day-3/solutions-morning.md:7 -msgid "" -"```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: setup\n" -"pub trait Widget {\n" -" /// Natural width of `self`.\n" -" fn width(&self) -> usize;\n" -"\n" -" /// Draw the widget into a buffer.\n" -" fn draw_into(&self, buffer: &mut dyn std::fmt::Write);\n" -"\n" -" /// Draw the widget on standard output.\n" -" fn draw(&self) {\n" -" let mut buffer = String::new();\n" -" self.draw_into(&mut buffer);\n" -" println!(\"{buffer}\");\n" -" }\n" -"}\n" -"\n" -"pub struct Label {\n" -" label: String,\n" -"}\n" -"\n" -"impl Label {\n" -" fn new(label: &str) -> Label {\n" -" Label {\n" -" label: label.to_owned(),\n" -" }\n" -" }\n" -"}\n" -"\n" -"pub struct Button {\n" -" label: Label,\n" -" callback: Box,\n" -"}\n" -"\n" -"impl Button {\n" -" fn new(label: &str, callback: Box) -> Button {\n" -" Button {\n" -" label: Label::new(label),\n" -" callback,\n" -" }\n" -" }\n" -"}\n" -"\n" -"pub struct Window {\n" -" title: String,\n" -" widgets: Vec>,\n" -"}\n" -"\n" -"impl Window {\n" -" fn new(title: &str) -> Window {\n" -" Window {\n" -" title: title.to_owned(),\n" -" widgets: Vec::new(),\n" -" }\n" -" }\n" -"\n" -" fn add_widget(&mut self, widget: Box) {\n" -" self.widgets.push(widget);\n" -" }\n" -"\n" -" fn inner_width(&self) -> usize {\n" -" std::cmp::max(\n" -" self.title.chars().count(),\n" -" self.widgets.iter().map(|w| w.width()).max().unwrap_or(0),\n" -" )\n" -" }\n" -"}\n" -"\n" -"// ANCHOR_END: setup\n" -"\n" -"// ANCHOR: Window-width\n" -"impl Widget for Window {\n" -" fn width(&self) -> usize {\n" -" // ANCHOR_END: Window-width\n" -" // Add 4 paddings for borders\n" -" self.inner_width() + 4\n" -" }\n" -"\n" -" // ANCHOR: Window-draw_into\n" -" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n" -" // ANCHOR_END: Window-draw_into\n" -" let mut inner = String::new();\n" -" for widget in &self.widgets {\n" -" widget.draw_into(&mut inner);\n" -" }\n" -"\n" -" let inner_width = self.inner_width();\n" -"\n" -" // TODO: after learning about error handling, you can change\n" -" // draw_into to return Result<(), std::fmt::Error>. Then use\n" -" // the ?-operator here instead of .unwrap().\n" -" writeln!(buffer, \"+-{:- usize {\n" -" // ANCHOR_END: Button-width\n" -" self.label.width() + 8 // add a bit of padding\n" -" }\n" -"\n" -" // ANCHOR: Button-draw_into\n" -" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n" -" // ANCHOR_END: Button-draw_into\n" -" let width = self.width();\n" -" let mut label = String::new();\n" -" self.label.draw_into(&mut label);\n" -"\n" -" writeln!(buffer, \"+{:- usize {\n" -" // ANCHOR_END: Label-width\n" -" self.label\n" -" .lines()\n" -" .map(|line| line.chars().count())\n" -" .max()\n" -" .unwrap_or(0)\n" -" }\n" -"\n" -" // ANCHOR: Label-draw_into\n" -" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n" -" // ANCHOR_END: Label-draw_into\n" -" writeln!(buffer, \"{}\", &self.label).unwrap();\n" -" }\n" -"}\n" -"\n" -"// ANCHOR: main\n" -"fn main() {\n" -" let mut window = Window::new(\"Rust GUI Demo 1.23\");\n" -" window.add_widget(Box::new(Label::new(\"This is a small text GUI demo." -"\")));\n" -" window.add_widget(Box::new(Button::new(\n" -" \"Click me!\",\n" -" Box::new(|| println!(\"You clicked the button!\")),\n" -" )));\n" -" window.draw();\n" -"}\n" -"// ANCHOR_END: main\n" -"```" -msgstr "" - #: src/exercises/day-3/solutions-afternoon.md:1 #, fuzzy msgid "Day 3 Afternoon Exercises" @@ -21122,25 +21015,10 @@ msgstr "([zurück zur Übung](safe-ffi-wrapper.md))" #: src/exercises/day-3/solutions-afternoon.md:7 msgid "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: ffi\n" "mod ffi {\n" " use std::os::raw::{c_char, c_int};\n" " #[cfg(not(target_os = \"macos\"))]\n" -" use std::os::raw::{c_long, c_ulong, c_ushort};\n" +" use std::os::raw::{c_long, c_ulong, c_ushort, c_uchar};\n" "\n" " // Opaque type. See https://doc.rust-lang.org/nomicon/ffi.html.\n" " #[repr(C)]\n" @@ -21150,23 +21028,25 @@ msgid "" "PhantomPinned)>,\n" " }\n" "\n" -" // Layout as per readdir(3) and definitions in /usr/include/x86_64-linux-" -"gnu.\n" +" // Layout according to the Linux man page for readdir(3), where ino_t " +"and\n" +" // off_t are resolved according to the definitions in\n" +" // /usr/include/x86_64-linux-gnu/{sys/types.h, bits/typesizes.h}.\n" " #[cfg(not(target_os = \"macos\"))]\n" " #[repr(C)]\n" " pub struct dirent {\n" -" pub d_ino: c_long,\n" -" pub d_off: c_ulong,\n" +" pub d_ino: c_ulong,\n" +" pub d_off: c_long,\n" " pub d_reclen: c_ushort,\n" -" pub d_type: c_char,\n" +" pub d_type: c_uchar,\n" " pub d_name: [c_char; 256],\n" " }\n" "\n" -" // Layout as per man entry for dirent\n" -" #[cfg(target_os = \"macos\")]\n" +" // Layout according to the macOS man page for dir(5).\n" +" #[cfg(all(target_os = \"macos\"))]\n" " #[repr(C)]\n" " pub struct dirent {\n" -" pub d_ino: u64,\n" +" pub d_fileno: u64,\n" " pub d_seekoff: u64,\n" " pub d_reclen: u16,\n" " pub d_namlen: u16,\n" @@ -21176,7 +21056,22 @@ msgid "" "\n" " extern \"C\" {\n" " pub fn opendir(s: *const c_char) -> *mut DIR;\n" +"\n" +" #[cfg(not(all(target_os = \"macos\", target_arch = \"x86_64\")))]\n" " pub fn readdir(s: *mut DIR) -> *const dirent;\n" +"\n" +" // See https://github.com/rust-lang/libc/issues/414 and the section " +"on\n" +" // _DARWIN_FEATURE_64_BIT_INODE in the macOS man page for stat(2).\n" +" //\n" +" // \"Platforms that existed before these updates were available\" " +"refers\n" +" // to macOS (as opposed to iOS / wearOS / etc.) on Intel and " +"PowerPC.\n" +" #[cfg(all(target_os = \"macos\", target_arch = \"x86_64\"))]\n" +" #[link_name = \"readdir$INODE64\"]\n" +" pub fn readdir(s: *mut DIR) -> *const dirent;\n" +"\n" " pub fn closedir(s: *mut DIR) -> c_int;\n" " }\n" "}\n" @@ -21189,14 +21084,11 @@ msgid "" " path: CString,\n" " dir: *mut ffi::DIR,\n" "}\n" -"// ANCHOR_END: ffi\n" "\n" -"// ANCHOR: DirectoryIterator\n" "impl DirectoryIterator {\n" " fn new(path: &str) -> Result {\n" " // Call opendir and return a Ok value if that worked,\n" " // otherwise return Err with a message.\n" -" // ANCHOR_END: DirectoryIterator\n" " let path = CString::new(path).map_err(|err| format!(\"Invalid path: " "{err}\"))?;\n" " // SAFETY: path.as_ptr() cannot be NULL.\n" @@ -21209,12 +21101,10 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: Iterator\n" "impl Iterator for DirectoryIterator {\n" " type Item = OsString;\n" " fn next(&mut self) -> Option {\n" " // Keep calling readdir until we get a NULL pointer back.\n" -" // ANCHOR_END: Iterator\n" " // SAFETY: self.dir is never NULL.\n" " let dirent = unsafe { ffi::readdir(self.dir) };\n" " if dirent.is_null() {\n" @@ -21229,11 +21119,9 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: Drop\n" "impl Drop for DirectoryIterator {\n" " fn drop(&mut self) {\n" " // Call closedir as needed.\n" -" // ANCHOR_END: Drop\n" " if !self.dir.is_null() {\n" " // SAFETY: self.dir is not NULL.\n" " if unsafe { ffi::closedir(self.dir) } != 0 {\n" @@ -21243,13 +21131,11 @@ msgid "" " }\n" "}\n" "\n" -"// ANCHOR: main\n" "fn main() -> Result<(), String> {\n" " let iter = DirectoryIterator::new(\".\")?;\n" " println!(\"files: {:#?}\", iter.collect::>());\n" " Ok(())\n" "}\n" -"// ANCHOR_END: main\n" "\n" "#[cfg(test)]\n" "mod tests {\n" @@ -21307,21 +21193,6 @@ msgstr "([zurück zur Übung](for-loops.md))" #: src/exercises/bare-metal/solutions-morning.md:7 msgid "" "```rust,compile_fail\n" -"// Copyright 2023 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: top\n" "#![no_main]\n" "#![no_std]\n" "\n" @@ -21329,7 +21200,6 @@ msgid "" "\n" "use core::fmt::Write;\n" "use cortex_m_rt::entry;\n" -"// ANCHOR_END: top\n" "use core::cmp::{max, min};\n" "use lsm303agr::{AccelOutputDataRate, Lsm303agr, MagOutputDataRate};\n" "use microbit::display::blocking::Display;\n" @@ -21343,7 +21213,6 @@ msgid "" "const COMPASS_SCALE: i32 = 30000;\n" "const ACCELEROMETER_SCALE: i32 = 700;\n" "\n" -"// ANCHOR: main\n" "#[entry]\n" "fn main() -> ! {\n" " let board = Board::take().unwrap();\n" @@ -21357,7 +21226,6 @@ msgid "" " );\n" "\n" " // Set up the I2C controller and Inertial Measurement Unit.\n" -" // ANCHOR_END: main\n" " writeln!(serial, \"Setting up IMU...\").unwrap();\n" " let i2c = Twim::new(board.TWIM0, board.i2c_internal.into(), FREQUENCY_A::" "K100);\n" @@ -21374,12 +21242,10 @@ msgid "" " let mut mode = Mode::Compass;\n" " let mut button_pressed = false;\n" "\n" -" // ANCHOR: loop\n" " writeln!(serial, \"Ready.\").unwrap();\n" "\n" " loop {\n" " // Read compass data and log it to the serial port.\n" -" // ANCHOR_END: loop\n" " while !(imu.mag_status().unwrap().xyz_new_data\n" " && imu.accel_status().unwrap().xyz_new_data)\n" " {}\n" @@ -21483,28 +21349,12 @@ msgstr "" #: src/exercises/bare-metal/solutions-afternoon.md:9 msgid "" "```rust,compile_fail\n" -"// Copyright 2023 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: top\n" "#![no_main]\n" "#![no_std]\n" "\n" "mod exceptions;\n" "mod logger;\n" "mod pl011;\n" -"// ANCHOR_END: top\n" "mod pl031;\n" "\n" "use crate::pl031::Rtc;\n" @@ -21512,7 +21362,6 @@ msgid "" "use arm_gic::{irq_enable, wfi};\n" "use chrono::{TimeZone, Utc};\n" "use core::hint::spin_loop;\n" -"// ANCHOR: imports\n" "use crate::pl011::Uart;\n" "use arm_gic::gicv3::GicV3;\n" "use core::panic::PanicInfo;\n" @@ -21526,14 +21375,12 @@ msgid "" "\n" "/// Base address of the primary PL011 UART.\n" "const PL011_BASE_ADDRESS: *mut u32 = 0x900_0000 as _;\n" -"// ANCHOR_END: imports\n" "\n" "/// Base address of the PL031 RTC.\n" "const PL031_BASE_ADDRESS: *mut u32 = 0x901_0000 as _;\n" "/// The IRQ used by the PL031 RTC.\n" "const PL031_IRQ: IntId = IntId::spi(2);\n" "\n" -"// ANCHOR: main\n" "#[no_mangle]\n" "extern \"C\" fn main(x0: u64, x1: u64, x2: u64, x3: u64) {\n" " // Safe because `PL011_BASE_ADDRESS` is the base address of a PL011 " @@ -21551,7 +21398,6 @@ msgid "" " let mut gic = unsafe { GicV3::new(GICD_BASE_ADDRESS, " "GICR_BASE_ADDRESS) };\n" " gic.setup();\n" -" // ANCHOR_END: main\n" "\n" " // Safe because `PL031_BASE_ADDRESS` is the base address of a PL031 " "device,\n" @@ -21613,7 +21459,6 @@ msgid "" " );\n" " info!(\"Finished waiting\");\n" "\n" -" // ANCHOR: main_end\n" " system_off::().unwrap();\n" "}\n" "\n" @@ -21623,31 +21468,16 @@ msgid "" " system_off::().unwrap();\n" " loop {}\n" "}\n" -"// ANCHOR_END: main_end\n" "```" msgstr "" -#: src/exercises/bare-metal/solutions-afternoon.md:149 +#: src/exercises/bare-metal/solutions-afternoon.md:127 msgid "`pl031.rs`:" msgstr "" -#: src/exercises/bare-metal/solutions-afternoon.md:151 +#: src/exercises/bare-metal/solutions-afternoon.md:129 msgid "" "```rust\n" -"// Copyright 2023 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" "use core::ptr::{addr_of, addr_of_mut};\n" "\n" "#[repr(C, align(4))]\n" @@ -21728,8 +21558,8 @@ msgid "" "\n" " /// Returns whether there is currently an interrupt pending.\n" " ///\n" -" /// This should be true iff `matched` returns true and the interrupt is\n" -" /// masked.\n" +" /// This should be true if and only if `matched` returns true and the\n" +" /// interrupt is masked.\n" " pub fn interrupt_pending(&self) -> bool {\n" " // Safe because we know that self.registers points to the control\n" " // registers of a PL031 device which is appropriately mapped.\n" @@ -21778,21 +21608,6 @@ msgstr "([zurück zur Übung](dining-philosophers.md))" #: src/exercises/concurrency/solutions-morning.md:7 msgid "" "```rust\n" -"// Copyright 2022 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: Philosopher\n" "use std::sync::{mpsc, Arc, Mutex};\n" "use std::thread;\n" "use std::time::Duration;\n" @@ -21801,29 +21616,23 @@ msgid "" "\n" "struct Philosopher {\n" " name: String,\n" -" // ANCHOR_END: Philosopher\n" " left_fork: Arc>,\n" " right_fork: Arc>,\n" " thoughts: mpsc::SyncSender,\n" "}\n" "\n" -"// ANCHOR: Philosopher-think\n" "impl Philosopher {\n" " fn think(&self) {\n" " self.thoughts\n" " .send(format!(\"Eureka! {} has a new idea!\", &self.name))\n" " .unwrap();\n" " }\n" -" // ANCHOR_END: Philosopher-think\n" "\n" -" // ANCHOR: Philosopher-eat\n" " fn eat(&self) {\n" -" // ANCHOR_END: Philosopher-eat\n" " println!(\"{} is trying to eat\", &self.name);\n" " let left = self.left_fork.lock().unwrap();\n" " let right = self.right_fork.lock().unwrap();\n" "\n" -" // ANCHOR: Philosopher-eat-end\n" " println!(\"{} is eating...\", &self.name);\n" " thread::sleep(Duration::from_millis(10));\n" " }\n" @@ -21833,7 +21642,6 @@ msgid "" " &[\"Socrates\", \"Plato\", \"Aristotle\", \"Thales\", \"Pythagoras\"];\n" "\n" "fn main() {\n" -" // ANCHOR_END: Philosopher-eat-end\n" " let (tx, rx) = mpsc::sync_channel(10);\n" "\n" " let forks = (0..PHILOSOPHERS.len())\n" @@ -21842,8 +21650,8 @@ msgid "" "\n" " for i in 0..forks.len() {\n" " let tx = tx.clone();\n" -" let mut left_fork = forks[i].clone();\n" -" let mut right_fork = forks[(i + 1) % forks.len()].clone();\n" +" let mut left_fork = Arc::clone(&forks[i]);\n" +" let mut right_fork = Arc::clone(&forks[(i + 1) % forks.len()]);\n" "\n" " // To avoid a deadlock, we have to break the symmetry\n" " // somewhere. This will swap the forks without deinitializing\n" @@ -21875,6 +21683,193 @@ msgid "" "```" msgstr "" +#: src/exercises/concurrency/solutions-morning.md:82 +#, fuzzy +msgid "Link Checker" +msgstr "Link Überprüfung mit mehreren Ausführungssträngen" + +#: src/exercises/concurrency/solutions-morning.md:84 +#, fuzzy +msgid "([back to exercise](link-checker.md))" +msgstr "([zurück zur Übung](luhn.md))" + +#: src/exercises/concurrency/solutions-morning.md:86 +msgid "" +"```rust,compile_fail\n" +"use std::{sync::Arc, sync::Mutex, sync::mpsc, thread};\n" +"\n" +"use reqwest::{blocking::Client, Url};\n" +"use scraper::{Html, Selector};\n" +"use thiserror::Error;\n" +"\n" +"#[derive(Error, Debug)]\n" +"enum Error {\n" +" #[error(\"request error: {0}\")]\n" +" ReqwestError(#[from] reqwest::Error),\n" +" #[error(\"bad http response: {0}\")]\n" +" BadResponse(String),\n" +"}\n" +"\n" +"#[derive(Debug)]\n" +"struct CrawlCommand {\n" +" url: Url,\n" +" extract_links: bool,\n" +"}\n" +"\n" +"fn visit_page(client: &Client, command: &CrawlCommand) -> Result, " +"Error> {\n" +" println!(\"Checking {:#}\", command.url);\n" +" let response = client.get(command.url.clone()).send()?;\n" +" if !response.status().is_success() {\n" +" return Err(Error::BadResponse(response.status().to_string()));\n" +" }\n" +"\n" +" let mut link_urls = Vec::new();\n" +" if !command.extract_links {\n" +" return Ok(link_urls);\n" +" }\n" +"\n" +" let base_url = response.url().to_owned();\n" +" let body_text = response.text()?;\n" +" let document = Html::parse_document(&body_text);\n" +"\n" +" let selector = Selector::parse(\"a\").unwrap();\n" +" let href_values = document\n" +" .select(&selector)\n" +" .filter_map(|element| element.value().attr(\"href\"));\n" +" for href in href_values {\n" +" match base_url.join(href) {\n" +" Ok(link_url) => {\n" +" link_urls.push(link_url);\n" +" }\n" +" Err(err) => {\n" +" println!(\"On {base_url:#}: ignored unparsable {href:?}: " +"{err}\");\n" +" }\n" +" }\n" +" }\n" +" Ok(link_urls)\n" +"}\n" +"\n" +"struct CrawlState {\n" +" domain: String,\n" +" visited_pages: std::collections::HashSet,\n" +"}\n" +"\n" +"impl CrawlState {\n" +" fn new(start_url: &Url) -> CrawlState {\n" +" let mut visited_pages = std::collections::HashSet::new();\n" +" visited_pages.insert(start_url.as_str().to_string());\n" +" CrawlState {\n" +" domain: start_url.domain().unwrap().to_string(),\n" +" visited_pages,\n" +" }\n" +" }\n" +"\n" +" /// Determine whether links within the given page should be extracted.\n" +" fn should_extract_links(&self, url: &Url) -> bool {\n" +" let Some(url_domain) = url.domain() else {\n" +" return false;\n" +" };\n" +" url_domain == self.domain\n" +" }\n" +"\n" +" /// Mark the given page as visited, returning true if it had already\n" +" /// been visited.\n" +" fn mark_visited(&mut self, url: &Url) -> bool {\n" +" self.visited_pages.insert(url.as_str().to_string())\n" +" }\n" +"}\n" +"\n" +"type CrawlResult = Result, (Url, Error)>;\n" +"fn spawn_crawler_threads(\n" +" command_receiver: mpsc::Receiver,\n" +" result_sender: mpsc::Sender,\n" +" thread_count: u32,\n" +") {\n" +" let command_receiver = Arc::new(Mutex::new(command_receiver));\n" +"\n" +" for _ in 0..thread_count {\n" +" let result_sender = result_sender.clone();\n" +" let command_receiver = command_receiver.clone();\n" +" thread::spawn(move || {\n" +" let client = Client::new();\n" +" loop {\n" +" let command_result = {\n" +" let receiver_guard = command_receiver.lock().unwrap();\n" +" receiver_guard.recv()\n" +" };\n" +" let Ok(crawl_command) = command_result else {\n" +" // The sender got dropped. No more commands coming in.\n" +" break;\n" +" };\n" +" let crawl_result = match visit_page(&client, &crawl_command) " +"{\n" +" Ok(link_urls) => Ok(link_urls),\n" +" Err(error) => Err((crawl_command.url, error)),\n" +" };\n" +" result_sender.send(crawl_result).unwrap();\n" +" }\n" +" });\n" +" }\n" +"}\n" +"\n" +"fn control_crawl(\n" +" start_url: Url,\n" +" command_sender: mpsc::Sender,\n" +" result_receiver: mpsc::Receiver,\n" +") -> Vec {\n" +" let mut crawl_state = CrawlState::new(&start_url);\n" +" let start_command = CrawlCommand { url: start_url, extract_links: " +"true };\n" +" command_sender.send(start_command).unwrap();\n" +" let mut pending_urls = 1;\n" +"\n" +" let mut bad_urls = Vec::new();\n" +" while pending_urls > 0 {\n" +" let crawl_result = result_receiver.recv().unwrap();\n" +" pending_urls -= 1;\n" +"\n" +" match crawl_result {\n" +" Ok(link_urls) => {\n" +" for url in link_urls {\n" +" if crawl_state.mark_visited(&url) {\n" +" let extract_links = crawl_state." +"should_extract_links(&url);\n" +" let crawl_command = CrawlCommand { url, " +"extract_links };\n" +" command_sender.send(crawl_command).unwrap();\n" +" pending_urls += 1;\n" +" }\n" +" }\n" +" }\n" +" Err((url, error)) => {\n" +" bad_urls.push(url);\n" +" println!(\"Got crawling error: {:#}\", error);\n" +" continue;\n" +" }\n" +" }\n" +" }\n" +" bad_urls\n" +"}\n" +"\n" +"fn check_links(start_url: Url) -> Vec {\n" +" let (result_sender, result_receiver) = mpsc::channel::();\n" +" let (command_sender, command_receiver) = mpsc::channel::" +"();\n" +" spawn_crawler_threads(command_receiver, result_sender, 16);\n" +" control_crawl(start_url, command_sender, result_receiver)\n" +"}\n" +"\n" +"fn main() {\n" +" let start_url = reqwest::Url::parse(\"https://www.google.org\")." +"unwrap();\n" +" let bad_urls = check_links(start_url);\n" +" println!(\"Bad URLs: {:#?}\", bad_urls);\n" +"}\n" +"```" +msgstr "" + #: src/exercises/concurrency/solutions-afternoon.md:1 #, fuzzy msgid "Concurrency Afternoon Exercise" @@ -21888,21 +21883,6 @@ msgstr "([zurück zur Übung](dining-philosophers.md))" #: src/exercises/concurrency/solutions-afternoon.md:7 msgid "" "```rust,compile_fail\n" -"// Copyright 2023 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: Philosopher\n" "use std::sync::Arc;\n" "use tokio::time;\n" "use tokio::sync::mpsc::{self, Sender};\n" @@ -21912,13 +21892,11 @@ msgid "" "\n" "struct Philosopher {\n" " name: String,\n" -" // ANCHOR_END: Philosopher\n" " left_fork: Arc>,\n" " right_fork: Arc>,\n" " thoughts: Sender,\n" "}\n" "\n" -"// ANCHOR: Philosopher-think\n" "impl Philosopher {\n" " async fn think(&self) {\n" " self.thoughts\n" @@ -21926,12 +21904,9 @@ msgid "" "await\n" " .unwrap();\n" " }\n" -" // ANCHOR_END: Philosopher-think\n" "\n" -" // ANCHOR: Philosopher-eat\n" " async fn eat(&self) {\n" " // Pick up forks...\n" -" // ANCHOR_END: Philosopher-eat\n" " let _first_lock = self.left_fork.lock().await;\n" " // Add a delay before picking the second fork to allow the " "execution\n" @@ -21939,13 +21914,10 @@ msgid "" " time::sleep(time::Duration::from_millis(1)).await;\n" " let _second_lock = self.right_fork.lock().await;\n" "\n" -" // ANCHOR: Philosopher-eat-body\n" " println!(\"{} is eating...\", &self.name);\n" " time::sleep(time::Duration::from_millis(5)).await;\n" -" // ANCHOR_END: Philosopher-eat-body\n" "\n" " // The locks are dropped here\n" -" // ANCHOR: Philosopher-eat-end\n" " }\n" "}\n" "\n" @@ -21954,7 +21926,6 @@ msgid "" "\n" "#[tokio::main]\n" "async fn main() {\n" -" // ANCHOR_END: Philosopher-eat-end\n" " // Create forks\n" " let mut forks = vec![];\n" " (0..PHILOSOPHERS.len()).for_each(|_| forks.push(Arc::new(Mutex::" @@ -21965,14 +21936,19 @@ msgid "" " let mut philosophers = vec![];\n" " let (tx, rx) = mpsc::channel(10);\n" " for (i, name) in PHILOSOPHERS.iter().enumerate() {\n" -" let left_fork = forks[i].clone();\n" -" let right_fork = forks[(i + 1) % PHILOSOPHERS.len()].clone();\n" +" let left_fork = Arc::clone(&forks[i]);\n" +" let right_fork = Arc::clone(&forks[(i + 1) % PHILOSOPHERS." +"len()]);\n" +" // To avoid a deadlock, we have to break the symmetry\n" +" // somewhere. This will swap the forks without deinitializing\n" +" // either of them.\n" +" if i == 0 {\n" +" std::mem::swap(&mut left_fork, &mut right_fork);\n" +" }\n" " philosophers.push(Philosopher {\n" " name: name.to_string(),\n" -" left_fork: if i % 2 == 0 { left_fork.clone() } else " -"{ right_fork.clone() },\n" -" right_fork: if i % 2 == 0 { right_fork } else " -"{ left_fork },\n" +" left_fork,\n" +" right_fork,\n" " thoughts: tx.clone(),\n" " });\n" " }\n" @@ -21999,44 +21975,27 @@ msgid "" "```" msgstr "" -#: src/exercises/concurrency/solutions-afternoon.md:115 +#: src/exercises/concurrency/solutions-afternoon.md:97 #, fuzzy msgid "([back to exercise](chat-app.md))" msgstr "([zurück zur Übung](luhn.md))" -#: src/exercises/concurrency/solutions-afternoon.md:119 +#: src/exercises/concurrency/solutions-afternoon.md:101 msgid "" "```rust,compile_fail\n" -"// Copyright 2023 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: setup\n" "use futures_util::sink::SinkExt;\n" +"use futures_util::stream::StreamExt;\n" "use std::error::Error;\n" "use std::net::SocketAddr;\n" "use tokio::net::{TcpListener, TcpStream};\n" "use tokio::sync::broadcast::{channel, Sender};\n" "use tokio_websockets::{Message, ServerBuilder, WebsocketStream};\n" -"// ANCHOR_END: setup\n" "\n" -"// ANCHOR: handle_connection\n" "async fn handle_connection(\n" " addr: SocketAddr,\n" " mut ws_stream: WebsocketStream,\n" " bcast_tx: Sender,\n" ") -> Result<(), Box> {\n" -" // ANCHOR_END: handle_connection\n" "\n" " ws_stream\n" " .send(Message::text(\"Welcome to chat! Type a message\".into()))\n" @@ -22052,9 +22011,10 @@ msgid "" " incoming = ws_stream.next() => {\n" " match incoming {\n" " Some(Ok(msg)) => {\n" -" let msg = msg.as_text()?;\n" -" println!(\"From client {addr:?} {msg:?}\");\n" -" bcast_tx.send(msg.into())?;\n" +" if let Some(text) = msg.as_text() {\n" +" println!(\"From client {addr:?} {text:?}\");\n" +" bcast_tx.send(text.into())?;\n" +" }\n" " }\n" " Some(Err(err)) => return Err(err.into()),\n" " None => return Ok(()),\n" @@ -22065,7 +22025,6 @@ msgid "" " }\n" " }\n" " }\n" -" // ANCHOR: main\n" "}\n" "\n" "#[tokio::main]\n" @@ -22087,28 +22046,13 @@ msgid "" " });\n" " }\n" "}\n" -"// ANCHOR_END: main\n" "```" msgstr "" -#: src/exercises/concurrency/solutions-afternoon.md:204 +#: src/exercises/concurrency/solutions-afternoon.md:168 msgid "" "```rust,compile_fail\n" -"// Copyright 2023 Google LLC\n" -"//\n" -"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" -"// you may not use this file except in compliance with the License.\n" -"// You may obtain a copy of the License at\n" -"//\n" -"// http://www.apache.org/licenses/LICENSE-2.0\n" -"//\n" -"// Unless required by applicable law or agreed to in writing, software\n" -"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" -"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" -"// See the License for the specific language governing permissions and\n" -"// limitations under the License.\n" -"\n" -"// ANCHOR: setup\n" +"use futures_util::stream::StreamExt;\n" "use futures_util::SinkExt;\n" "use http::Uri;\n" "use tokio::io::{AsyncBufReadExt, BufReader};\n" @@ -22116,31 +22060,32 @@ msgid "" "\n" "#[tokio::main]\n" "async fn main() -> Result<(), tokio_websockets::Error> {\n" -" let mut ws_stream = ClientBuilder::from_uri(Uri::" -"from_static(\"ws://127.0.0.1:2000\"))\n" -" .connect()\n" -" .await?;\n" +" let (mut ws_stream, _) =\n" +" ClientBuilder::from_uri(Uri::from_static(\"ws://127.0.0.1:2000\"))\n" +" .connect()\n" +" .await?;\n" "\n" " let stdin = tokio::io::stdin();\n" -" let mut stdin = BufReader::new(stdin);\n" +" let mut stdin = BufReader::new(stdin).lines();\n" "\n" -" // ANCHOR_END: setup\n" " // Continuous loop for concurrently sending and receiving messages.\n" " loop {\n" -" let mut line = String::new();\n" " tokio::select! {\n" " incoming = ws_stream.next() => {\n" " match incoming {\n" -" Some(Ok(msg)) => println!(\"From server: {}\", msg." -"as_text()?),\n" +" Some(Ok(msg)) => {\n" +" if let Some(text) = msg.as_text() {\n" +" println!(\"From server: {}\", text);\n" +" }\n" +" },\n" " Some(Err(err)) => return Err(err.into()),\n" " None => return Ok(()),\n" " }\n" " }\n" -" res = stdin.read_line(&mut line) => {\n" +" res = stdin.next_line() => {\n" " match res {\n" -" Ok(0) => return Ok(()),\n" -" Ok(_) => ws_stream.send(Message::text(line.trim_end()." +" Ok(None) => return Ok(()),\n" +" Ok(Some(line)) => ws_stream.send(Message::text(line." "to_string())).await?,\n" " Err(err) => return Err(err.into()),\n" " }\n" @@ -22151,3 +22096,333 @@ msgid "" "}\n" "```" msgstr "" + +#~ msgid "Comparison" +#~ msgstr "Vergleich" + +#~ msgid "GitHub contributors" +#~ msgstr "Github Beiträger" + +#~ msgid "GitHub stars" +#~ msgstr "Github Sterne" + +#~ msgid "The course is fast paced and covers a lot of ground:" +#~ msgstr "Der Kurs geht in schnellem Tempo voran und deckt viele Themen ab:" + +#~ msgid "Day 1: Basic Rust, ownership and the borrow checker." +#~ msgstr "" +#~ "Tag 1: Rust Grundlagen, Eigentümerschaft (ownership) und der " +#~ "Ausleihenprüfer (borrow checker)." + +#~ msgid "Concurrency" +#~ msgstr "Nebenläufigkeit" + +#~ msgid "Rustup (Recommended)" +#~ msgstr "Rustup (empfohlen)" + +#~ msgid "" +#~ "You can follow the instructions to install cargo and rust compiler, among " +#~ "other standard ecosystem tools with the [rustup](https://rust-analyzer." +#~ "github.io/) tool, which is maintained by the Rust Foundation." +#~ msgstr "" +#~ "Du kannst den Anweisungen zur Installation von Cargo und des Rust-" +#~ "Compilers sowie anderer Standard-Ökosystem-Tools mit dem Tool [rustup]" +#~ "(https://rust-analyzer.github.io/) folgen, das von der Rust Foundation " +#~ "verwaltet wird." + +#~ msgid "Package Managers" +#~ msgstr "Paketmanager" + +#~ msgid "Debian" +#~ msgstr "Debian" + +#~ msgid "" +#~ "This will allow \\[rust-analyzer\\]\\[1\\] to jump to the definitions. We " +#~ "suggest using [VS Code](https://code.visualstudio.com/) to edit the code " +#~ "(but any LSP compatible editor works)." +#~ msgstr "" +#~ "Dadurch kann \\[rust-analyzer\\]\\[1\\] zu den Definitionen springen. Wir " +#~ "empfehlen die Verwendung von [VS Code](https://code.visualstudio.com/), " +#~ "um Code zu bearbeiten (aber jeder LSP-kompatible Editor funktioniert " +#~ "auch)." + +#~ msgid "" +#~ "Some folks also like to use the [JetBrains](https://www.jetbrains.com/" +#~ "clion/) family of IDEs, which do their own analysis but have their own " +#~ "tradeoffs. If you prefer them, you can install the [Rust Plugin](https://" +#~ "www.jetbrains.com/rust/). Please take note that as of January 2023 " +#~ "debugging only works on the CLion version of the JetBrains IDEA suite." +#~ msgstr "" +#~ "Einige Leute verwenden auch gerne die [JetBrains](https://www.jetbrains." +#~ "com/clion/)\\-Familie von IDEs, die eigene Code-Analysen durchführen, " +#~ "aber auch eigene Einschränkungen haben. Wenn du diese IDEs bevorzugst, " +#~ "kannst du das \\[Rust-Plugin\\] [5](https://www.jetbrains.com/rust/) " +#~ "installieren. Bitte beachte, dass das Debuggen seit Januar 2023 nur auf " +#~ "der CLion-Version funktioniert, welche Teil der JetBrains IDEA-Suite ist." + +#~ msgid "" +#~ "```shell\n" +#~ "$ cargo new exercise\n" +#~ " Created binary (application) `exercise` package\n" +#~ "```" +#~ msgstr "" +#~ "```shell\n" +#~ "$ cargo new exercise\n" +#~ " Created binary (application) `exercise` package\n" +#~ "```" + +#~ msgid "" +#~ "```shell\n" +#~ "$ cd exercise\n" +#~ "$ cargo run\n" +#~ " Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n" +#~ " Finished dev [unoptimized + debuginfo] target(s) in 0.75s\n" +#~ " Running `target/debug/exercise`\n" +#~ "Hello, world!\n" +#~ "```" +#~ msgstr "" +#~ "```shell\n" +#~ "$ cd exercise\n" +#~ "$ cargo run\n" +#~ " Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n" +#~ " Finished dev [unoptimized + debuginfo] target(s) in 0.75s\n" +#~ " Running `target/debug/exercise`\n" +#~ "Hello, world!\n" +#~ "```" + +#~ msgid "" +#~ "```shell\n" +#~ "$ cargo run\n" +#~ " Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n" +#~ " Finished dev [unoptimized + debuginfo] target(s) in 0.24s\n" +#~ " Running `target/debug/exercise`\n" +#~ "Edit me!\n" +#~ "```" +#~ msgstr "" +#~ "```shell\n" +#~ "$ cargo run\n" +#~ " Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n" +#~ " Finished dev [unoptimized + debuginfo] target(s) in 0.24s\n" +#~ " Running `target/debug/exercise`\n" +#~ "Edit me!\n" +#~ "```" + +#~ msgid "" +#~ "```rust,editable,compile_fail\n" +#~ "fn new(width: u32, height: u32) -> Rectangle {\n" +#~ " Rectangle { width, height }\n" +#~ "}\n" +#~ "```" +#~ msgstr "" +#~ "```rust,editable,compile_fail\n" +#~ "fn new(width: u32, height: u32) -> Rectangle {\n" +#~ " Rectangle { width, height }\n" +#~ "}\n" +#~ "```" + +#~ msgid "" +#~ "After looking at the exercises, you can look at the \\[solutions\\] " +#~ "provided." +#~ msgstr "" +#~ "Nachdem Du Dir die Übungen angesehen hast, kannst Du Dir die " +#~ "bereitgestellten \\[Lösungen\\] ansehen." + +#~ msgid "" +#~ "Note that since `println!` is a macro, `x` is not moved, even using the " +#~ "function like syntax of `println!(\"x: {}\", x)`" +#~ msgstr "" +#~ "Beachte, dass, da `println!` ein Makro ist, `x` nicht verschoben (moved) " +#~ "wird, selbst wenn die funktionsähnliche Syntax von `println!(\"x: {}\", " +#~ "x)` verwendet wird." + +#~ msgid "Global state is managed with static and constant variables." +#~ msgstr "" +#~ "Der globale Status (global state) wird mit statischen und konstanten " +#~ "Variablen verwaltet." + +#~ msgid "You can declare compile-time constants:" +#~ msgstr "Du kannst Kompilierzeitkonstanten deklarieren:" + +#~ msgid "You can also declare static variables:" +#~ msgstr "Sie können auch statische Variablen deklarieren:" + +#~ msgid "" +#~ "We will look at mutating static data in the [chapter on Unsafe Rust](../" +#~ "unsafe.md)." +#~ msgstr "" +#~ "Wir werden uns im [Kapitel über unsicheres Rust](../unsafe.md) mit " +#~ "mutierenden statischen Daten befassen." + +#, fuzzy +#~ msgid "" +#~ "Depending on which abstraction (or combination of abstractions) you " +#~ "choose, can be a single unique pointer, reference counted, or atomically " +#~ "reference counted." +#~ msgstr "" +#~ "Je nachdem, welche Abstraktion (oder Kombination von Abstraktionen) Sie " +#~ "wählen, kann es sich um einen einzelnen eindeutigen Zeiger, eine " +#~ "Referenzzählung oder eine atomare Referenzzählung handeln." + +#, fuzzy +#~ msgid "Here is a rough comparison of the memory management techniques." +#~ msgstr "Hier ist ein grober Vergleich der Speicherverwaltungstechniken." + +#, fuzzy +#~ msgid "Pros of Different Memory Management Techniques" +#~ msgstr "Vorteile verschiedener Speicherverwaltungstechniken" + +#, fuzzy +#~ msgid "Manual like C:" +#~ msgstr "Handbuch wie C:" + +#, fuzzy +#~ msgid "No runtime overhead." +#~ msgstr "Kein Laufzeitaufwand." + +#, fuzzy +#~ msgid "Automatic like Java:" +#~ msgstr "Automatisch wie Java:" + +#, fuzzy +#~ msgid "Fully automatic." +#~ msgstr "Komplett automatisch." + +#, fuzzy +#~ msgid "Safe and correct." +#~ msgstr "Sicher und korrekt." + +#, fuzzy +#~ msgid "Scope-based like C++:" +#~ msgstr "Bereichsbasiert wie C++:" + +#, fuzzy +#~ msgid "Partially automatic." +#~ msgstr "Teilautomatisch." + +#, fuzzy +#~ msgid "Compiler-enforced scope-based like Rust:" +#~ msgstr "Vom Compiler erzwungener Geltungsbereich wie Rust:" + +#, fuzzy +#~ msgid "Enforced by compiler." +#~ msgstr "Vom Compiler erzwungen." + +#, fuzzy +#~ msgid "Cons of Different Memory Management Techniques" +#~ msgstr "Nachteile verschiedener Techniken zur Speicherverwaltung" + +#, fuzzy +#~ msgid "Use-after-free." +#~ msgstr "Use-after-free." + +#, fuzzy +#~ msgid "Double-frees." +#~ msgstr "Double-frees." + +#, fuzzy +#~ msgid "Memory leaks." +#~ msgstr "Speicherlecks." + +#, fuzzy +#~ msgid "Garbage collection pauses." +#~ msgstr "Garbage Collection pausiert." + +#, fuzzy +#~ msgid "Destructor delays." +#~ msgstr "Destruktorverzögerungen." + +#, fuzzy +#~ msgid "Complex, opt-in by programmer." +#~ msgstr "Komplex, Opt-in durch Programmierer." + +#, fuzzy +#~ msgid "Potential for use-after-free." +#~ msgstr "Potenzial für die Nutzung nach dem Kostenlos." + +#, fuzzy +#~ msgid "Compiler-enforced and scope-based like Rust:" +#~ msgstr "Compiler-erzwungen und bereichsbasiert wie Rust:" + +#, fuzzy +#~ msgid "Some upfront complexity." +#~ msgstr "Etwas Komplexität im Voraus." + +#, fuzzy +#~ msgid "Can reject valid programs." +#~ msgstr "Kann gültige Programme ablehnen." + +#, fuzzy +#~ msgid "The data was _moved_ from `s1` and `s1` is no longer accessible." +#~ msgstr "" +#~ "Die Daten wurden von `s1` _verschoben_ und `s1` ist nicht mehr zugänglich." + +#, fuzzy +#~ msgid "A small book library," +#~ msgstr "Iteratoren und Besitz (schwer)." + +#, fuzzy +#~ msgid "Simple struct which tracks health statistics." +#~ msgstr "Mehrere Strukturen und Aufzählungen für eine Zeichnungsbibliothek." + +#, fuzzy +#~ msgid "" +#~ "If you need to mutate the data inside an `Rc`, you will need to wrap the " +#~ "data in a type such as [`Cell` or `RefCell`](../concurrency/shared_state/" +#~ "arc.md)." +#~ msgstr "" +#~ "Wenn Sie die Daten innerhalb eines „Rc“ mutieren müssen, müssen Sie die " +#~ "Daten einschließen ein Typ wie [`Cell` oder `RefCell`](../concurrency/" +#~ "shared_state/arc.md). Siehe [`Arc`](https://doc.rust-lang.org/std/sync/" +#~ "struct.Mutex.html), wenn Sie sich in einem Multithreading befinden " +#~ "Kontext." + +#, fuzzy +#~ msgid "The module content can be omitted:" +#~ msgstr "Der Modulinhalt kann weggelassen werden:" + +#, fuzzy +#~ msgid "The `garden` module content is found at:" +#~ msgstr "Die Inhalte des Moduls „Garten“ finden Sie unter:" + +#, fuzzy +#~ msgid "`src/garden.rs` (modern Rust 2018 style)" +#~ msgstr "`src/garden.rs` (moderner Rust 2018-Stil)" + +#, fuzzy +#~ msgid "`src/garden/mod.rs` (older Rust 2015 style)" +#~ msgstr "`src/garden/mod.rs` (älterer Rust 2015-Stil)" + +#, fuzzy +#~ msgid "Similarly, a `garden::vegetables` module can be found at:" +#~ msgstr "" +#~ "In ähnlicher Weise kann ein `garden::vegetables`\\-Modul gefunden werden " +#~ "unter:" + +#, fuzzy +#~ msgid "`src/garden/vegetables.rs` (modern Rust 2018 style)" +#~ msgstr "`src/garden/vegetables.rs` (moderner Rust 2018-Stil)" + +#, fuzzy +#~ msgid "`src/garden/vegetables/mod.rs` (older Rust 2015 style)" +#~ msgstr "`src/garden/vegetables/mod.rs` (älterer Rust 2015 Stil)" + +#, fuzzy +#~ msgid "" +#~ "Copy the following code to and implement " +#~ "the function:" +#~ msgstr "" +#~ "Kopieren Sie den folgenden Code nach und " +#~ "implementieren Sie die Funktion:" + +#, fuzzy +#~ msgid "`move` closures only implement `FnOnce`." +#~ msgstr "`move`\\-Closures implementieren nur `FnOnce`." + +#~ msgid "" +#~ "**Note:** Please ignore the `// ANCHOR: label` and `// ANCHOR_END: label` " +#~ "comments you see in the solutions. They are there to make it possible to " +#~ "re-use parts of the solutions as the exercises." +#~ msgstr "" +#~ "**Hinweis:** Bitte ignoriere `// ANCHOR: label` und `// ANCHOR_END: " +#~ "label` Kommentare, die Du in den Lösungen siehst. Sie sind da, um es zu " +#~ "ermöglichen Teile der Lösungen als Aufgaben wiederverwenden."