Skip to content

Commit

Permalink
Merge pull request #380 from damoasda/master
Browse files Browse the repository at this point in the history
Änderungen im Originalbuch bis zum 05.10.2024 nachziehen
  • Loading branch information
damoasda authored Oct 6, 2024
2 parents 24c5dec + 0c1e791 commit 12ceb66
Show file tree
Hide file tree
Showing 50 changed files with 879 additions and 551 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pages-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
toolchain: stable

- name: Install mdbook
run: cargo install mdbook --vers "^0.4.37" --no-default-features
run: cargo install mdbook --vers "^0.4.40" --no-default-features

- name: Build Book
run: mdbook build
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Das Buch „Die Programmiersprache Rust“ ist eine deutsche Gemeinschafts-Übersetzung
des [offiziellen Rust-Buchs][rustbook-en].
Es enthält alle Änderungen des englischen Originals bis einschließlich zum **11.05.2024**.
Es enthält alle Änderungen des englischen Originals bis einschließlich zum **05.10.2024**.

## [📖 > Hier online lesen < 📖][rustbook-de]

Expand All @@ -14,7 +14,7 @@ Die deutsche Übersetzung gibt es auch als **Taschenbuch** und als **E-Book**:

Schritte zum Bauen und Anschauen des Buchs:

1. mdBook installieren: `cargo install mdbook --vers "^0.4.37"`
1. mdBook installieren: `cargo install mdbook --vers "^0.4.40"`
2. Live-Vorschau-Server starten: `mdbook serve`
3. http://localhost:3000/ im Browser öffnen

Expand Down
Binary file modified images/trpl04-05.odg
Binary file not shown.
Binary file modified images/trpl04-06.odg
Binary file not shown.
Binary file added images/trpl04-07.odg
Binary file not shown.
3 changes: 1 addition & 2 deletions src/appendix-06-translation.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ eine neue Übersetzung zu informieren!
- [Português (PT)](https://github.com/nunojesus/rust-book-pt-pt)
- [简体中文](https://github.com/KaiserY/trpl-zh-cn)
- [正體中文](https://github.com/rust-tw/book-tw)
- [Українська](https://github.com/pavloslav/rust-book-uk-ua)
- [Українська](https://rust-lang-ua.github.io/rustbook_ukrainian)
- [Español](https://github.com/thecodix/book), [Español](https://github.com/ManRR/rust-book-es)
- [Italiano](https://github.com/EmanueleGurini/book_it)
- [Русский](https://github.com/rust-lang-ru/book)
- [한국어](https://github.com/rinthel/rust-lang-book-ko)
- [日本語](https://github.com/rust-lang-ja/book-ja)
Expand Down
3 changes: 2 additions & 1 deletion src/ch01-03-hello-cargo.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ organisieren. Es gibt einen Platz für alles und alles ist an seinem Platz.
Wenn du ein Projekt begonnen hast, das Cargo nicht verwendet, wie wir es mit
dem Projekt „Hallo Welt!“ getan haben, kannst du es in ein Projekt umwandeln,
das Cargo verwendet. Verschiebe den Projektcode in das Verzeichnis *src* und
erstelle eine entsprechende *Cargo.toml*-Datei.
erstelle eine entsprechende *Cargo.toml*-Datei. Eine einfache Möglichkeit, die
Datei *Cargo.toml* zu erstellen, besteht darin, `cargo init` auszuführen.

### Bauen und Ausführen eines Cargo-Projekts

Expand Down
4 changes: 2 additions & 2 deletions src/ch02-00-guessing-game-tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -1043,8 +1043,8 @@ erneut auszuführen. Beachte, dass es ein neues Problem gibt, weil das Programm
genau das tut, was wir ihm gesagt haben: Frage für immer nach einer weiteren
Schätzung! Es sieht nicht so aus, als könne der Benutzer das Programm beenden!

Der Benutzer könnte das Programm jederzeit mit dem Tastaturkürzel <span
class="keystroke">Strg+c</span> unterbrechen. Aber es gibt noch eine andere
Der Benutzer könnte das Programm jederzeit mit dem Tastaturkürzel
<kbd>Strg</kbd>+<kbd>c</kbd> unterbrechen. Aber es gibt noch eine andere
Möglichkeit, diesem unersättlichen Monster zu entkommen, wie in der
`parse`-Diskussion in [„Vergleichen der Schätzung mit der
Geheimzahl“](#vergleichen-der-schätzung-mit-der-geheimzahl) erwähnt: Wenn der
Expand Down
18 changes: 7 additions & 11 deletions src/ch03-01-variables-and-mutability.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@ error[E0384]: cannot assign twice to immutable variable `x`
--> src/main.rs:4:5
|
2 | let x = 5;
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
3 | println!("Der Wert von x ist: {}", x);
| - first assignment to `x`
3 | println!("Der Wert von x ist: {x}");
4 | x = 6;
| ^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
2 | let mut x = 5;
| +++

For more information about this error, try `rustc --explain E0384`.
error: could not compile `variables` (bin "variables") due to 1 previous error
Expand Down Expand Up @@ -257,12 +259,6 @@ error[E0308]: mismatched types
| ----- expected due to this value
3 | spaces = spaces.len();
| ^^^^^^^^^^^^ expected `&str`, found `usize`
|
help: try removing the method call
|
3 - spaces = spaces.len();
3 + spaces = spaces;
|

For more information about this error, try `rustc --explain E0308`.
error: could not compile `variables` (bin "variables") due to 1 previous error
Expand Down
19 changes: 10 additions & 9 deletions src/ch03-02-data-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,15 +355,16 @@ fn main() {
```

Arrays sind nützlich, wenn du deine Daten eher auf dem Stapelspeicher als im
Haldenspeicher abgelegt haben möchtest (auf den Stapelspeicher und den
Haldenspeicher gehen wir in [Kapitel 4][stack-and-heap] näher ein) oder wenn du
sicherstellen willst, dass du immer eine feste Anzahl von Elementen hast. Ein
Array ist jedoch nicht so flexibel wie der Vektortyp. Ein *Vektor* ist ein
ähnlicher Kollektionstyp, der von der Standardbibliothek zur Verfügung gestellt
wird und der in seiner Größe wachsen oder schrumpfen kann. Wenn du dir nicht
sicher bist, ob du ein Array oder einen Vektor verwenden sollst, ist es
wahrscheinlich, dass du einen Vektor verwenden solltest. In [Kapitel
8][vectors] werden Vektoren ausführlicher besprochen.
Haldenspeicher abgelegt haben möchtest, wie bei den anderen Typen, die wir
bisher gesehen haben, (auf den Stapelspeicher und den Haldenspeicher gehen wir
in [Kapitel 4][stack-and-heap] näher ein) oder wenn du sicherstellen willst,
dass du immer eine feste Anzahl von Elementen hast. Ein Array ist jedoch nicht
so flexibel wie der Vektortyp. Ein *Vektor* ist ein ähnlicher Kollektionstyp,
der von der Standardbibliothek zur Verfügung gestellt wird und der in seiner
Größe wachsen oder schrumpfen kann. Wenn du dir nicht sicher bist, ob du ein
Array oder einen Vektor verwenden sollst, ist es wahrscheinlich, dass du einen
Vektor verwenden solltest. In [Kapitel 8][vectors] werden Vektoren
ausführlicher besprochen.

Arrays sind jedoch hilfreicher, wenn du weißt, dass sich die Anzahl der
Elemente nicht ändern wird. Wenn du z.B. die Monatsnamen in einem Programm
Expand Down
3 changes: 2 additions & 1 deletion src/ch03-03-how-functions-work.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ fn main() {
Anweisung enthält</span>

Auch Funktionsdefinitionen sind Anweisungen; das gesamte vorhergehende Beispiel
ist eine Anweisung für sich.
ist eine Anweisung für sich. (Wie wir weiter unten sehen werden, ist der
*Aufruf* einer Funktion keine Anweisung.)

Anweisungen geben keine Werte zurück. Daher kannst du keine `let`-Anweisung
einer anderen Variablen zuweisen, wie es der folgende Code versucht; du wirst
Expand Down
14 changes: 7 additions & 7 deletions src/ch03-05-control-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,9 @@ fn main() {

Wenn wir dieses Programm ausführen, werden wir sehen, dass es immer und immer
wieder `nochmal!` ausgibt, bis wir das Programm manuell stoppen. Die meisten
Terminals unterstützen das Tastaturkürzel <span
class="keystroke">Strg+c</span>, um ein Programm zu unterbrechen, das in einer
Endlosschleife feststeckt. Probiere es aus:
Terminals unterstützen das Tastaturkürzel <kbd>Strg</kbd>+<kbd>c</kbd>, um ein
Programm zu unterbrechen, das in einer Endlosschleife feststeckt. Probiere es
aus:

```console
$ cargo run
Expand All @@ -313,10 +313,10 @@ nochmal!
^Cnochmal!
```

Das Symbol `^C` steht für die Stelle, an der du <span
class="keystroke">Strg+c</span> gedrückt hast. Je nachdem, wo sich der Code in
der Schleife befand, als er das Unterbrechungssignal empfing, siehst du nach
dem `^C` das Wort `nochmal!` oder nicht.
Das Symbol `^C` steht für die Stelle, an der du <kbd>Strg</kbd>+<kbd>c</kbd>
gedrückt hast. Je nachdem, wo sich der Code in der Schleife befand, als er das
Unterbrechungssignal empfing, siehst du nach dem `^C` das Wort `nochmal!` oder
nicht.

Glücklicherweise bietet Rust auch eine Möglichkeit, aus einer Schleife
mittels Code auszubrechen. Du kannst das Schlüsselwort `break` innerhalb der
Expand Down
71 changes: 53 additions & 18 deletions src/ch04-01-what-is-ownership.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,22 @@ die sich auf eine sehr verbreitete Datenstruktur konzentrieren: Zeichenketten
> Größe oder einer Größe, die sich ändern könnte, müssen stattdessen im
> Haldenspeicher gespeichert werden.
>
> Der Haldenspeicher ist weniger organisiert: Wenn du
> Daten in den Haldenspeicher legst, forderst du eine bestimmte Menge an
> Speicherplatz an. Der Speicher-Allokator (memory allocator) sucht eine leere
> Stelle im Haldenspeicher, die groß genug ist, markiert sie als in
> Benutzung und gibt einen *Zeiger* (pointer) zurück, der die Adresse dieser
> Stelle ist. Dieser Vorgang wird als *Allokieren im Haldenspeicher*
> bezeichnet und manchmal mit *Allokieren* abgekürzt (Das Legen von Werten auf
> den Stapelspeicher gilt nicht als Allokieren). Da es sich beim Zeiger um eine
> bekannte, feste Größe handelt, kannst du den Zeiger auf den Stapelspeicher
> legen, aber wenn du die eigentlichen Daten benötigst, musst du dem Zeiger
> folgen. Stell dir vor, du sitzt in einem Restaurant. Wenn du hineingehst,
> gibst du die Anzahl der Personen deiner Gruppe an, und das Personal findet
> einen leeren Tisch, der groß genug ist, und führt euch dorthin. Wenn jemand
> aus deiner Gruppe zu spät kommt, kann er fragen, wo ihr Platz genommen habt,
> um euch zu finden.
> Der Haldenspeicher ist weniger organisiert: Wenn du Daten in den
> Haldenspeicher legst, forderst du eine bestimmte Menge an Speicherplatz an.
> Der Speicher-Allokator (memory allocator) sucht eine leere Stelle im
> Haldenspeicher, die groß genug ist, markiert sie als in Benutzung und gibt
> einen *Zeiger* (pointer) zurück, der die Adresse dieser Stelle ist. Dieser
> Vorgang wird als *Allokieren im Haldenspeicher* bezeichnet und manchmal mit
> *Allokieren* abgekürzt. (Das Legen von Werten auf den Stapelspeicher gilt
> nicht als Allokieren.) Da es sich beim Zeiger um eine bekannte, feste Größe
> handelt, kannst du den Zeiger auf den Stapelspeicher legen, aber wenn du die
> eigentlichen Daten benötigst, musst du dem Zeiger folgen. Stell dir vor, du
> eigentlichen Daten benötigst, musst du dem Zeiger folgen. Stell dir vor, du
> sitzt in einem Restaurant. Wenn du hineingehst, gibst du die Anzahl der
> Personen deiner Gruppe an, und der Restaurantbesitzer findet einen leeren,
> ausreichend großen Tisch und führt euch dorthin. Wenn jemand aus deiner
> Gruppe zu spät kommt, kann er fragen, wo ihr Platz genommen habt, um euch zu
> finden.
>
> Das Legen auf den Stapelspeicher ist schneller als das Allokieren im
> Haldenspeicher, da der Speicher-Allokator nie nach Platz zum Speichern
Expand Down Expand Up @@ -153,8 +154,8 @@ gültig ist</span>

Mit anderen Worten, es gibt hier zwei wichtige Zeitpunkte:

* Wenn `s` *in den Gültigkeitsbereich* kommt, ist es gültig.
* Es bleibt gültig, bis es *den Gültigkeitsbereich* verlässt.
* Wenn `s` *in den Gültigkeitsbereich kommt*, ist es gültig.
* Es bleibt gültig, bis es *den Gültigkeitsbereich verlässt*.

An diesem Punkt ist die Beziehung zwischen Gültigkeitsbereichen und wann
Variablen gültig sind ähnlich zu anderen Programmiersprachen. Nun werden wir
Expand Down Expand Up @@ -426,7 +427,6 @@ ungültig macht, wird es nicht als flache Kopie, sondern als *Verschieben*
*verschoben* wurde. Was tatsächlich geschieht, ist in Abbildung 4-4
dargestellt.


<img alt="Drei Tabellen: Die Tabellen s1 und s2, die jeweils die Zeichenketten
auf dem Stapelspeicher darstellen und beide auf dieselben Zeichenkettendaten
auf dem Haldenspeicher referenzieren. Die Tabelle s1 ist durchgestrichen, weil
Expand All @@ -446,6 +446,41 @@ Rust wird niemals automatisch „tiefe“ Kopien deiner Daten erstellen. Daher k
man davon ausgehen, dass jedes *automatische* Kopieren im Hinblick auf die
Laufzeitperformanz kostengünstig ist.

#### Gültigkeitsbereich und Zuweisung

Umgekehrt gilt dies auch für die Beziehung zwischen Gültigkeitsbereich,
Eigentümerschaft und Speicherfreigabe durch die Funktion `drop`. Wenn du einer
bestehenden Variablen einen völlig neuen Wert zuweist, ruft Rust die Funktion
`drop` auf und gibt den Speicher des ursprünglichen Wertes sofort frei.
Betrachte zum Beispiel diesen Code:

```rust
# fn main() {
let mut s = String::from("Hallo");
s = String::from("Ahoi");

println!("{s} Welt!");
# }
```

Wir deklarieren zunächst eine Variable `s` und binden sie an einen `String` mit
dem Wert `„Hallo“`. Danach erstellen wir eine neue Zeichenkette mit dem Wert
„Ahoi“ und weisen sie der Variable „s“ zu. Zu diesem Zeitpunkt referenziert
nichts mehr auf den ursprünglichen Wert im Haldenspeicher.

<img alt="Eine Tabelle stellt den Zeichenketten-Wert auf dem Haldenspeicher dar
und zeigt auf den zweiten Teil der Zeichenketten-Daten (Ahoi) auf dem
Haldenspeicher, wobei die ursprünglichen Zeichenketten-Daten (Hallo)
durchgestrichen sind, weil auf sie nicht mehr zugegriffen werden kann."
src="img/trpl04-05.svg" class="center" style="width: 50%;" />

<span class="caption">Figure 4-5: Darstellung im Speicher, nachdem der
ursprüngliche Wert vollständig ersetzt worden ist.</span>

Die ursprüngliche Zeichenkette verlässt damit sofort den Geltungsbereich. Rust
führt die Funktion `drop` aus und ihr Speicher wird sofort freigegeben. Wenn
wir den Wert am Ende ausgeben, lautet er „Ahoi Welt!“.

#### Variablen und Daten im Zusammenspiel mit Clone

Wenn wir die Daten von `String` im Haldenspeicher *tief* kopieren wollen,
Expand Down
19 changes: 13 additions & 6 deletions src/ch04-02-references-and-borrowing.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ Rückgabewert der Funktion verschwunden ist. Beachte des Weiteren, dass wir
`&s1` an `calculate_length` übergeben und in seiner Definition `&String` statt
`String` steht. Das `&`-Zeichen steht für eine *Referenz*, und sie ermöglicht
es dir, sich auf einen Wert zu beziehen, ohne dessen Eigentümerschaft zu
übernehmen. Abbildung 4-5 zeigt die Speicherdarstellung.
übernehmen. Abbildung 4-6 zeigt die Speicherdarstellung.

<img alt="Drei Tabellen: Die Tabelle für s enthält nur einen Zeiger auf die
Tabelle für s1. Die Tabelle für s1 enthält die Stapelspeicher-Daten für s1 und
zeigt auf die Zeichenketten-Daten auf dem Haldenspeicher."
src="img/trpl04-05.svg" class="center" />
src="img/trpl04-06.svg" class="center" />

<span class="caption">Abbildung 4-5: Eine Grafik mit `&String s`, das auf
<span class="caption">Abbildung 4-6: Eine Grafik mit `&String s`, das auf
`String s1` zeigt</span>

> Anmerkung: Das Gegenteil der Referenzierung durch `&` ist die
Expand Down Expand Up @@ -353,7 +353,7 @@ Hier ist die Fehlermeldung:

```console
$ cargo run
Compiling ownership v0.1.0 (file:///projects/ownership)
Compiling playground v0.0.1 (/playground)
error[E0106]: missing lifetime specifier
--> src/main.rs:5:16
|
Expand All @@ -371,8 +371,15 @@ help: instead, you are more likely to want to return an owned value
5 + fn dangle() -> String {
|

For more information about this error, try `rustc --explain E0106`.
error: could not compile `ownership` (bin "ownership") due to 1 previous error
error[E0515]: cannot return reference to local variable `s`
--> src/main.rs:8:5
|
8 | &s
| ^^ returns a reference to data owned by the current function

Some errors have detailed explanations: E0106, E0515.
For more information about an error, try `rustc --explain E0106`.
error: could not compile `playground` (bin "playground") due to 2 previous errors; 1 warning emitted
```

Diese Fehlermeldung bezieht sich auf eine Funktionalität, die wir noch nicht
Expand Down
6 changes: 3 additions & 3 deletions src/ch04-03-slices.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,16 +208,16 @@ was `ending_index` minus `starting_index` entspricht. Im Fall von `let world =
&s[6..10];` wäre `world` also ein Anteilstyp, der einen Zeiger auf das Byte bei
Index 6 von `s` mit dem Längenwert `4` enthält.

Abbildung 4-6 stellt dies dar.
Abbildung 4-7 stellt dies dar.

<img alt="Drei Tabellen: Eine Tabelle, die die Stapelspeicher-Daten von s
darstellt, die auf das Byte bei Index 0 in einer Tabelle der
Zeichenketten-Daten &quot;Hallo Welt&quot; auf dem Haldenspeicher zeigt. Die
dritte Tabelle repräsentiert die Stapelspeicher-Daten des Anteilstypen Welt,
der den Längenwert 4 hat und auf Byte 6 der Haldenspeicher-Datentabelle zeigt."
src="img/trpl04-06.svg" class="center" style="width: 50%;" />
src="img/trpl04-07.svg" class="center" style="width: 50%;" />

<span class="caption">Abbildung 4-6: Zeichenkettenanteilstyp, der sich auf einen
<span class="caption">Abbildung 4-7: Zeichenkettenanteilstyp, der sich auf einen
Teil eines `String` bezieht</span>

Wenn du mit der Bereichssyntax `..` in Rust beim Index 0 beginnen willst,
Expand Down
3 changes: 2 additions & 1 deletion src/ch05-01-defining-structs.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,8 @@ verwendet, wäre `user1` auch nach dem Erstellen von `user2` noch gültig. Die
Typen `active` und `sign_in_count` sind Typen, die das Merkmal `Copy`
implementieren, sodass das Verhalten, das wir im Abschnitt [„Nur
Stapelspeicher-Daten: Kopieren (copy)“][copy] besprochen haben, zutreffen
würde.
würde. Wir können in diesem Beispiel immer noch `user1.email` verwenden, da
sein Wert _nicht_ verschoben wurde.

### Verwenden von Tupel-Strukturen ohne benannte Felder um verschiedene Typen zu erzeugen

Expand Down
4 changes: 2 additions & 2 deletions src/ch05-02-example-structs.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ error[E0277]: `Rectangle` doesn't implement `Debug`
Aber auch hier gibt uns der Compiler einen hilfreichen Hinweis:

```text
= help: the trait `std::fmt::Debug` is not implemented for `Rectangle`
= note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug`
= help: the trait `Debug` is not implemented for `Rectangle`
= note: add `#[derive(Debug)]` to `Rectangle` or manually `impl Debug for Rectangle`
```

Rust enthält durchaus eine Funktionalität zum Ausgeben von Debug-Informationen,
Expand Down
16 changes: 8 additions & 8 deletions src/ch05-03-method-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ fn main() {
height: 45,
};
println!("Umfasst rect1 rect2? {}", rect1.can_hold(&rect2));
println!("Umfasst rect1 rect3? {}", rect1.can_hold(&rect3));
println!("rect1 umfasst rect2? {}", rect1.can_hold(&rect2));
println!("rect1 umfasst rect3? {}", rect1.can_hold(&rect3));
}
```
Expand All @@ -222,8 +222,8 @@ Die erwartete Ausgabe würde wie folgt aussehen, da beide Dimensionen von
`rect1` ist:

```text
Umfasst rect1 rect2? true
Umfasst rect1 rect3? false
rect1 umfasst rect2? true
rect1 umfasst rect3? false
```

Wir wissen, dass wir eine Methode definieren wollen, also wird sie innerhalb
Expand Down Expand Up @@ -273,8 +273,8 @@ impl Rectangle {
# height: 45,
# };
#
# println!("Umfasst rect1 rect2? {}", rect1.can_hold(&rect2));
# println!("Umfasst rect1 rect3? {}", rect1.can_hold(&rect3));
# println!("rect1 umfasst rect2? {}", rect1.can_hold(&rect2));
# println!("rect1 umfasst rect3? {}", rect1.can_hold(&rect3));
# }
```

Expand Down Expand Up @@ -377,8 +377,8 @@ impl Rectangle {
# height: 45,
# };
#
# println!("Umfasst rect1 rect2? {}", rect1.can_hold(&rect2));
# println!("Umfasst rect1 rect3? {}", rect1.can_hold(&rect3));
# println!("rect1 umfasst rect2? {}", rect1.can_hold(&rect2));
# println!("rect1 umfasst rect3? {}", rect1.can_hold(&rect3));
# }
```

Expand Down
Loading

0 comments on commit 12ceb66

Please sign in to comment.