diff --git a/README.md b/README.md index 5748c0a..f00b8f8 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,6 @@ Vorschläge und Korrekturen oder gar Übersetzungen sind natürlich gerne gewün Falls du helfen möchtest, dann am besten via Pull Request oder Issue. Das Buch wurde mittlerweile komplett übersetzt und enthält alle Änderungen des -englischen Originals bis einschließlich zum **23.01.2023**. +englischen Originals bis einschließlich zum **29.06.2023**. Bitte beachte auch die [Übersetzungskonventionen](https://github.com/rust-lang-de/rustbook-de/wiki/%C3%9Cbersetzungskonventionen). diff --git a/src/appendix-07-nightly-rust.md b/src/appendix-07-nightly-rust.md index a6510fa..580937d 100644 --- a/src/appendix-07-nightly-rust.md +++ b/src/appendix-07-nightly-rust.md @@ -145,12 +145,14 @@ ermöglicht, neue Funktionen praktisch zu nutzen, bevor wir sie für immer für stabil erklären. Diejenigen, die sich für das Allerneueste entscheiden wollen, können dies tun, und diejenigen, die eine felsenfeste Erfahrung machen wollen, können bei der stabilen Version bleiben und wissen, dass ihr Code nicht brechen -wird. Stabilität ohne Stillstand. Dieses Buch enthält nur Informationen über -stabile Funktionalitäten, da sich in Entwicklung befindliche Funktionalitäten -noch ändern, und sicherlich werden sie sich zwischen dem Zeitpunkt, an dem -dieses Buch geschrieben wurde, und dem Zeitpunkt, an dem sie in stabilen -Versionen aktiviert werden, unterscheiden. Die Dokumentation für die nur -nächtlich verfügbaren Funktionalitäten findest du online. +wird. Stabilität ohne Stillstand. + +Dieses Buch enthält nur Informationen über stabile Funktionalitäten, da sich in +Entwicklung befindliche Funktionalitäten noch ändern, und sicherlich werden sie +sich zwischen dem Zeitpunkt, an dem dieses Buch geschrieben wurde, und dem +Zeitpunkt, an dem sie in stabilen Versionen aktiviert werden, unterscheiden. +Die Dokumentation für die nur nächtlich verfügbaren Funktionalitäten findest du +online. ### Rustup und die Rolle des nächtlichen Rust diff --git a/src/ch00-00-introduction.md b/src/ch00-00-introduction.md index 25e62fb..8f616b2 100644 --- a/src/ch00-00-introduction.md +++ b/src/ch00-00-introduction.md @@ -203,4 +203,4 @@ Codeversion, wenn er sich nicht kompilieren lässt. Die Quelldateien, aus denen dieses Buch generiert wird, findest du unter [GitHub][book-de]. -[book-de]: https://github.com/rust-lang-de/rustbook-de/tree/master/src +[book-de]: https://github.com/rust-lang-de/rustbook-de/ diff --git a/src/ch01-01-installation.md b/src/ch01-01-installation.md index 7d294a0..5704e0e 100644 --- a/src/ch01-01-installation.md +++ b/src/ch01-01-installation.md @@ -10,19 +10,18 @@ benötigen. > nach anderen Möglichkeiten. Die folgenden Schritte installieren die neueste stabile Version des -Rust-Compilers. Rust garantiert Stabilität und stellt somit sicher, -dass alle kompilierbaren Beispiele in diesem Buch auch mit neueren -Rust-Versionen kompilierbar bleiben werden. Die Konsolenausgabe -der Beispiele kann sich zwischen Versionen leicht unterscheiden, -weil Rust oft Fehlermeldungen und Warnungen verbessert. -Anders ausgedrückt, jede neuere stabile Version von Rust, die du -mithilfe dieser Schritte installierst, sollte wie erwartet mit dem -Inhalt dieses Buches funktionieren. +Rust-Compilers. Rust garantiert Stabilität und stellt somit sicher, dass alle +kompilierbaren Beispiele in diesem Buch auch mit neueren Rust-Versionen +kompilierbar bleiben werden. Die Ausgabe der Beispiele kann sich zwischen +Versionen leicht unterscheiden, weil Rust oft Fehlermeldungen und Warnungen +verbessert. Anders ausgedrückt, jede neuere stabile Version von Rust, die du +mithilfe dieser Schritte installierst, sollte wie erwartet mit dem Inhalt +dieses Buchs funktionieren. > ### Kommandozeilen-Schreibweise > -> In diesem Kapitel und im ganzen Buch werden wir einige Befehle auf der -> Konsole zeigen. Alle Zeilen, die du in die Konsole eingeben sollst, +> In diesem Kapitel und im ganzen Buch werden wir einige Befehle auf dem +> Terminal zeigen. Alle Zeilen, die du in das Terminal eingeben sollst, > beginnen mit `$`. Du brauchst das `$`-Zeichen nicht einzugeben; > es weist nur auf den Beginn jedes Befehls hin. Zeilen, die nicht mit > `$` beginnen, zeigen normalerweise die Ausgabe eines vorherigen Befehls. @@ -31,7 +30,7 @@ Inhalt dieses Buches funktionieren. ### Die Installation von `rustup` in Linux und macOS -Falls du Linux oder macOS verwendest, öffne ein Konsolenfenster und gib den +Falls du Linux oder macOS verwendest, öffne ein Terminalfenster und gib den folgenden Befehl ein: ```console @@ -86,8 +85,8 @@ werden wir diese erläutern. ### Fehlersuche -Um zu überprüfen, ob du Rust korrekt installiert hast, öffne eine -Kommandozeile und gib folgende Zeile ein: +Um zu überprüfen, ob du Rust korrekt installiert hast, öffne ein +Terminal und gib folgende Zeile ein: ```console $ rustc --version @@ -129,9 +128,8 @@ Rust-Entwicklern in Kontakt treten kannst, erfährst du auf der ### Aktualisieren und Deinstallieren -Nachdem du Rust mithilfe von `rustup` installiert hast, ist es einfach, -auf die neueste Version zu aktualisieren. Führe folgenden Befehl auf der -Kommandozeile aus: +Nachdem du Rust mithilfe von `rustup` installiert hast, ist es einfach, auf die +neueste Version zu aktualisieren. Führe folgenden Befehl im Terminal aus: ```console $ rustup update diff --git a/src/ch01-02-hello-world.md b/src/ch01-02-hello-world.md index 1c2c1b6..c84c71f 100644 --- a/src/ch01-02-hello-world.md +++ b/src/ch01-02-hello-world.md @@ -22,7 +22,7 @@ erstellen. Es ist Rust egal, wo dein Code lebt, aber für die Übungen und Projekte in diesem Buch schlagen wir vor, ein Verzeichnis *projects* in deinem Hauptverzeichnis anzulegen und all deine Projekte dort abzulegen. -Öffne eine Kommandozeile und gib die folgenden Befehle ein, um ein Verzeichnis +Öffne ein Terminal und gib die folgenden Befehle ein, um ein Verzeichnis *projects* und ein Verzeichnis für das Projekt „Hallo Welt!“ innerhalb des Verzeichnisses *projects* zu erstellen. @@ -65,8 +65,9 @@ fn main() { Codeblock 1-1: Ein Programm, das `Hallo Welt!` ausgibt -Speichere die Datei und gehe zurück zu deinem Konsolenfenster. Gib unter Linux -oder MacOS die folgenden Befehle ein, um die Datei zu kompilieren und auszuführen: +Speichere die Datei und gehe zurück zu deinem Terminalfenster im Verzeichnis +*~/projects/hello_world*. Gib unter Linux oder MacOS die folgenden Befehle ein, +um die Datei zu kompilieren und auszuführen: ```console $ rustc main.rs @@ -82,9 +83,9 @@ Unter Windows gib den Befehl `.\main.exe` anstelle von `./main` ein: Hallo Welt! ``` -Unabhängig von deinem Betriebssystem sollte die Zeichenfolge `Hallo Welt!` auf -der Kommandozeile ausgegeben werden. Wenn du diese Ausgabe nicht siehst, lies -im Abschnitt [„Fehlersuche“][troubleshooting] des Installationsabschnitts nach, +Unabhängig von deinem Betriebssystem sollte die Zeichenfolge `Hallo Welt!` im +Terminal ausgegeben werden. Wenn du diese Ausgabe nicht siehst, lies im +Abschnitt [„Fehlersuche“][troubleshooting] des Installationsabschnitts nach, wie du Hilfe erhalten kannst. Wenn `Hallo Welt!` ausgegeben wurde, herzlichen Glückwunsch! Du hast offiziell @@ -166,7 +167,7 @@ Wenn du einen C- oder C++-Hintergrund hast, wirst du feststellen, dass dies eine ausführbare Binärdatei aus. Unter Linux, MacOS und PowerShell unter Windows kannst du die ausführbare Datei -sehen, indem du den Befehl `ls` in deiner Konsole eingibst: +sehen, indem du den Befehl `ls` in deinem Terminal eingibst: ```console $ ls @@ -195,7 +196,7 @@ $ ./main # oder .\main.exe unter Windows ``` Wenn *main.rs* dein „Hallo Welt!“-Programm wäre, würde diese Zeile „Hallo -Welt!“ in deiner Konsole ausgeben. +Welt!“ in deinem Terminal ausgeben. Wenn du mit einer dynamischen Sprache wie Ruby, Python oder JavaScript besser vertraut bist, bist du es möglicherweise nicht gewohnt, ein Programm in diff --git a/src/ch02-00-guessing-game-tutorial.md b/src/ch02-00-guessing-game-tutorial.md index 3370a2a..185227d 100644 --- a/src/ch02-00-guessing-game-tutorial.md +++ b/src/ch02-00-guessing-game-tutorial.md @@ -823,19 +823,26 @@ versuchen: ```console $ cargo build - Compiling libc v0.2.51 - Compiling rand_core v0.4.0 - Compiling rand_core v0.3.1 - Compiling rand v0.5.6 + Compiling libc v0.2.86 + Compiling getrandom v0.2.2 + Compiling cfg-if v1.0.0 + Compiling ppv-lite86 v0.2.10 + Compiling rand_core v0.6.2 + Compiling rand_chacha v0.3.0 + Compiling rand v0.8.5 Compiling guessing_game v0.1.0 (file:///projects/guessing_game) error[E0308]: mismatched types --> src/main.rs:22:21 | 22 | match guess.cmp(&secret_number) { - | ^^^^^^^^^^^^^^ expected struct `String`, found integer + | --- ^^^^^^^^^^^^^^ expected struct `String`, found integer + | | + | arguments to this function are incorrect | = note: expected reference `&String` found reference `&{integer}` +note: associated function defined here + --> /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/cmp.rs:783:8 For more information about this error, try `rustc --explain E0308`. error: could not compile `guessing_game` due to previous error diff --git a/src/ch03-02-data-types.md b/src/ch03-02-data-types.md index 6633b18..c9b9a1a 100644 --- a/src/ch03-02-data-types.md +++ b/src/ch03-02-data-types.md @@ -29,7 +29,12 @@ error[E0282]: type annotations needed --> src/main.rs:2:9 | 2 | let guess = "42".parse().expect("Keine Zahl!"); - | ^^^^^ consider giving `guess` a type + | ^^^^^ + | +help: consider giving `guess` an explicit type + | +2 | let guess: _ = "42".parse().expect("Keine Zahl!"); + | +++ For more information about this error, try `rustc --explain E0282`. error: could not compile `no_type_annotations` due to previous error @@ -194,7 +199,7 @@ fn main() { // Division let quotient = 56.7 / 32.2; - let floored = 2 / 3; // Ergibt 0 + let truncated = -5 / 3; // Ergibt -1 // Restberechnung let remainder = 43 % 5; diff --git a/src/ch03-03-how-functions-work.md b/src/ch03-03-how-functions-work.md index 21d0c67..a0b9111 100644 --- a/src/ch03-03-how-functions-work.md +++ b/src/ch03-03-how-functions-work.md @@ -188,15 +188,12 @@ Wenn du dieses Programm ausführst, wirst du in etwa folgenden Fehler erhalten: ```console $ cargo run - Compiling playground v0.0.1 (/playground) -error[E0658]: `let` expressions in this position are experimental + Compiling functions v0.1.0 (file:///projects/functions) +error: expected expression, found `let` statement --> src/main.rs:2:14 | 2 | let x = (let y = 6); - | ^^^^^^^^^ - | - = note: see issue #53667 for more information - = help: you can write `matches!(, )` instead of `let = ` + | ^^^ error: expected expression, found statement (`let`) --> src/main.rs:2:14 @@ -206,20 +203,30 @@ error: expected expression, found statement (`let`) | = note: variable declaration using `let` is a statement +error[E0658]: `let` expressions in this position are unstable + --> src/main.rs:2:14 + | +2 | let x = (let y = 6); + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + warning: unnecessary parentheses around assigned value --> src/main.rs:2:13 | 2 | let x = (let y = 6); - | ^^^^^^^^^^^ help: remove these parentheses + | ^ ^ | = note: `#[warn(unused_parens)]` on by default - -error: aborting due to 2 previous errors; 1 warning emitted +help: remove these parentheses + | +2 - let x = (let y = 6); +2 + let x = let y = 6; + | For more information about this error, try `rustc --explain E0658`. -error: could not compile `playground` - -To learn more, run the command again with --verbose. +warning: `functions` (bin "functions") generated 1 warning +error: could not compile `functions` due to 3 previous errors; 1 warning emitted ``` Die Anweisung `let y = 6` gibt keinen Wert zurück, also gibt es für `x` nichts, diff --git a/src/ch04-01-what-is-ownership.md b/src/ch04-01-what-is-ownership.md index ec0e4d6..95554dc 100644 --- a/src/ch04-01-what-is-ownership.md +++ b/src/ch04-01-what-is-ownership.md @@ -1,18 +1,16 @@ ## Was ist Eigentümerschaft (ownership)? *Eigentümerschaft* ist eine Reihe von Regeln, die bestimmen, wie ein -Rust-Programm den Speicher verwaltet. - -Alle Programme müssen den Arbeitsspeicher eines Rechners verwalten, während sie -ausgeführt werden. Einige Sprachen verfügen über eine automatische -Speicherbereinigung, die während der Programmausführung ständig nach nicht mehr -genutztem Speicher sucht. Bei anderen Sprachen muss der Programmierer selbst -den Speicher explizit reservieren und freigeben. Rust verwendet einen dritten -Ansatz: Der Speicher wird durch ein System aus Eigentümerschaft und einer Reihe -von Regeln verwaltet, die der Compiler überprüft. Wenn eine der Regeln verletzt -wird, lässt sich das Programm nicht kompilieren. Keine der -Eigentümerschaftsfunktionalitäten verlangsamt dein Programm, während es -läuft. +Rust-Programm den Speicher verwaltet. Alle Programme müssen den Arbeitsspeicher +eines Rechners verwalten, während sie ausgeführt werden. Einige Sprachen +verfügen über eine automatische Speicherbereinigung, die während der +Programmausführung ständig nach nicht mehr genutztem Speicher sucht. Bei +anderen Sprachen muss der Programmierer selbst den Speicher explizit +reservieren und freigeben. Rust verwendet einen dritten Ansatz: Der Speicher +wird durch ein System aus Eigentümerschaft und einer Reihe von Regeln +verwaltet, die der Compiler überprüft. Wenn eine der Regeln verletzt wird, +lässt sich das Programm nicht kompilieren. Keine der +Eigentümerschaftsfunktionalitäten verlangsamt dein Programm, während es läuft. Da die Eigentümerschaft für viele Programmierer ein neues Konzept ist, braucht es etwas Zeit, sich daran zu gewöhnen. Die gute Nachricht ist, je mehr @@ -112,8 +110,7 @@ Lass uns zunächst einen Blick auf die Eigentumsregeln (ownership rules) werfen. Behalte diese Regeln im Hinterkopf, während wir veranschaulichende Beispiele durcharbeiten: -* Jeder Wert in Rust hat eine Variable, die als sein *Eigentümer* bezeichnet - wird. +* Jeder Wert in Rust hat einen *Eigentümer* (owner). * Es kann immer nur einen Eigentümer zur gleichen Zeit geben. * Wenn der Eigentümer den Gültigkeitsbereich verlässt, wird der Wert aufgeräumt. @@ -407,9 +404,15 @@ error[E0382]: borrow of moved value: `s1` | -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait 3 | let s2 = s1; | -- value moved here -4 | +4 | 5 | println!("{} Welt!", s1); | ^^ value borrowed here after move + | + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider cloning the value if the performance cost is acceptable + | +3 | let s2 = s1.clone(); + | ++++++++ For more information about this error, try `rustc --explain E0382`. error: could not compile `ownership` due to previous error diff --git a/src/ch04-02-references-and-borrowing.md b/src/ch04-02-references-and-borrowing.md index c2b9239..2c3fec3 100644 --- a/src/ch04-02-references-and-borrowing.md +++ b/src/ch04-02-references-and-borrowing.md @@ -133,7 +133,7 @@ error[E0596]: cannot borrow `*some_string` as mutable, as it is behind a `&` ref 7 | fn change(some_string: &String) { | ------- help: consider changing this to be a mutable reference: `&mut String` 8 | some_string.push_str(" Welt"); - | ^^^^^^^^^^^ `some_string` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `some_string` is a `&` reference, so the data it refers to cannot be borrowed as mutable For more information about this error, try `rustc --explain E0596`. error: could not compile `ownership` due to previous error @@ -361,7 +361,7 @@ error[E0106]: missing lifetime specifier help: consider using the `'static` lifetime | 5 | fn dangle() -> &'static String { - | ~~~~~~~~ + | +++++++ For more information about this error, try `rustc --explain E0106`. error: could not compile `ownership` due to previous error diff --git a/src/ch05-01-defining-structs.md b/src/ch05-01-defining-structs.md index e67a3b2..7b69610 100644 --- a/src/ch05-01-defining-structs.md +++ b/src/ch05-01-defining-structs.md @@ -51,9 +51,9 @@ Codeblock 5-2 zu sehen ist. # fn main() { let user1 = User { - email: String::from("jemand@example.com"), - username: String::from("benutzername123"), active: true, + username: String::from("benutzername123"), + email: String::from("jemand@example.com"), sign_in_count: 1, }; } @@ -81,9 +81,9 @@ einem bestimmten Feld zuweisen. Codeblock 5-3 gezeigt, wie der Wert im Feld # fn main() { let mut user1 = User { - email: String::from("jemand@example.com"), - username: String::from("benutzername123"), active: true, + username: String::from("benutzername123"), + email: String::from("jemand@example.com"), sign_in_count: 1, }; @@ -114,9 +114,9 @@ den Wert `true` und das Feld `sign_in_count` den Wert `1`. # fn build_user(email: String, username: String) -> User { User { - email: email, - username: username, active: true, + username: username, + email: email, sign_in_count: 1, } } @@ -158,9 +158,9 @@ wiederholen, siehe Codeblock 5-5. # fn build_user(email: String, username: String) -> User { User { - email, - username, active: true, + username, + email, sign_in_count: 1, } } @@ -389,38 +389,36 @@ für jeden Typ implementiert, auch für unit-ähnliche Strukturen. > > ```console > $ cargo run -> Compiling playground v0.0.1 (/playground) +> Compiling structs v0.1.0 (file:///projects/structs) > error[E0106]: missing lifetime specifier -> --> src/main.rs:2:15 +> --> src/main.rs:3:15 > | -> 2 | username: &str, +> 3 | username: &str, > | ^ expected named lifetime parameter > | > help: consider introducing a named lifetime parameter > | -> 1 | struct User<'a> { -> 2 | username: &'a str, +> 1 ~ struct User<'a> { +> 2 | active: bool, +> 3 ~ username: &'a str, > | > > error[E0106]: missing lifetime specifier -> --> src/main.rs:3:12 +> --> src/main.rs:4:12 > | -> 3 | email: &str, +> 4 | email: &str, > | ^ expected named lifetime parameter > | > help: consider introducing a named lifetime parameter > | -> 1 | struct User<'a> { -> 2 | username: &str, -> 3 | email: &'a str, +> 1 ~ struct User<'a> { +> 2 | active: bool, +> 3 | username: &str, +> 4 ~ email: &'a str, > | > -> error: aborting due to 2 previous errors -> > For more information about this error, try `rustc --explain E0106`. -> error: could not compile `playground` -> -> To learn more, run the command again with --verbose. +> error: could not compile `structs` due to 2 previous errors > ``` > > In Kapitel 10 werden wir klären, wie man diese Fehler behebt und Referenzen diff --git a/src/ch05-02-example-structs.md b/src/ch05-02-example-structs.md index aa6dab8..316175f 100644 --- a/src/ch05-02-example-structs.md +++ b/src/ch05-02-example-structs.md @@ -7,10 +7,8 @@ einsetzen. Legen wir mit Cargo ein neues Binärprojekt namens *rectangles* an, das die Breite und Höhe eines in Pixeln angegebenen Rechtecks nimmt und die Fläche des -Rechtecks berechnet. - -Codeblock 5-8 zeigt ein kurzes Programm, das genau das in *src/main.rs* unseres -Projekts macht. +Rechtecks berechnet. Codeblock 5-8 zeigt ein kurzes Programm, das genau das in +*src/main.rs* unseres Projekts macht. Dateiname: src/main.rs @@ -305,9 +303,9 @@ Zeilennummer, in der der `dbg!`-Makroaufruf in deinem Code vorkommt, zusammen mit dem resultierenden Wert des Ausdrucks ausgibt und die Eigentümerschaft am Wert zurückgibt. -> Hinweis: Der Aufruf des Makros `dbg!` schreibt in den -> Standard-Fehler-Konsolenstrom (`stderr`), im Gegensatz zu `println!`, das in -> den Standard-Ausgabe-Konsolenstrom (`stdout`) schreibt. Wir werden mehr über +> Hinweis: Der Aufruf des Makros `dbg!` schreibt in die +> Standardfehlerausgabe (`stderr`), im Gegensatz zu `println!`, das in +> die Standardausgabe (`stdout`) schreibt. Wir werden mehr über > `stderr` und `stdout` im Abschnitt [„Fehlermeldungen in die > Standardfehlerausgabe anstatt der Standardausgabe schreiben“ in Kapitel > 12][err] erfahren. diff --git a/src/ch06-01-defining-an-enum.md b/src/ch06-01-defining-an-enum.md index 8887fce..a19ea6f 100644 --- a/src/ch06-01-defining-an-enum.md +++ b/src/ch06-01-defining-an-enum.md @@ -426,6 +426,11 @@ error[E0277]: cannot add `Option` to `i8` | ^ no implementation for `i8 + Option` | = help: the trait `Add>` is not implemented for `i8` + = help: the following other types implement trait `Add`: + <&'a i8 as Add> + <&i8 as Add<&i8>> + > + For more information about this error, try `rustc --explain E0277`. error: could not compile `enums` due to previous error diff --git a/src/ch06-02-match.md b/src/ch06-02-match.md index 1300d48..5c92a41 100644 --- a/src/ch06-02-match.md +++ b/src/ch06-02-match.md @@ -263,10 +263,10 @@ fn plus_one(x: Option) -> Option { Some(i) => Some(i + 1), } } - -let five = Some(5); -let six = plus_one(five); -let none = plus_one(None); +# +# let five = Some(5); +# let six = plus_one(five); +# let none = plus_one(None); ``` Wir haben den Fall `None` nicht behandelt, daher wird dieser Code einen Fehler @@ -278,13 +278,22 @@ diese Fehlermeldung bekommen: $ cargo run Compiling enums v0.1.0 (file:///projects/enums) error[E0004]: non-exhaustive patterns: `None` not covered - --> src/main.rs:3:15 - | -3 | match x { - | ^ pattern `None` not covered - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - = note: the matched value is of type `Option` + --> src/main.rs:3:15 + | +3 | match x { + | ^ pattern `None` not covered + | +note: `Option` defined here + --> /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/option.rs:518:1 + | + = note: +/rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/option.rs:522:5: not covered + = note: the matched value is of type `Option` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +4 ~ Some(i) => Some(i + 1), +5 ~ None => todo!(), + | For more information about this error, try `rustc --explain E0004`. error: could not compile `enums` due to previous error diff --git a/src/ch07-02-defining-modules-to-control-scope-and-privacy.md b/src/ch07-02-defining-modules-to-control-scope-and-privacy.md index 8ca8894..b49c58f 100644 --- a/src/ch07-02-defining-modules-to-control-scope-and-privacy.md +++ b/src/ch07-02-defining-modules-to-control-scope-and-privacy.md @@ -42,8 +42,8 @@ sich daran zu erinnern, wie Module funktionieren. - **Pfade zum Code in Modulen**: Sobald ein Modul Teil deiner Kiste ist, kannst du auf den Code in diesem Modul von jedem anderen Ort in derselben Kiste aus referenzieren, solange die Datenschutzregeln dies zulassen, indem du den Pfad - zum Code verwendest. Zum Beispiel würde ein Typ `Asparagus` im - Gartengemüse-Modul unter `crate::garden::vegetables::Asparagus` zu finden + zum Code verwendest. Zum Beispiel würde ein Typ `Asparagus` (engl. Spargel) + im Gartengemüse-Modul unter `crate::garden::vegetables::Asparagus` zu finden sein. - **Privat vs. öffentlich**: Der Code innerhalb eines Moduls ist standardmäßig für seine übergeordneten Module nicht zugänglich. Um ein Modul öffentlich zu diff --git a/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md b/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md index 7f09357..a128976 100644 --- a/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md +++ b/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md @@ -42,10 +42,10 @@ mod front_of_house { } pub fn eat_at_restaurant() { - // absoluter Pfad + // Absoluter Pfad crate::front_of_house::hosting::add_to_waitlist(); - // relativer Pfad + // Relativer Pfad front_of_house::hosting::add_to_waitlist(); } ``` @@ -62,7 +62,7 @@ erreichen. Du kannst dir ein Dateisystem mit der gleichen Struktur vorstellen: Wir würden den Pfad `/front_of_house/hosting/add_to_waitlist` angeben, um das Programm `add_to_waitlist` auszuführen; das Verwenden des Namens `crate`, um von der Kistenwurzel aus zu beginnen, ist analog zu `/`, um vom -Dateisystem-Wurzelverzeichnis in deiner Eingabeaufforderung aus zu beginnen. +Dateisystem-Wurzelverzeichnis in deinem Terminal aus zu beginnen. Beim zweiten Aufruf von `add_to_waitlist` in `eat_at_restaurant` verwenden wir einen relativen Pfad. Der Pfad beginnt mit `front_of_house`, dem Namen des @@ -148,7 +148,7 @@ den äußeren Code zu brechen. Rust gibt dir jedoch die Möglichkeit, innere Tei des Codes von Kindmodulen für äußere Vorgängermodule offenzulegen, indem du das Schlüsselwort `pub` verwendest, um ein Element öffentlich zu machen. -### Pfade mit dem Schlüsselwort `pub` öffnen +### Pfade mit dem Schlüsselwort `pub` öffentlich machen Kehren wir zum Fehler in Codeblock 7-4 zurück, der uns sagte, das Modul `hosting` sei privat. Wir wollen, dass die Funktion `eat_at_restaurant` im @@ -166,7 +166,7 @@ mod front_of_house { } pub fn eat_at_restaurant() { - // Absolutet Pfad + // Absoluter Pfad crate::front_of_house::hosting::add_to_waitlist(); // Relativer Pfad @@ -242,10 +242,10 @@ mod front_of_house { } pub fn eat_at_restaurant() { - // absoluter Path + // Absoluter Pfad crate::front_of_house::hosting::add_to_waitlist(); - // relativer Path + // Relativer Pfad front_of_house::hosting::add_to_waitlist(); } ``` @@ -285,7 +285,7 @@ Benutzern deiner Kiste, die festlegt, wie sie mit deinem Code interagieren können. Es gibt viele Überlegungen zum Umgang mit Änderungen an deiner öffentlichen API, um es für andere einfacher zu machen, sich auf deine Kiste zu verlassen. Diese Überlegungen liegen außerhalb des Rahmens dieses Buches; wenn -du an diesem Thema interessiert bist, lies [The Rust API +du an diesem Thema interessiert bist, lies die [Rust API Guidelines][api-guidelines]. > #### Bewährte Praktiken für Pakete mit einer Binärdatei und einer Bibliothek diff --git a/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md b/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md index 8265cc8..669682f 100644 --- a/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md +++ b/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md @@ -74,12 +74,6 @@ nicht mehr gilt: ```console $ cargo build Compiling restaurant v0.1.0 (file:///projects/restaurant) -error[E0433]: failed to resolve: use of undeclared crate or module `hosting` - --> src/lib.rs:11:9 - | -11 | hosting::add_to_waitlist(); - | ^^^^^^^ use of undeclared crate or module `hosting` - warning: unused import: `crate::front_of_house::hosting` --> src/lib.rs:7:5 | @@ -88,6 +82,12 @@ warning: unused import: `crate::front_of_house::hosting` | = note: `#[warn(unused_imports)]` on by default +error[E0433]: failed to resolve: use of undeclared crate or module `hosting` + --> src/lib.rs:11:9 + | +11 | hosting::add_to_waitlist(); + | ^^^^^^^ use of undeclared crate or module `hosting` + For more information about this error, try `rustc --explain E0433`. warning: `restaurant` (lib) generated 1 warning error: could not compile `restaurant` due to previous error; 1 warning emitted @@ -282,7 +282,7 @@ Projekt zu verwenden, fügten wir diese Zeile zu *Cargo.toml* hinzu: Dateiname: Cargo.toml ```toml -rand = "0.8.3" +rand = "0.8.5" ``` Das Hinzufügen von `rand` als Abhängigkeit in *Cargo.toml* weist Cargo an, das diff --git a/src/ch07-05-separating-modules-into-different-files.md b/src/ch07-05-separating-modules-into-different-files.md index 90bd548..42933ad 100644 --- a/src/ch07-05-separating-modules-into-different-files.md +++ b/src/ch07-05-separating-modules-into-different-files.md @@ -11,6 +11,13 @@ eigene Datei *src/front_of_house.rs*, indem wir die Kistenwurzeldatei so ist die Kistenwurzeldatei *src/lib.rs*, aber diese Vorgehensweise funktioniert auch mit binären Kisten, deren Kistenwurzeldatei *src/main.rs* ist. +Zuerst extrahieren wir das Modul `front_of_house` in eine eigene Datei. +Entferne den Code innerhalb der geschweiften Klammern des Moduls +`front_of_house` und lasse nur die Deklaration `mod front_of_house;` übrig, +sodass *src/lib.rs* den in Codeblock 7-21 gezeigten Code enthält. Beachte, dass +dies nicht kompiliert und wir noch die Datei *src/front_of_house.rs* in +Codeblock 7-22 erstellen müssen. + Dateiname: src/lib.rs ```rust,ignore diff --git a/src/ch08-01-vectors.md b/src/ch08-01-vectors.md index ceb69fa..d5ab1a8 100644 --- a/src/ch08-01-vectors.md +++ b/src/ch08-01-vectors.md @@ -85,11 +85,11 @@ mittels Indexierungssyntax und der Methode `get`. let v = vec![1, 2, 3, 4, 5]; let third: &i32 = &v[2]; -println!("Das dritte Element ist {}", third); +println!("Das dritte Element ist {third}"); let third: Option<&i32> = v.get(2); match third { - Some(third) => println!("Das dritte Element ist {}", third), + Some(third) => println!("Das dritte Element ist {third}"), None => println!("Es gibt kein drittes Element."), } ``` @@ -154,7 +154,7 @@ let first = &v[0]; v.push(6); -println!("Das erste Element ist: {}", first); +println!("Das erste Element ist: {first}"); ``` Codeblock 8-6: Versuch, ein Element zu einem Vektor @@ -174,8 +174,8 @@ error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immuta 6 | v.push(6); | ^^^^^^^^^ mutable borrow occurs here 7 | -8 | println!("Das erste Element ist: {}", first); - | ----- immutable borrow later used here +8 | println!("Das erste Element ist: {first}"); + | ----- immutable borrow later used here For more information about this error, try `rustc --explain E0502`. error: could not compile `collections` due to previous error @@ -206,7 +206,7 @@ Vektors von `i32`-Werten zu erhalten und diese auszugeben. ```rust let v = vec![100, 32, 57]; for i in &v { - println!("{}", i); + println!("{i}"); } ``` diff --git a/src/ch08-02-strings.md b/src/ch08-02-strings.md index ad6f486..2ee25b2 100644 --- a/src/ch08-02-strings.md +++ b/src/ch08-02-strings.md @@ -37,18 +37,6 @@ dieser Typen. Obwohl es in diesem Abschnitt weitgehend um `String` geht, werden beide Typen in Rusts Standardbibliothek stark verwendet, und sowohl `String` als auch Zeichenkettenanteilstypen sind UTF-8-kodiert. -Die Standardbibliothek von Rust enthält auch eine Reihe anderer -Zeichenkettentypen wie `OsString`, `OsStr`, `CString` und `CStr`. -Bibliothekskisten (library crates) können noch weitere Möglichkeiten zum -Speichern von Zeichenkettendaten bieten. Fällt dir auf, dass diese Namen alle -auf `String` oder `Str` enden? Sie beziehen sich auf aneigenbare und -ausgeliehene Varianten, genau wie die Typen `String` und `str`, die du zuvor -gesehen hast. Diese Zeichenkettentypen können z.B. Text in verschiedenen -Kodierungen speichern oder unterschiedliche Speicherdarstellungen haben. Diese -anderen Zeichenkettentypen werden in diesem Kapitel nicht besprochen; in ihrer -API-Dokumentation erfährst du mehr darüber, wie sie zu verwenden sind und wozu -jeder einzelne geeignet ist. - ### Erstellen einer neuen Zeichenkette Viele der gleichen Operationen, die mit `Vec` verfügbar sind, sind auch mit @@ -84,7 +72,7 @@ let s = "initialer Inhalt".to_string(); Codeblock 8-12: Verwenden der Methode `to_string` zum Erzeugen eines `String` aus einem Zeichenkettenliteral -Dieser Code erzeugt eine Zeichenkette mit dem Inhalt `initialer Inhalt`. +Dieser Code erzeugt eine Zeichenkette, die `initialer Inhalt` enthält. Wir können auch die Funktion `String::from` verwenden, um einen `String` aus einem Zeichenkettenliteral zu erzeugen. Der Code in Codeblock 8-13 ist @@ -158,7 +146,7 @@ Inhalt an `s1` angehängt haben. let mut s1 = String::from("foo"); let s2 = "bar"; s1.push_str(s2); -println!("s2 ist {}", s2); +println!("s2 ist {s2}"); ``` Codeblock 8-16: Verwenden eines Zeichenkettenanteilstyps @@ -259,7 +247,7 @@ let s1 = String::from("tic"); let s2 = String::from("tac"); let s3 = String::from("toe"); -let s = format!("{}-{}-{}", s1, s2, s3); +let s = format!("{s1}-{s2}-{s3}"); ``` Auch bei diesem Code wird `s` den Wert `tic-tac-toe` haben. Das Makro `format!` @@ -280,8 +268,6 @@ ungültigen Code in Codeblock 8-19. ```rust,does_not_compile let s1 = String::from("Hallo"); let h = s1[0]; - - ``` Codeblock 8-19: Versuch, die Indexierungssyntax bei einer @@ -299,6 +285,13 @@ error[E0277]: the type `String` cannot be indexed by `{integer}` | ^^^^^ `String` cannot be indexed by `{integer}` | = help: the trait `Index<{integer}>` is not implemented for `String` + = help: the following other types implement trait `Index`: + >> + > + >> + >> + >> + >> For more information about this error, try `rustc --explain E0277`. error: could not compile `collections` due to previous error @@ -322,7 +315,7 @@ In diesem Fall wird `hello.len()` gleich 4 sein, was bedeutet, dass der Vektor, der die Zeichenkette „Hola“ speichert, 4 Bytes lang ist. Jeder dieser Buchstaben benötigt 1 Byte in UTF-8-Kodierung. Die folgende Zeile mag dich jedoch überraschen. (Beachte, dass diese Zeichenkette mit dem kyrillischen -Großbuchstaben „Ze“ beginnt, nicht mit der arabischen Zahl 3.) +Großbuchstaben „Ze“ beginnt, nicht mit der Zahl 3.) ```rust let hello = String::from("Здравствуйте"); @@ -338,8 +331,6 @@ Um das zu erläutern, betrachte diesen ungültigen Rust-Code: ```rust,does_not_compile let hello = "Здравствуйте"; let answer = &hello[0]; - - ``` Du weißt bereits, dass `answer` nicht `З`, der erste Buchstabe, sein wird. In @@ -395,12 +386,14 @@ Hindi-Wort besteht: Rust bietet verschiedene Möglichkeiten zur Interpretation von rohen Zeichenkettendaten, die von Computern gespeichert werden, sodass jedes Programm die Interpretation wählen kann, die es benötigt, unabhängig davon, in welcher -menschlichen Sprache die Daten vorliegen. Ein letzter Grund, warum Rust uns -nicht erlaubt, eine Zeichenkette zu indexieren, um ein Zeichen zu erhalten, -ist, dass von Indexoperationen erwartet wird, dass sie immer in konstanter Zeit -(O(1)) erfolgen. Es ist jedoch nicht möglich, diese Zeitgarantie bei einem -`String` einzuhalten, da Rust den Inhalt von Anfang an bis zum Index durchgehen -müsste, um festzustellen, wie viele gültige Zeichen es gibt. +menschlichen Sprache die Daten vorliegen. + +Ein letzter Grund, warum Rust uns nicht erlaubt, eine Zeichenkette zu +indexieren, um ein Zeichen zu erhalten, ist, dass von Indexoperationen erwartet +wird, dass sie immer in konstanter Zeit (O(1)) erfolgen. Es ist jedoch nicht +möglich, diese Zeitgarantie bei einem `String` einzuhalten, da Rust den Inhalt +von Anfang an bis zum Index durchgehen müsste, um festzustellen, wie viele +gültige Zeichen es gibt. ### Anteilige Zeichenketten diff --git a/src/ch08-03-hash-maps.md b/src/ch08-03-hash-maps.md index 4885876..9895ee7 100644 --- a/src/ch08-03-hash-maps.md +++ b/src/ch08-03-hash-maps.md @@ -7,12 +7,14 @@ wie er diese Schlüssel und Werte im Speicher ablegt. Viele Programmiersprachen unterstützen diese Art Datenstruktur, aber sie verwenden oft einen anderen Namen, z.B. Hash, Abbildung (map), Objekt, Hashtabelle (hash table), Wörterbuch (dictionary) oder assoziatives Array (associative array), um nur einige zu -nennen. Hashtabellen sind nützlich, wenn du Daten nicht wie bei Vektoren über -einen Index nachschlagen willst, sondern über einen Schlüssel, der ein -beliebiger Typ sein kann. Beispielsweise könntest du in einem Spiel den -Spielstand jedes Teams in einer Hashtabelle vermerken, in der die Schlüssel den -Teamnamen und die Werte den Spielstand des jeweiligen Teams darstellen. Wenn du -den Namen eines Teams angibst, kannst du seine Punktzahl abrufen. +nennen. + +Hashtabellen sind nützlich, wenn du Daten nicht wie bei Vektoren über einen +Index nachschlagen willst, sondern über einen Schlüssel, der ein beliebiger Typ +sein kann. Beispielsweise könntest du in einem Spiel den Spielstand jedes Teams +in einer Hashtabelle vermerken, in der die Schlüssel den Teamnamen und die +Werte den Spielstand des jeweiligen Teams darstellen. Wenn du den Namen eines +Teams angibst, kannst du seine Punktzahl abrufen. In diesem Abschnitt gehen wir die grundlegende Programmierschnittstelle (API) von Hashtabellen durch, aber viele weitere Leckerbissen verbergen sich in den @@ -174,7 +176,7 @@ einen bestimmten Schlüssel Dieser Code wird `{"Blau": 25}` ausgeben. Der ursprüngliche Wert `10` wurde überschrieben. -#### Nur einen Schlüssel und Wert einfügen, wenn der Schlüssel nicht vorhanden ist +#### Einen Schlüssel und Wert nur dann einfügen, wenn der Schlüssel nicht vorhanden ist Es ist üblich, zu prüfen, ob ein bestimmter Schlüssel bereits in der Hashtabelle mit einem Wert vorhanden ist, und dann folgende Maßnahmen zu diff --git a/src/ch09-02-recoverable-errors-with-result.md b/src/ch09-02-recoverable-errors-with-result.md index b2cef80..5f6f9a7 100644 --- a/src/ch09-02-recoverable-errors-with-result.md +++ b/src/ch09-02-recoverable-errors-with-result.md @@ -248,7 +248,8 @@ der Fehlerursache erleichtern. Die Syntax von `expect` sieht wie folgt aus: use std::fs::File; fn main() { - let greeting_file = File::open("hallo.txt").expect("Problem beim Öffnen von hallo.txt"); + let greeting_file = File::open("hallo.txt") + .expect("Problem beim Öffnen von hallo.txt"); } ``` @@ -362,9 +363,10 @@ Absturz bringen, einen Standardbenutzernamen verwenden oder den Benutzernamen von irgendwo anders als z.B. einer Datei nachschlagen. Wir haben nicht genug Informationen darüber, was der aufrufende Code tatsächlich versucht, also propagieren wir alle Erfolgs- und Fehlerinformationen nach oben, damit sie -angemessen behandelt werden. Dieses Muster der Fehlerweitergabe ist in Rust so -verbreitet, dass Rust den Fragezeichen-Operator `?` bereitstellt, um dies zu -erleichtern. +angemessen behandelt werden. + +Dieses Muster der Fehlerweitergabe ist in Rust so verbreitet, dass Rust den +Fragezeichen-Operator `?` bereitstellt, um dies zu erleichtern. #### Abkürzung zum Weitergeben von Fehlern: Der Operator `?` @@ -518,15 +520,14 @@ kompilieren, erhalten wir folgende Fehlermeldung: $ cargo run Compiling error-handling v0.1.0 (file:///projects/error-handling) error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> src/main.rs:4:48 - | -3 | / fn main() { -4 | | let f = File::open("hallo.txt")?; - | | ^ cannot use the `?` operator in a function that returns `()` -5 | | } - | |_- this function should return `Result` or `Option` to accept `?` - | - = help: the trait `FromResidual>` is not implemented for `()` + --> src/main.rs:4:48 + | +3 | fn main() { + | --------- this function should return `Result` or `Option` to accept `?` +4 | let greeting_file = File::open("hallo.txt")?; + | ^ cannot use the `?` operator in a function that returns `()` + | + = help: the trait `FromResidual>` is not implemented for `()` For more information about this error, try `rustc --explain E0277`. error: could not compile `error-handling` due to previous error diff --git a/src/ch10-01-syntax.md b/src/ch10-01-syntax.md index e30f976..e10acce 100644 --- a/src/ch10-01-syntax.md +++ b/src/ch10-01-syntax.md @@ -152,7 +152,7 @@ error[E0369]: binary operation `>` cannot be applied to type `&T` help: consider restricting type parameter `T` | 1 | fn largest(list: &[T]) -> &T { - | ^^^^^^^^^^^^^^^^^^^^^^ + | ++++++++++++++++++++++ For more information about this error, try `rustc --explain E0369`. error: could not compile `chapter10` due to previous error diff --git a/src/ch10-02-traits.md b/src/ch10-02-traits.md index 10902d7..f916656 100644 --- a/src/ch10-02-traits.md +++ b/src/ch10-02-traits.md @@ -212,7 +212,7 @@ Infolgedessen können wir immer noch die Methode `summarize` einer # # fn main() { let article = NewsArticle { - headline: String::from("Pinguine gewinnen die Stanley-Cup-Meisterschaft!"), + headline: String::from("Penguins gewinnen die Stanley-Cup-Meisterschaft!"), location: String::from("Pittsburgh, PA, USA"), author: String::from("Iceburgh"), content: String::from("Die Pittsburgh Penguins sind erneut die beste \ @@ -516,7 +516,7 @@ fn returns_summarizable(switch: bool) -> impl Summary { if switch { NewsArticle { headline: String::from( - "Pinguine gewinnen die Stanley-Cup-Meisterschaft!", + "Penguins gewinnen die Stanley-Cup-Meisterschaft!", ), location: String::from("Pittsburgh, PA, USA"), author: String::from("Iceburgh"), diff --git a/src/ch10-03-lifetime-syntax.md b/src/ch10-03-lifetime-syntax.md index 031cb5e..dcfdb39 100644 --- a/src/ch10-03-lifetime-syntax.md +++ b/src/ch10-03-lifetime-syntax.md @@ -34,16 +34,14 @@ Gültigkeitsbereich hat. ```rust,does_not_compile fn main() { - { - let r; - - { - let x = 5; - r = &x; - } + let r; - println!("r: {}", r); + { + let x = 5; + r = &x; } + + println!("r: {}", r); } ``` @@ -69,15 +67,15 @@ versuchen, ihn zu verwenden. Hier ist die Fehlermeldung: $ cargo run Compiling chapter10 v0.1.0 (file:///projects/chapter10) error[E0597]: `x` does not live long enough - --> src/main.rs:7:17 - | -7 | r = &x; - | ^^ borrowed value does not live long enough -8 | } - | - `x` dropped here while still borrowed -9 | -10 | println!("r: {}", r); - | - borrow later used here + --> src/main.rs:6:13 + | +6 | r = &x; + | ^^ borrowed value does not live long enough +7 | } + | - `x` dropped here while still borrowed +8 | +9 | println!("r: {}", r); + | - borrow later used here For more information about this error, try `rustc --explain E0597`. error: could not compile `chapter10` due to previous error @@ -101,18 +99,16 @@ sind. Codeblock 10-17 zeigt den gleichen Code wie Codeblock 10-16, jedoch mit Annotationen, die die Lebensdauer der Variablen angeben. ```rust,does_not_compile -# fn main() { - { - let r; // ---------+-- 'a - // | - { // | - let x = 5; // -+-- 'b | - r = &x; // | | - } // -+ | - // | - println!("r: {}", r); // | - } // ---------+ -# } +fn main() { + let r; // ---------+-- 'a + // | + { // | + let x = 5; // -+-- 'b | + r = &x; // | | + } // -+ | + // | + println!("r: {}", r); // | +} // ---------+ ``` Codeblock 10-17: Annotationen der Lebensdauern von `r` @@ -131,15 +127,13 @@ Referenz hat und fehlerfrei kompiliert werden kann. ```rust fn main() { - { - let x = 5; // ----------+-- 'b - // | - let r = &x; // --+-- 'a | - // | | - println!("r: {}", r); // | | - // --+ | - } // ----------+ -} + let x = 5; // ----------+-- 'b + // | + let r = &x; // --+-- 'a | + // | | + println!("r: {}", r); // | | + // --+ | +} // ----------+ ``` Codeblock 10-18: Eine gültige Referenz, da die Daten eine @@ -217,7 +211,6 @@ noch nicht kompiliert Stattdessen erhalten wir folgenden Fehler, der von Lebensdauern spricht: ```console -$ cargo run $ cargo run Compiling chapter10 v0.1.0 (file:///projects/chapter10) error[E0106]: missing lifetime specifier @@ -230,7 +223,7 @@ error[E0106]: missing lifetime specifier help: consider introducing a named lifetime parameter | 9 | fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { - | ^^^^ ^^^^^^^ ^^^^^^^ ^^^ + | ++++ ++ ++ ++ For more information about this error, try `rustc --explain E0106`. error: could not compile `chapter10` due to previous error diff --git a/src/ch11-01-writing-tests.md b/src/ch11-01-writing-tests.md index 455f5e7..2287832 100644 --- a/src/ch11-01-writing-tests.md +++ b/src/ch11-01-writing-tests.md @@ -83,18 +83,18 @@ Codeblock 11-2 zu sehen ist. $ cargo test Compiling adder v0.1.0 (file:///projects/adder) Finished test [unoptimized + debuginfo] target(s) in 0.57s - Running unittests (target/debug/deps/adder-92948b65e88960b4) + Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) running 1 test test tests::it_works ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests adder running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Codeblock 11-2: Ergebnis der Ausführung des automatisch @@ -156,18 +156,18 @@ anstelle von `it_works`: $ cargo test Compiling adder v0.1.0 (file:///projects/adder) Finished test [unoptimized + debuginfo] target(s) in 0.59s - Running unittests (target/debug/deps/adder-92948b65e88960b4) + Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) running 1 test test tests::exploration ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests adder running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Fügen wir einen weiteren Test hinzu, aber dieses Mal machen wir einen Test, der @@ -207,7 +207,7 @@ Codeblock 11-4 aussehen, was zeigt, dass unser Test `exploration` bestanden und $ cargo test Compiling adder v0.1.0 (file:///projects/adder) Finished test [unoptimized + debuginfo] target(s) in 0.72s - Running unittests (target/debug/deps/adder-92948b65e88960b4) + Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) running 2 tests test tests::another ... FAILED @@ -216,15 +216,16 @@ test tests::exploration ... ok failures: ---- tests::another stdout ---- -thread 'main' panicked at 'Lasse diesen Test fehlschlagen', src/lib.rs:10:9 +thread 'tests::another' panicked at 'Lasse diesen Test fehlschlagen', src/lib.rs:10:9 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + failures: tests::another -test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` ``` Codeblock 11-4: Testergebnisse, wenn ein Test bestanden @@ -350,18 +351,18 @@ also sollte unser Test erfolgreich sein. Lass es uns herausfinden! $ cargo test Compiling rectangle v0.1.0 (file:///projects/rectangle) Finished test [unoptimized + debuginfo] target(s) in 0.66s - Running unittests (target/debug/deps/rectangle-6584c4561e48942e) + Running unittests src/lib.rs (target/debug/deps/rectangle-6584c4561e48942e) running 1 test test tests::larger_can_hold_smaller ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests rectangle running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Es funktioniert! Fügen wir noch einen weiteren Test hinzu, diesmal mit der @@ -426,19 +427,19 @@ Rückgabewert `false` hat: $ cargo test Compiling rectangle v0.1.0 (file:///projects/rectangle) Finished test [unoptimized + debuginfo] target(s) in 0.66s - Running unittests (target/debug/deps/rectangle-6584c4561e48942e) + Running unittests src/lib.rs (target/debug/deps/rectangle-6584c4561e48942e) running 2 tests test tests::larger_can_hold_smaller ... ok test tests::smaller_cannot_hold_larger ... ok -test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests rectangle running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Zwei Tests, die erfolgreich sind! Nun wollen wir sehen, was mit unseren @@ -501,7 +502,7 @@ Das Ausführen der Tests ergibt nun Folgendes: $ cargo test Compiling rectangle v0.1.0 (file:///projects/rectangle) Finished test [unoptimized + debuginfo] target(s) in 0.66s - Running unittests (target/debug/deps/rectangle-6584c4561e48942e) + Running unittests src/lib.rs (target/debug/deps/rectangle-6584c4561e48942e) running 2 tests test tests::larger_can_hold_smaller ... FAILED @@ -510,16 +511,16 @@ test tests::smaller_cannot_hold_larger ... ok failures: ---- tests::larger_can_hold_smaller stdout ---- -thread 'main' panicked at 'assertion failed: larger.can_hold(&smaller)', src/lib.rs:28:9 +thread 'tests::larger_can_hold_smaller' panicked at 'assertion failed: larger.can_hold(&smaller)', src/lib.rs:28:9 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace failures: tests::larger_can_hold_smaller -test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` ``` Unsere Tests haben den Fehler entdeckt! Da `larger.width` gleich 8 ist und @@ -572,18 +573,18 @@ Lass uns prüfen, ob sie den Test besteht! $ cargo test Compiling adder v0.1.0 (file:///projects/adder) Finished test [unoptimized + debuginfo] target(s) in 0.58s - Running unittests (target/debug/deps/adder-92948b65e88960b4) + Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) running 1 test test tests::it_adds_two ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests adder running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Wir übergeben `4` als Argument an `assert_eq!`, was identisch mit dem Ergebnis @@ -617,7 +618,7 @@ Führe die Tests erneut aus: $ cargo test Compiling adder v0.1.0 (file:///projects/adder) Finished test [unoptimized + debuginfo] target(s) in 0.61s - Running unittests (target/debug/deps/adder-92948b65e88960b4) + Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) running 1 test test tests::it_adds_two ... FAILED @@ -625,17 +626,18 @@ test tests::it_adds_two ... FAILED failures: ---- tests::it_adds_two stdout ---- -thread 'main' panicked at 'assertion failed: `(left == right)` +thread 'tests::it_adds_two' panicked at 'assertion failed: `(left == right)` left: `4`, right: `5`', src/lib.rs:11:9 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + failures: tests::it_adds_two -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` ``` Unser Test hat den Fehler entdeckt! Der Test `it_adds_two` schlug fehl und die @@ -750,7 +752,7 @@ Das Ausführen dieses Tests führt zu folgender Ausgabe: $ cargo test Compiling greeter v0.1.0 (file:///projects/greeter) Finished test [unoptimized + debuginfo] target(s) in 0.91s - Running unittests (target/debug/deps/greeter-170b942eb5bf5e3a) + Running unittests src/lib.rs (target/debug/deps/greeter-170b942eb5bf5e3a) running 1 test test tests::greeting_contains_name ... FAILED @@ -758,15 +760,16 @@ test tests::greeting_contains_name ... FAILED failures: ---- tests::greeting_contains_name stdout ---- -thread 'main' panicked at 'assertion failed: result.contains("Carol")', src/lib.rs:12:9 +thread 'tests::greeting_contains_name' panicked at 'assertion failed: result.contains(\"Carol\")', src/lib.rs:12:9 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + failures: tests::greeting_contains_name -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` ``` Dieses Ergebnis zeigt nur an, dass die Zusicherung fehlgeschlagen ist und in @@ -804,7 +807,7 @@ Fehlermeldung: $ cargo test Compiling greeter v0.1.0 (file:///projects/greeter) Finished test [unoptimized + debuginfo] target(s) in 0.93s - Running unittests (target/debug/deps/greeter-170b942eb5bf5e3a) + Running unittests src/lib.rs (target/debug/deps/greeter-170b942eb5bf5e3a) running 1 test test tests::greeting_contains_name ... FAILED @@ -812,15 +815,16 @@ test tests::greeting_contains_name ... FAILED failures: ---- tests::greeting_contains_name stdout ---- -thread 'main' panicked at 'Begrüßung enthielt nicht den Namen, Wert war `Hallo!`', src/lib.rs:12:9 +thread 'tests::greeting_contains_name' panicked at 'Begrüßung enthielt nicht den Namen, Wert war `Hallo!`', src/lib.rs:12:9 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + failures: tests::greeting_contains_name -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` ``` Wir können den Wert, den wir tatsächlich erhalten haben, in der Testausgabe @@ -885,18 +889,18 @@ wenn dieser Test bestanden ist: $ cargo test Compiling guessing_game v0.1.0 (file:///projects/guessing_game) Finished test [unoptimized + debuginfo] target(s) in 0.58s - Running unittests (target/debug/deps/guessing_game-57d70c3acb738f4d) + Running unittests src/lib.rs (target/debug/deps/guessing_game-57d70c3acb738f4d) running 1 test test tests::greater_than_100 - should panic ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests guessing_game running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Sieht gut aus! Lass uns nun einen Fehler in unseren Code einbringen, indem wir @@ -937,7 +941,7 @@ Wenn wir den Test in Codeblock 11-8 ausführen, wird er fehlschlagen: $ cargo test Compiling guessing_game v0.1.0 (file:///projects/guessing_game) Finished test [unoptimized + debuginfo] target(s) in 0.62s - Running unittests (target/debug/deps/guessing_game-57d70c3acb738f4d) + Running unittests src/lib.rs (target/debug/deps/guessing_game-57d70c3acb738f4d) running 1 test test tests::greater_than_100 - should panic ... FAILED @@ -950,9 +954,9 @@ note: test did not panic as expected failures: tests::greater_than_100 -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` ``` Wir erhalten in diesem Fall keine sehr hilfreiche Meldung, aber wenn wir uns @@ -995,7 +999,7 @@ mod tests { use super::*; #[test] - #[should_panic(expected = "Schätzwert muss kleiner oder gleich 100 sein")] + #[should_panic(expected = "kleiner oder gleich 100")] fn greater_than_100() { Guess::new(200); } @@ -1044,7 +1048,7 @@ vertauschen: # use super::*; # # #[test] -# #[should_panic(expected = "Guess value must be less than or equal to 100")] +# #[should_panic(expected = "kleiner oder gleich 100")] # fn greater_than_100() { # Guess::new(200); # } @@ -1057,7 +1061,7 @@ Wenn wir diesmal den `should_panic`-Test ausführen, wird er fehlschlagen: $ cargo test Compiling guessing_game v0.1.0 (file:///projects/guessing_game) Finished test [unoptimized + debuginfo] target(s) in 0.66s - Running unittests (target/debug/deps/guessing_game-57d70c3acb738f4d) + Running unittests src/lib.rs (target/debug/deps/guessing_game-57d70c3acb738f4d) running 1 test test tests::greater_than_100 - should panic ... FAILED @@ -1065,18 +1069,18 @@ test tests::greater_than_100 - should panic ... FAILED failures: ---- tests::greater_than_100 stdout ---- -thread 'main' panicked at 'Schätzwert muss größer oder gleich 1 sein, ist 200.', src/lib.rs:13:13 +thread 'tests::greater_than_100' panicked at 'Schätzwert muss größer oder gleich 1 sein, ist 200.', src/lib.rs:13:13 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace note: panic did not contain expected string panic message: `"Schätzwert muss größer oder gleich 1 sein, ist 200."`, - expected substring: `"Schätzwert muss kleiner oder gleich 100 sein"` + expected substring: `"kleiner oder gleich 100"` failures: tests::greater_than_100 -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` ``` Die Fehlermeldung zeigt an, dass dieser Test tatsächlich wie erwartet das diff --git a/src/ch11-02-running-tests.md b/src/ch11-02-running-tests.md index 4395bc6..ebc2179 100644 --- a/src/ch11-02-running-tests.md +++ b/src/ch11-02-running-tests.md @@ -105,7 +105,7 @@ sehen: $ cargo test Compiling silly-function v0.1.0 (file:///projects/silly-function) Finished test [unoptimized + debuginfo] target(s) in 0.58s - Running unittests (target/debug/deps/silly_function-160869f38cff9166) + Running unittests src/lib.rs (target/debug/deps/silly_function-160869f38cff9166) running 2 tests test tests::this_test_will_fail ... FAILED @@ -114,18 +114,19 @@ test tests::this_test_will_pass ... ok failures: ---- tests::this_test_will_fail stdout ---- -Ich habe den Wert 8 erhalten. -thread 'main' panicked at 'assertion failed: `(left == right)` +I got the value 8 +thread 'tests::this_test_will_fail' panicked at 'assertion failed: `(left == right)` left: `5`, right: `10`', src/lib.rs:19:9 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + failures: tests::this_test_will_fail -test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` ``` Beachte, dass wir nirgendwo in dieser Ausgabe `Ich habe den Wert 4 erhalten.` @@ -149,7 +150,7 @@ ausführen, sehen wir folgende Ausgabe: $ cargo test -- --show-output Compiling silly-function v0.1.0 (file:///projects/silly-function) Finished test [unoptimized + debuginfo] target(s) in 0.60s - Running unittests (target/debug/deps/silly_function-160869f38cff9166) + Running unittests src/lib.rs (target/debug/deps/silly_function-160869f38cff9166) running 2 tests test tests::this_test_will_fail ... FAILED @@ -160,24 +161,26 @@ successes: ---- tests::this_test_will_pass stdout ---- Ich habe den Wert 4 erhalten. + successes: tests::this_test_will_pass failures: ---- tests::this_test_will_fail stdout ---- -Ich habe den Wert 8 erhalten. -thread 'main' panicked at 'assertion failed: `(left == right)` +I got the value 8 +thread 'tests::this_test_will_fail' panicked at 'assertion failed: `(left == right)` left: `5`, right: `10`', src/lib.rs:19:9 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + failures: tests::this_test_will_fail -test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` ``` ### Ausführen einer Test-Teilmenge mittels Name @@ -230,20 +233,20 @@ Tests parallel laufen: $ cargo test Compiling adder v0.1.0 (file:///projects/adder) Finished test [unoptimized + debuginfo] target(s) in 0.62s - Running unittests (target/debug/deps/adder-92948b65e88960b4) + Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) running 3 tests test tests::add_three_and_two ... ok test tests::add_two_and_two ... ok test tests::one_hundred ... ok -test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests adder running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` #### Ausführen einzelner Tests @@ -255,12 +258,12 @@ um nur diesen Test auszuführen: $ cargo test one_hundred Compiling adder v0.1.0 (file:///projects/adder) Finished test [unoptimized + debuginfo] target(s) in 0.69s - Running unittests (target/debug/deps/adder-92948b65e88960b4) + Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) running 1 test test tests::one_hundred ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s ``` Nur der Test mit dem Namen `one_hundred` lief; die beiden anderen Tests passten @@ -283,13 +286,13 @@ Tests `add` enthalten, können wir diese beiden Tests ausführen, indem wir $ cargo test add Compiling adder v0.1.0 (file:///projects/adder) Finished test [unoptimized + debuginfo] target(s) in 0.61s - Running unittests (target/debug/deps/adder-92948b65e88960b4) + Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) running 2 tests test tests::add_three_and_two ... ok test tests::add_two_and_two ... ok -test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s ``` Dieser Befehl führte alle Tests mit `add` im Namen aus und filterte den Test @@ -328,19 +331,19 @@ aber `expensive_test` nicht: $ cargo test Compiling adder v0.1.0 (file:///projects/adder) Finished test [unoptimized + debuginfo] target(s) in 0.60s - Running unittests (target/debug/deps/adder-92948b65e88960b4) + Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) running 2 tests test expensive_test ... ignored test it_works ... ok -test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests adder running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Die Funktion `expensive_test` wird als `ignored` aufgeführt. Wenn wir nur die @@ -351,18 +354,18 @@ angeben: $ cargo test -- --ignored Compiling adder v0.1.0 (file:///projects/adder) Finished test [unoptimized + debuginfo] target(s) in 0.61s - Running unittests (target/debug/deps/adder-92948b65e88960b4) + Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) running 1 test test expensive_test ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s Doc-tests adder running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Indem du kontrollierst, welche Tests durchgeführt werden, kannst du diff --git a/src/ch11-03-test-organization.md b/src/ch11-03-test-organization.md index 9efaa43..3cb71a8 100644 --- a/src/ch11-03-test-organization.md +++ b/src/ch11-03-test-organization.md @@ -133,7 +133,7 @@ adder ├── Cargo.lock ├── Cargo.toml ├── src -│   └── lib.rs +│ └── lib.rs └── tests └── integration_test.rs ``` @@ -167,26 +167,26 @@ Dateien in diesem Verzeichnis nur dann, wenn wir `cargo test` ausführen. Führe ```console $ cargo test Compiling adder v0.1.0 (file:///projects/adder) - Finished test [unoptimized + debuginfo] target(s) in 0.73s - Running unittests (target/debug/deps/adder-92948b65e88960b4) + Finished test [unoptimized + debuginfo] target(s) in 1.31s + Running unittests src/lib.rs (target/debug/deps/adder-1082c4b063a8fbe6) running 1 test test tests::internal ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - Running unittests (target/debug/deps/integration_test-82e7799c1bc62298) + Running tests/integration_test.rs (target/debug/deps/integration_test-1082c4b063a8fbe6) running 1 test test it_adds_two ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests adder running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Die drei Abschnitte der Ausgabe umfassen die Modultests, den Integrationstest @@ -219,12 +219,12 @@ Tests in einer bestimmten Integrationstestdatei auszuführen, verwenden bei $ cargo test --test integration_test Compiling adder v0.1.0 (file:///projects/adder) Finished test [unoptimized + debuginfo] target(s) in 0.64s - Running unittests (target/debug/deps/integration_test-82e7799c1bc62298) + Running tests/integration_test.rs (target/debug/deps/integration_test-82e7799c1bc62298) running 1 test test it_adds_two ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Dieses Kommando führt nur die Tests in der Datei *tests/integration_test.rs* @@ -270,31 +270,31 @@ aufgerufen haben: $ cargo test Compiling adder v0.1.0 (file:///projects/adder) Finished test [unoptimized + debuginfo] target(s) in 0.89s - Running unittests (target/debug/deps/adder-92948b65e88960b4) + Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) running 1 test test tests::internal ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - Running unittests (target/debug/deps/common-7064e1b6d2e271be) + Running tests/common.rs (target/debug/deps/common-92948b65e88960b4) running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - Running unittests (target/debug/deps/integration_test-82e7799c1bc62298) + Running tests/integration_test.rs (target/debug/deps/integration_test-92948b65e88960b4) running 1 test test it_adds_two ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests adder running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Dass in den Testergebnissen `common` erscheint und dabei `running 0 tests` @@ -309,10 +309,10 @@ Projektverzeichnis sieht nun wie folgt aus: ├── Cargo.lock ├── Cargo.toml ├── src -│   └── lib.rs +│ └── lib.rs └── tests ├── common - │   └── mod.rs + │ └── mod.rs └── integration_test.rs ``` diff --git a/src/ch12-00-an-io-project.md b/src/ch12-00-an-io-project.md index 5f41e37..1fdddef 100644 --- a/src/ch12-00-an-io-project.md +++ b/src/ch12-00-an-io-project.md @@ -3,8 +3,8 @@ Dieses Kapitel ist eine Zusammenfassung der vielen Fähigkeiten, die du bisher gelernt hast, und eine Erkundung einiger weiterer Standard-Bibliotheks-Funktionalitäten. Wir werden ein Kommandozeilenwerkzeug -erstellen, das mit Datei- und Kommandozeilen-Ein- und -Ausgabe interagiert, um -einige der Rust-Konzepte zu üben, die du bereits gelernt hast. +erstellen, das mit der Datei- und der Terminal-Ein- und -Ausgabe interagiert, +um einige der Rust-Konzepte zu üben, die du bereits gelernt hast. Rusts Geschwindigkeit, Sicherheit, Ausgabe in eine einzelne Binärdatei und plattformübergreifende Unterstützung machen es zu einer idealen Sprache zum @@ -43,8 +43,8 @@ gelernt hast: * Schreiben von Tests ([Kapitel 11][chap11]) Wir werden auch kurz Funktionsabschlüsse (closures), Iteratoren und -Merkmalsobjekte (trait objects) vorstellen, die in den Kapiteln [13][ch13] und -[17][ch17] ausführlich behandelt werden. +Merkmalsobjekte (trait objects) vorstellen, die in den Kapiteln [13][chap13] +und [17][chap17] ausführlich behandelt werden. [chap7]: ch07-00-managing-growing-projects-with-packages-crates-and-modules.html [chap8]: ch08-00-common-collections.html diff --git a/src/ch12-01-accepting-command-line-arguments.md b/src/ch12-01-accepting-command-line-arguments.md index e31fd10..b9cb97d 100644 --- a/src/ch12-01-accepting-command-line-arguments.md +++ b/src/ch12-01-accepting-command-line-arguments.md @@ -17,7 +17,7 @@ Programm mit `cargo run`, einer zu suchenden Zeichenkette und einem Pfad zu einer Datei, in der gesucht werden soll, auszuführen: ```console -$ cargo run searchstring example-filename.txt +$ cargo run -- searchstring example-filename.txt ``` Im Moment kann das von `cargo new` generierte Programm die Argumente, die wir diff --git a/src/ch12-02-reading-a-file.md b/src/ch12-02-reading-a-file.md index 6e00931..325b05e 100644 --- a/src/ch12-02-reading-a-file.md +++ b/src/ch12-02-reading-a-file.md @@ -72,7 +72,7 @@ Kommandozeilenargument laufen (weil wir den Suchteil noch nicht implementiert haben) und die Datei *poem.txt* als zweites Argument: ```console -$ cargo run the poem.txt +$ cargo run -- the poem.txt Compiling minigrep v0.1.0 (file:///projects/minigrep) Finished dev [unoptimized + debuginfo] target(s) in 0.0s Running `target/debug/minigrep the poem.txt` diff --git a/src/ch12-03-improving-error-handling-and-modularity.md b/src/ch12-03-improving-error-handling-and-modularity.md index 84d2d58..a4decbb 100644 --- a/src/ch12-03-improving-error-handling-and-modularity.md +++ b/src/ch12-03-improving-error-handling-and-modularity.md @@ -2,7 +2,6 @@ Um unser Programm zu verbessern, werden wir vier Probleme beheben, die mit der Struktur des Programms und dem Umgang mit potenziellen Fehlern zu tun haben. - Erstens erfüllt unsere Funktion `main` jetzt zwei Aufgaben: Sie parst Argumente und liest Dateien. Für eine so kleine Funktion ist dies kein großes Problem. Wenn wir jedoch unser Programm innerhalb der Funktion `main` weiter ausbauen, @@ -752,17 +751,17 @@ warning: unused `Result` that must be used --> src/main.rs:19:5 | 19 | run(config); - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^ | - = note: `#[warn(unused_must_use)]` on by default = note: this `Result` may be an `Err` variant, which should be handled + = note: `#[warn(unused_must_use)]` on by default warning: `minigrep` (bin "minigrep") generated 1 warning Finished dev [unoptimized + debuginfo] target(s) in 0.71s Running `target/debug/minigrep the poem.txt` -Searching for the -In file poem.txt -With text: +Suche nach the +In Datei poem.txt +Mit text: I'm nobody! Who are you? Are you nobody, too? Then there's a pair of us - don't tell! diff --git a/src/ch12-04-testing-the-librarys-functionality.md b/src/ch12-04-testing-the-librarys-functionality.md index 3492c7a..258ae90 100644 --- a/src/ch12-04-testing-the-librarys-functionality.md +++ b/src/ch12-04-testing-the-librarys-functionality.md @@ -4,8 +4,8 @@ Jetzt, da wir die Logik nach *src/lib.rs* extrahiert haben und die Argumentkollektion und Fehlerbehandlung in *src/main.rs* belassen haben, ist es viel einfacher, Tests für die Kernfunktionalität unseres Codes zu schreiben. Wir können Funktionen direkt mit verschiedenen Argumenten aufrufen und -Rückgabewerte überprüfen, ohne unsere Binärdatei von der Kommandozeile aus -aufrufen zu müssen. +Rückgabewerte überprüfen, ohne unsere Binärdatei Terminal aus aufrufen zu +müssen. In diesem Abschnitt fügen wir dem `minigrep`-Programm die Suchlogik hinzu, indem wir die Methode der testgetriebenen Entwicklung (TDD) verwenden. Diese @@ -217,7 +217,7 @@ Lass uns jetzt den Test ausführen: $ cargo test Compiling minigrep v0.1.0 (file:///projects/minigrep) Finished test [unoptimized + debuginfo] target(s) in 0.97s - Running target/debug/deps/minigrep-4672b652f7794785 + Running unittests src/lib.rs (target/debug/deps/minigrep-9cd200e5fac0fc94) running 1 test test tests::one_result ... FAILED @@ -225,17 +225,18 @@ test tests::one_result ... FAILED failures: ---- tests::one_result stdout ---- -thread 'main' panicked at 'assertion failed: `(left == right)` - left: `["safe, fast, productive."]`, +thread 'tests::one_result' panicked at 'assertion failed: `(left == right)` + left: `["sicher, schnell, produktiv."]`, right: `[]`', src/lib.rs:44:9 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + failures: tests::one_result -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` ``` Toll, der Test schlägt fehl, genau wie wir erwartet haben. Bringen wir den Test @@ -471,24 +472,24 @@ enthalten, und unser Test sollte erfolgreich sein. Lass uns den Test ausführen: $ cargo test Compiling minigrep v0.1.0 (file:///projects/minigrep) Finished test [unoptimized + debuginfo] target(s) in 1.22s - Running target/debug/deps/minigrep-4672b652f7794785 + Running unittests src/lib.rs (target/debug/deps/minigrep-9cd200e5fac0fc94) running 1 test test tests::one_result ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - Running target/debug/deps/minigrep-caf9dbee196c78b9 + Running unittests src/main.rs (target/debug/deps/minigrep-9cd200e5fac0fc94) running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests minigrep running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Unser Test war erfolgreich, also wissen wir, dass es funktioniert! diff --git a/src/ch12-05-working-with-environment-variables.md b/src/ch12-05-working-with-environment-variables.md index b814539..f4f275c 100644 --- a/src/ch12-05-working-with-environment-variables.md +++ b/src/ch12-05-working-with-environment-variables.md @@ -263,25 +263,25 @@ Warten wir ab, ob diese Implementierung die Tests besteht: $ cargo test Compiling minigrep v0.1.0 (file:///projects/minigrep) Finished test [unoptimized + debuginfo] target(s) in 1.33s - Running target/debug/deps/minigrep-4672b652f7794785 + Running unittests src/lib.rs (target/debug/deps/minigrep-9cd200e5fac0fc94) running 2 tests test tests::case_insensitive ... ok test tests::case_sensitive ... ok -test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - Running target/debug/deps/minigrep-caf9dbee196c78b9 + Running unittests src/main.rs (target/debug/deps/minigrep-9cd200e5fac0fc94) running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests minigrep running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Großartig! Sie haben bestanden. Lass uns nun die neue Funktion @@ -535,7 +535,7 @@ impl Config { let query = args[1].clone(); let file_path = args[2].clone(); - let case_sensitive = env::var("CASE_INSENSITIVE").is_err(); + let case_sensitive = env::var("IGNORE_CASE").is_err(); Ok(Config { query, @@ -686,9 +686,6 @@ Wir sollten Zeilen erhalten, die „to“ enthalten, die Großbuchstaben haben könnten: ```console -$ CASE_INSENSITIVE=1 cargo run to poem.txt - Finished dev [unoptimized + debuginfo] target(s) in 0.0s - Running `target/debug/minigrep to poem.txt` Are you nobody, too? How dreary to be somebody! To tell your name the livelong day diff --git a/src/ch13-01-closures.md b/src/ch13-01-closures.md index c2fca8b..de1c763 100644 --- a/src/ch13-01-closures.md +++ b/src/ch13-01-closures.md @@ -403,9 +403,9 @@ use std::thread; fn main() { let list = vec![1, 2, 3]; - println!("Before defining closure: {:?}", list); + println!("Vor der Funktionsabschlussdefinition: {:?}", list); - thread::spawn(move || println!("From thread: {:?}", list)) + thread::spawn(move || println!("Im Strang: {:?}", list)) .join() .unwrap(); } diff --git a/src/ch13-02-iterators.md b/src/ch13-02-iterators.md index 0fdb363..cb91795 100644 --- a/src/ch13-02-iterators.md +++ b/src/ch13-02-iterators.md @@ -205,10 +205,10 @@ warning: unused `Map` that must be used --> src/main.rs:4:5 | 4 | v1.iter().map(|x| x + 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unused_must_use)]` on by default = note: iterators are lazy and do nothing unless consumed + = note: `#[warn(unused_must_use)]` on by default warning: `iterators` (bin "iterators") generated 1 warning Finished dev [unoptimized + debuginfo] target(s) in 0.47s diff --git a/src/ch14-02-publishing-to-crates-io.md b/src/ch14-02-publishing-to-crates-io.md index 25d47ab..0a4d181 100644 --- a/src/ch14-02-publishing-to-crates-io.md +++ b/src/ch14-02-publishing-to-crates-io.md @@ -412,6 +412,12 @@ API-Schlüssel auf: ```console $ cargo login abcdefghijklmnopqrstuvwxyz012345 ``` + +Diese Kommando informiert Cargo über dein API-Token und speichert es lokal in +*~/.cargo/credentials*. Beachte, dass dieses Token ein *Geheimnis* ist: Gib es +nicht an andere weiter. Wenn du es aus irgendeinem Grund mit jemandem teilst, +solltest du es widerrufen und ein neues Token auf [crates.io][crates] erzeugen. + ### Metadaten zu einer neuen Kiste hinzufügen Angenommen, du hast eine Kiste, die du veröffentlichen möchtest. Vor dem diff --git a/src/ch14-03-cargo-workspaces.md b/src/ch14-03-cargo-workspaces.md index 62ed01b..93d5b71 100644 --- a/src/ch14-03-cargo-workspaces.md +++ b/src/ch14-03-cargo-workspaces.md @@ -154,11 +154,7 @@ use add_one; fn main() { let num = 10; - println!( - "Hello, world! {} plus one is {}!", - num, - add_one::add_one(num) - ); + println!("Hello, world! {num} plus one is {}!", add_one::add_one(num)); } ``` @@ -206,7 +202,7 @@ verwenden können: ```toml [dependencies] -rand = "0.8.3" +rand = "0.8.5" ``` Wir können nun `use rand;` zur Datei *add_one/src/lib.rs* hinzufügen, und wenn @@ -300,19 +296,19 @@ $ cargo test running 1 test test tests::it_works ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Running unittests src/main.rs (target/debug/deps/adder-49979ff40686fa8e) running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests add_one running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Der erste Abschnitt der Ausgabe zeigt, dass der Test `it_works` in der @@ -332,13 +328,13 @@ $ cargo test -p add_one running 1 test test tests::it_works ... ok -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s Doc-tests add_one running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Die Ausgabe zeigt, dass `cargo test` nur die Tests für die Kiste `add_one` aber diff --git a/src/ch15-01-box.md b/src/ch15-01-box.md index f6e3609..2684d0c 100644 --- a/src/ch15-01-box.md +++ b/src/ch15-01-box.md @@ -169,7 +169,6 @@ enthält. Dieser `List`-Wert ist ein weiterer `Cons`, der `3` enthält und ein `List`, der schließlich `Nil` ist, die nicht rekursive Variante, die das Ende der Liste signalisiert. - Wenn wir versuchen den Programmcode in Codeblock 15-3 zu kompilieren, erhalten wir den Fehler der in Codeblock 15-4 gezeigt wird: @@ -180,27 +179,17 @@ error[E0072]: recursive type `List` has infinite size --> src/main.rs:1:1 | 1 | enum List { - | ^^^^^^^^^ recursive type has infinite size + | ^^^^^^^^^ 2 | Cons(i32, List), | ---- recursive without indirection | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `List` representable +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle | 2 | Cons(i32, Box), | ++++ + -error[E0391]: cycle detected when computing drop-check constraints for `List` - --> src/main.rs:1:1 - | -1 | enum List { - | ^^^^^^^^^ - | - = note: ...which again requires computing drop-check constraints for `List`, completing the cycle - = note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: List } }` - -Some errors have detailed explanations: E0072, E0391. -For more information about an error, try `rustc --explain E0072`. -error: could not compile `cons-list` due to 2 previous errors +For more information about this error, try `rustc --explain E0072`. +error: could not compile `cons-list` due to previous error ``` Codeblock 15-4: Der Fehler den wir erhalten wenn wir diff --git a/src/ch15-02-deref.md b/src/ch15-02-deref.md index f345669..3875deb 100644 --- a/src/ch15-02-deref.md +++ b/src/ch15-02-deref.md @@ -65,10 +65,20 @@ error[E0277]: can't compare `{integer}` with `&{integer}` --> src/main.rs:6:5 | 6 | assert_eq!(5, y); - | ^^^^^^^^^^^^^^^^^ no implementation for `{integer} == &{integer}` + | ^^^^^^^^^^^^^^^^ no implementation for `{integer} == &{integer}` | = help: the trait `PartialEq<&{integer}>` is not implemented for `{integer}` - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z external-macro-backtrace for more info) + = help: the following other types implement trait `PartialEq`: + f32 + f64 + i128 + i16 + i32 + i64 + i8 + isize + and 6 others + = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) For more information about this error, try `rustc --explain E0277`. error: could not compile `deref-example` due to previous error diff --git a/src/ch15-03-drop.md b/src/ch15-03-drop.md index d9885a7..473de0c 100644 --- a/src/ch15-03-drop.md +++ b/src/ch15-03-drop.md @@ -43,7 +43,7 @@ struct CustomSmartPointer { impl Drop for CustomSmartPointer { fn drop(&mut self) { - println!("CustomSmartPointer und Daten aufräumen: `{}`!", self.data); + println!("CustomSmartPointer mit Daten aufräumen: `{}`!", self.data); } } @@ -84,8 +84,8 @@ $ cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.60s Running `target/debug/drop-example` CustomSmartPointers erzeugt. -CustomSmartPointer und Daten aufräumen: `andere Sachen`! -CustomSmartPointer und Daten aufräumen: `meine Sache`! +CustomSmartPointer mit Daten aufräumen: `andere Sachen`! +CustomSmartPointer mit Daten aufräumen: `meine Sache`! ``` Rust hat für uns automatisch `drop` und den von uns angegebenen Programmcode aufgerufen, sobald unsere Instanzen den Gültigkeitsbereich verlassen haben. @@ -122,7 +122,7 @@ indem wir die `main`-Funktion aus Codeblock 15-14 ändern, wie im Codeblock # # impl Drop for CustomSmartPointer { # fn drop(&mut self) { -# println!("CustomSmartPointer und Daten aufräumen: `{}`!", self.data); +# println!("CustomSmartPointer mit Daten aufräumen: `{}`!", self.data); # } # } # @@ -189,7 +189,7 @@ Funktion befindet sich im Präludium, daher können wir `main` in Codeblock 15-1 # # impl Drop for CustomSmartPointer { # fn drop(&mut self) { -# println!("CustomSmartPointer und Daten aufräumen: `{}`!", self.data); +# println!("CustomSmartPointer mit Daten aufräumen: `{}`!", self.data); # } # } # @@ -214,11 +214,11 @@ $ cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.73s Running `target/debug/drop-example` CustomSmartPointer erzeugt. -CustomSmartPointer und Daten aufräumen: `Daten`! +CustomSmartPointer mit Daten aufräumen: `Daten`! CustomSmartPointer vor dem Ende von main aufgeräumt. ``` -Der Text ```CustomSmartPointer und Daten aufräumen: `Daten`!``` wird zwischen +Der Text ```CustomSmartPointer mit Daten aufräumen: `Daten`!``` wird zwischen `CustomSmartPointer erzeugt` und `CustomSmartPointer vor dem Ende von main aufgeräumt.` ausgegeben und zeigt, dass der `drop`-Methodencode aufgerufen wird um `c` an diesem Punkt aufzuräumen. diff --git a/src/ch15-04-rc.md b/src/ch15-04-rc.md index 140f9e3..6489788 100644 --- a/src/ch15-04-rc.md +++ b/src/ch15-04-rc.md @@ -189,7 +189,8 @@ fn main() { let c = Cons(4, Rc::clone(&a)); println!("Zähler nach der Erstellung von c = {}", Rc::strong_count(&a)); } - println!("Zahler nachdem c den Gültigkeitsbereich verlässt = {}", Rc::strong_count(&a)); + println!("Zahler nachdem c den Gültigkeitsbereich verlässt = {}", + Rc::strong_count(&a)); } ``` diff --git a/src/ch15-05-interior-mutability.md b/src/ch15-05-interior-mutability.md index 2a8a587..e199163 100644 --- a/src/ch15-05-interior-mutability.md +++ b/src/ch15-05-interior-mutability.md @@ -342,13 +342,11 @@ error[E0596]: cannot borrow `self.sent_messages` as mutable, as it is behind a ` | ----- help: consider changing that to be a mutable reference: `&mut self` ... 58 | self.sent_messages.push(String::from(message)); - | ^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable For more information about this error, try `rustc --explain E0596`. error: could not compile `limit-tracker` due to previous error - warning: build failed, waiting for other jobs to finish... -error: build failed ``` Wir können den `MockMessenger` nicht ändern, um die Nachrichten zu verfolgen, da @@ -594,7 +592,7 @@ test tests::it_sends_an_over_75_percent_warning_message ... FAILED failures: ---- tests::it_sends_an_over_75_percent_warning_message stdout ---- -thread 'main' panicked at 'already borrowed: BorrowMutError', src/lib.rs:60:53 +thread 'tests::it_sends_an_over_75_percent_warning_message' panicked at 'already borrowed: BorrowMutError', src/lib.rs:60:53 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace @@ -603,7 +601,7 @@ failures: test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s -error: test failed, to rerun pass '--lib' +error: test failed, to rerun pass `--lib` ``` Beachte, dass der Programmcode mit der Meldung `already borrowed: BorrowMutError` abstürzt. Auf diese Weise behandelt `RefCell` zur @@ -661,9 +659,9 @@ fn main() { *value.borrow_mut() += 10; - println!("a after = {:?}", a); - println!("b after = {:?}", b); - println!("c after = {:?}", c); + println!("a nachher = {:?}", a); + println!("b nachher = {:?}", b); + println!("c nachher = {:?}", c); } ``` @@ -697,9 +695,9 @@ $ cargo run Compiling cons-list v0.1.0 (file:///projects/cons-list) Finished dev [unoptimized + debuginfo] target(s) in 0.63s Running `target/debug/cons-list` -a after = Cons(RefCell { value: 15 }, Nil) -b after = Cons(RefCell { value: 3 }, Cons(RefCell { value: 15 }, Nil)) -c after = Cons(RefCell { value: 4 }, Cons(RefCell { value: 15 }, Nil)) +a nachher = Cons(RefCell { value: 15 }, Nil) +b nachher = Cons(RefCell { value: 3 }, Cons(RefCell { value: 15 }, Nil)) +c nachher = Cons(RefCell { value: 4 }, Cons(RefCell { value: 15 }, Nil)) ``` Diese Technik ist ziemlich sauber! Durch die Verwendung von `RefCell` haben diff --git a/src/ch15-06-reference-cycles.md b/src/ch15-06-reference-cycles.md index 4e8978c..d7ec289 100644 --- a/src/ch15-06-reference-cycles.md +++ b/src/ch15-06-reference-cycles.md @@ -211,12 +211,6 @@ verwendet `weak_count`, um den Überblick zu behalten wie viele Unterschied besteht darin, dass `weak_count` nicht 0 sein muss, damit die `Rc`-Instanz aufgeräumt wird. -Mit starken Referenzen kann man die Eigentümerschaft einer `Rc`-Instanz -teilen, schwache Referenzen drücken hingegen keine Eigentümerschafts-Beziehung -aus. Sie verursachen keinen Referenzzyklus, da jeder Zyklus mit schwachen -Referenzen unterbrochen wird, sobald die starke Referenzanzahl der beteiligten -Werte 0 beträgt. - Da der Wert, auf den `Weak` referenziert, möglicherweise aufgeräumt wurde, musst du sicherstellen, dass der Wert noch vorhanden ist, um etwas mit dem Wert zu tun, auf den ein `Weak` zeigt. Ruft man dazu die Methode `upgrade` für eine diff --git a/src/ch16-01-threads.md b/src/ch16-01-threads.md index 99db44b..6b786fb 100644 --- a/src/ch16-01-threads.md +++ b/src/ch16-01-threads.md @@ -282,7 +282,7 @@ note: function requires argument type to outlive `'static` help: to force the closure to take ownership of `v` (and any other referenced variables), use the `move` keyword | 6 | let handle = thread::spawn(move || { - | ^^^^^^^ + | ++++ For more information about this error, try `rustc --explain E0373`. error: could not compile `threads` due to previous error diff --git a/src/ch16-02-message-passing.md b/src/ch16-02-message-passing.md index 2484603..42e08ce 100644 --- a/src/ch16-02-message-passing.md +++ b/src/ch16-02-message-passing.md @@ -219,6 +219,8 @@ error[E0382]: borrow of moved value: `val` | --- value moved here 10 | println!("val ist {}", val); | ^^^ value borrowed here after move + | + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) For more information about this error, try `rustc --explain E0382`. error: could not compile `message-passing` due to previous error diff --git a/src/ch16-03-shared-state.md b/src/ch16-03-shared-state.md index 5bf0e1c..4f87797 100644 --- a/src/ch16-03-shared-state.md +++ b/src/ch16-03-shared-state.md @@ -242,20 +242,30 @@ lehrt uns eine Menge. $ cargo run Compiling shared-state v0.1.0 (file:///projects/shared-state) error[E0277]: `Rc>` cannot be sent between threads safely - --> src/main.rs:11:22 - | -11 | let handle = thread::spawn(move || { - | ______________________^^^^^^^^^^^^^_- - | | | - | | `Rc>` cannot be sent between threads safely -12 | | let mut num = counter.lock().unwrap(); -13 | | -14 | | *num += 1; -15 | | }); - | |_________- within this `[closure@src/main.rs:11:36: 15:10]` - | - = help: within `[closure@src/main.rs:11:36: 15:10]`, the trait `Send` is not implemented for `Rc>` - = note: required because it appears within the type `[closure@src/main.rs:11:36: 15:10]` + --> src/main.rs:11:36 + | +11 | let handle = thread::spawn(move || { + | ------------- ^------ + | | | + | ______________________|_____________within this `[closure@src/main.rs:11:36: 11:43]` + | | | + | | required by a bound introduced by this call +12 | | let mut num = counter.lock().unwrap(); +13 | | +14 | | *num += 1; +15 | | }); + | |_________^ `Rc>` cannot be sent between threads safely + | + = help: within `[closure@src/main.rs:11:36: 11:43]`, the trait `Send` is not implemented for `Rc>` +note: required because it's used within this closure + --> src/main.rs:11:36 + | +11 | let handle = thread::spawn(move || { + | ^^^^^^^ +note: required by a bound in `spawn` + --> /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/thread/mod.rs:704:8 + | + = note: required by this bound in `spawn` For more information about this error, try `rustc --explain E0277`. error: could not compile `shared-state` due to previous error diff --git a/src/ch18-02-refutability.md b/src/ch18-02-refutability.md index c1674b5..e623484 100644 --- a/src/ch18-02-refutability.md +++ b/src/ch18-02-refutability.md @@ -52,19 +52,27 @@ abweisbares Muster zu verwenden, wo ein unabweisbares Muster erforderlich ist: $ cargo run Compiling patterns v0.1.0 (file:///projects/patterns) error[E0005]: refutable pattern in local binding: `None` not covered - --> src/main.rs:3:9 - | -3 | let Some(x) = some_option_value; - | ^^^^^^^ pattern `None` not covered - | - = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + --> src/main.rs:3:9 + | +3 | let Some(x) = some_option_value; + | ^^^^^^^ pattern `None` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html note: `Option` defined here - = note: the matched value is of type `Option` + --> /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/option.rs:518:1 + | + = note: +/rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/option.rs:522:5: not covered + = note: the matched value is of type `Option` help: you might want to use `if let` to ignore the variant that isn't matched - | -3 | let x = if let Some(x) = some_option_value { x } else { todo!() }; - | ++++++++++ ++++++++++++++++++++++ + | +3 | let x = if let Some(x) = some_option_value { x } else { todo!() }; + | ++++++++++ ++++++++++++++++++++++ +help: alternatively, you might want to use let else to handle the variant that isn't matched + | +3 | let Some(x) = some_option_value else { todo!() }; + | ++++++++++++++++ For more information about this error, try `rustc --explain E0005`. error: could not compile `patterns` due to previous error @@ -120,9 +128,9 @@ warning: irrefutable `if let` pattern 2 | if let x = 5 { | ^^^^^^^^^ | - = note: `#[warn(irrefutable_let_patterns)]` on by default = note: this pattern will always match, so the `if let` is useless = help: consider replacing the `if let` with a `let` + = note: `#[warn(irrefutable_let_patterns)]` on by default warning: `patterns` (bin "patterns") generated 1 warning Finished dev [unoptimized + debuginfo] target(s) in 0.39s diff --git a/src/ch18-03-pattern-syntax.md b/src/ch18-03-pattern-syntax.md index d8f3781..6e60457 100644 --- a/src/ch18-03-pattern-syntax.md +++ b/src/ch18-03-pattern-syntax.md @@ -293,15 +293,11 @@ fn main() { println!("Die Quit-Variante hat keine Daten zu destrukturieren.") } Message::Move { x, y } => { - println!( - "Bewege in x-Richtung {} und in y-Richtung {}", - x, y - ); + println!("Bewege in x-Richtung {x} und in y-Richtung {y}"); } Message::Write(text) => println!("Textnachricht: {}", text), Message::ChangeColor(r, g, b) => println!( - "Ändere die Farbe in rot {}, grün {} und blau {}", - r, g, b + "Ändere die Farbe in rot {r}, grün {g} und blau {b}" ), } } @@ -356,14 +352,12 @@ fn main() { let msg = Message::ChangeColor(Color::Hsv(0, 160, 255)); match msg { - Message::ChangeColor(Color::Rgb(r, g, b)) => println!( - "Ändere die Farbe in rot {}, grün {} und blau {}", - r, g, b - ), - Message::ChangeColor(Color::Hsv(h, s, v)) => println!( - "Ändere die Farbe in Farbwert {}, Sättigung {} und Hellwert {}", - h, s, v - ), + Message::ChangeColor(Color::Rgb(r, g, b)) => { + println!("Ändere die Farbe in rot {r}, grün {g} und blau {b}"); + } + Message::ChangeColor(Color::Hsv(h, s, v)) => { + println!("Ändere die Farbe in Farbwert {h}, Sättigung {s} und Hellwert {v}") + } _ => (), } } diff --git a/src/ch19-03-advanced-traits.md b/src/ch19-03-advanced-traits.md index c697dd7..acab90d 100644 --- a/src/ch19-03-advanced-traits.md +++ b/src/ch19-03-advanced-traits.md @@ -525,15 +525,21 @@ Kompilierfehler erhalten: ```console $ cargo run Compiling traits-example v0.1.0 (file:///projects/traits-example) -error[E0283]: type annotations needed +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> src/main.rs:20:43 | -20 | println!("A baby dog is called a {}", Animal::baby_name()); - | ^^^^^^^^^^^^^^^^^ cannot infer type +2 | fn baby_name() -> String; + | ------------------------- `Animal::baby_name` defined here +... +20 | println!("Ein Hundebaby wird {} genannt.", Animal::baby_name()); + | ^^^^^^^^^^^^^^^^^ cannot call associated function of trait | - = note: cannot satisfy `_: Animal` +help: use the fully-qualified path to the only available implementation + | +20 | println!("Ein Hundebaby wird {} genannt.", ::baby_name()); + | +++++++ + -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0790`. error: could not compile `traits-example` due to previous error ``` diff --git a/src/ch19-04-advanced-types.md b/src/ch19-04-advanced-types.md index 1980734..b8b2854 100644 --- a/src/ch19-04-advanced-types.md +++ b/src/ch19-04-advanced-types.md @@ -375,18 +375,16 @@ machen die Typen `s1` und `s2` zu einem `&str` anstatt zu einem `str`. Erinnere dich, dass wir im Abschnitt [„Zeichenkettenanteilstypen (string slices)“][string-slices] in Kapitel 4 gesagt haben, dass die Anteilstypen-Datenstruktur die Startposition und die Länge des Anteilstyps -speichert. - -Obwohl also `&T` ein einzelner Wert ist, der die Speicheradresse des Ortes -speichert, an dem sich `T` befindet, hat `&str` *zwei* Werte: Die Adresse von -`str` und seine Länge. Als solches können wir die Größe eines `&str`-Wertes zur -Kompilierzeit kennen: Er ist doppelt so lang wie ein `usize`. Das heißt, wir -wissen immer die Größe einer `&str`, egal wie lang die Zeichenkette ist, auf -die sie sich bezieht. Im Allgemeinen werden in Rust Typen mit dynamischer Größe -auf diese Weise verwendet: Sie haben ein zusätzliches Stück Metadaten, das die -Größe der dynamischen Information speichert. Die goldene Regel für Typen -dynamischer Größe lautet, dass wir Werte von Typen mit dynamischer Größe immer -hinter eine Art Zeiger stellen müssen. +speichert. Obwohl also `&T` ein einzelner Wert ist, der die Speicheradresse des +Ortes speichert, an dem sich `T` befindet, hat `&str` *zwei* Werte: Die Adresse +von `str` und seine Länge. Als solches können wir die Größe eines `&str`-Wertes +zur Kompilierzeit kennen: Er ist doppelt so lang wie ein `usize`. Das heißt, +wir wissen immer die Größe einer `&str`, egal wie lang die Zeichenkette ist, +auf die sie sich bezieht. Im Allgemeinen werden in Rust Typen mit dynamischer +Größe auf diese Weise verwendet: Sie haben ein zusätzliches Stück Metadaten, +das die Größe der dynamischen Information speichert. Die goldene Regel für +Typen dynamischer Größe lautet, dass wir Werte von Typen mit dynamischer Größe +immer hinter eine Art Zeiger stellen müssen. Wir können `str` mit allen Arten von Zeigern kombinieren: Zum Beispiel `Box` oder `Rc`. Tatsächlich hast du das schon einmal gesehen, aber diff --git a/src/ch20-01-single-threaded.md b/src/ch20-01-single-threaded.md index 092cf71..23fb4d2 100644 --- a/src/ch20-01-single-threaded.md +++ b/src/ch20-01-single-threaded.md @@ -410,13 +410,13 @@ lesen, sie der Antwort als Rumpf hinzuzufügen und sie zu senden. Dateiname: src/main.rs ```rust,no_run -use std::fs; +use std::{ + fs, + io::{prelude::*, BufReader}, + net::{TcpListener, TcpStream}, +}; // --abschneiden-- -# use std::io::prelude::*; -# use std::net::TcpListener; -# use std::net::TcpStream; -# # fn main() { # let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); # @@ -428,19 +428,21 @@ use std::fs; # } # fn handle_connection(mut stream: TcpStream) { - let mut buffer = [0; 1024]; - stream.read(&mut buffer).unwrap(); + let buf_reader = BufReader::new(&mut stream); + let http_request: Vec<_> = buf_reader + .lines() + .map(|result| result.unwrap()) + .take_while(|line| !line.is_empty()) + .collect(); + let status_line = "HTTP/1.1 200 OK"; let contents = fs::read_to_string("hello.html").unwrap(); + let length = contents.len(); - let response = format!( - "HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}", - contents.len(), - contents - ); + let response = + format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - stream.write(response.as_bytes()).unwrap(); - stream.flush().unwrap(); + stream.write_all(response.as_bytes()).unwrap(); } ``` diff --git a/src/ch20-02-multithreaded.md b/src/ch20-02-multithreaded.md index cd418ef..89f73ff 100644 --- a/src/ch20-02-multithreaded.md +++ b/src/ch20-02-multithreaded.md @@ -428,10 +428,10 @@ Lass uns den Code noch einmal überprüfen: $ cargo check Checking hello v0.1.0 (file:///projects/hello) error[E0599]: no method named `execute` found for struct `ThreadPool` in the current scope - --> src/bin/main.rs:16:14 + --> src/main.rs:17:14 | -16 | pool.execute(|| { - | ^^^^^^^ method not found in `hello::ThreadPool` +17 | pool.execute(|| { + | ^^^^^^^ method not found in `ThreadPool` For more information about this error, try `rustc --explain E0599`. error: could not compile `hello` due to previous error @@ -799,6 +799,15 @@ die wir ihr geben, und speichert eine `JoinHandle<()>`-Instanz, die durch das Erzeugen eines neuen Strangs unter Verwendung eines leeren Funktionsabschlusses erzeugt wird. +> Hinweis: Wenn das Betriebssystem keinen Strang erstellen kann, weil nicht +> genügend Systemressourcen vorhanden sind, bringt `thread::spawn` das Programm +> zum Abstürzen. Das führt dazu, dass unser gesamter Server abstürzt, auch wenn +> die Erstellung einiger Stränge erfolgreich wäre. Der Einfachheit halber +> lassen wir es bei diesem Verhalten, aber in einer produktiven +> Strang-Pool-Implementierung würdest du wahrscheinlich +> [`std::thread::Builder`][builder] mit der Methode [`spawn`][builder-spawn] +> verwenden wollen, die stattdessen `Result` zurückgibt. + Dieser Code kompiliert und speichert die Anzahl der `Worker`-Instanzen, die wir als Argument für `ThreadPool::new` angegeben haben. Aber wir *verarbeiten* noch nicht den Funktionsabschluss, den wir in `execute` erhalten. Schauen wir uns @@ -1446,9 +1455,9 @@ temporäre Werte erst am Ende des zugehörigen Blocks frei. In Codeblock 20-21 bleibt die Sperre für die Dauer des Aufrufs von `job()` erhalten, was bedeutet, dass andere `Worker` keine Aufträge erhalten können. -[type-synonyms]: -ch19-04-advanced-types.html#erstellen-von-typ-synonymen-mit-typ-alias +[builder]: https://doc.rust-lang.org/std/thread/struct.Builder.html +[builder-spawn]: https://doc.rust-lang.org/std/thread/struct.Builder.html#method.spawn +[fn-traits]: ch13-01-closures.html#verschieben-erfasster-werte-aus-funktionsabschlüssen-und-fn-merkmalen [integer-types]: ch03-02-data-types.html#ganzzahl-typen [similar-interface]: #erstellen-einer-endliche-anzahl-von-strängen -[fn-traits]: -ch13-01-closures.html#verschieben-erfasster-werte-aus-funktionsabschlüssen-und-fn-merkmalen +[type-synonyms]: ch19-04-advanced-types.html#erstellen-von-typ-synonymen-mit-typ-alias diff --git a/src/ch20-03-graceful-shutdown-and-cleanup.md b/src/ch20-03-graceful-shutdown-and-cleanup.md index 5a44ea0..a95dfa9 100644 --- a/src/ch20-03-graceful-shutdown-and-cleanup.md +++ b/src/ch20-03-graceful-shutdown-and-cleanup.md @@ -120,14 +120,15 @@ Hier ist der Fehler, den wir erhalten, wenn wir diesen Code kompilieren: $ cargo check Checking hello v0.1.0 (file:///projects/hello) error[E0507]: cannot move out of `worker.thread` which is behind a mutable reference - --> src/lib.rs:52:13 - | -52 | worker.thread.join().unwrap(); - | ^^^^^^^^^^^^^ ------ `worker.thread` moved due to this method call - | | - | move occurs because `worker.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait - | + --> src/lib.rs:52:13 + | +52 | worker.thread.join().unwrap(); + | ^^^^^^^^^^^^^ ------ `worker.thread` moved due to this method call + | | + | move occurs because `worker.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait + | note: this function takes ownership of the receiver `self`, which moves `worker.thread` + --> /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/thread/mod.rs:1581:17 For more information about this error, try `rustc --explain E0507`. error: could not compile `hello` due to previous error @@ -238,6 +239,13 @@ error[E0599]: no method named `join` found for enum `Option` in the current scop | 52 | worker.thread.join().unwrap(); | ^^^^ method not found in `Option>` + | +note: the method `join` exists on the type `JoinHandle<()>` + --> /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/thread/mod.rs:1581:5 +help: consider using `Option::expect` to unwrap the `JoinHandle<()>` value, panicking if the value is an `Option::None` + | +52 | worker.thread.expect("REASON").join().unwrap(); + | +++++++++++++++++ error[E0308]: mismatched types --> src/lib.rs:72:22 diff --git a/src/title-page.md b/src/title-page.md index c665752..4624d40 100644 --- a/src/title-page.md +++ b/src/title-page.md @@ -3,22 +3,26 @@ *von Steve Klabnik und Carol Nichols, unter Mitarbeit der Rust-Gemeinschaft;* *übersetzt ins Deutsche durch die Rust-Gemeinschaft* -Diese Version des Textes geht davon aus, dass du Rust 1.65 (veröffentlicht am -2022-11-03) oder später verwendest. Siehe [Abschnitt „Installation“ in Kapitel +Diese Version des Textes geht davon aus, dass du Rust 1.67.1 (veröffentlicht am +2023-02-09) oder später verwendest. Siehe [Abschnitt „Installation“ in Kapitel 1][install1] zum Installieren und Aktualisieren von Rust. Die HTML-Version ist online verfügbar unter -[https://doc.rust-lang.org/stable/book/](https://doc.rust-lang.org/stable/book/) +[https://doc.rust-lang.org/stable/book/][rustbook-en] (englisches Original) und unter -[https://rust-lang-de.github.io/rustbook-de/](https://rust-lang-de.github.io/rustbook-de/) -(deutsche Übersetzung) und offline mit Rust-Installationen, die mit `rustup` +[https://rust-lang-de.github.io/rustbook-de/][rustbook-de] +(deutsche Übersetzung) sowie offline in Rust-Installationen, die mit `rustup` erfolgt sind; führe `rustup docs --book` aus um es zu öffnen. Es sind weitere [Gemeinschaftsübersetzungen][translations] verfügbar. -Der englische Text ist auch als [Taschenbuch und E-Book bei No Starch -Press][nsprust] erhältlich. +Der englische Text ist als [Taschenbuch und E-Book bei No Starch +Press][nsprust] erhältlich, den deutschen Text gibt es ebenfalls als +[Taschenbuch und E-Book][rust-lernen]. [install1]: ch01-01-installation.html [nsprust]: https://nostarch.com/rust-programming-language-2nd-edition +[rustbook-de]: https://rust-lang-de.github.io/rustbook-de/ +[rustbook-en]: https://doc.rust-lang.org/stable/book/ +[rust-lernen]: https://rust-lernen.de/ [translations]: appendix-06-translation.html