Skip to content

Modul 4 — Structs & Methoden

Eigene Datentypen bauen: Structs mit Feldern und Ableitungen, Methoden mit impl, das Newtype-Muster — und ein Inventar als Mini-Projekt.

Fortschritt0/4 Lektionen
13

Structs: Daten bündeln

Lektion 13 von 4

Bisher hatten deine Programme lose Variablen. Ein echtes Programm bündelt zusammengehörige Daten: ein Buch hat Titel und Seitenzahl, ein Nutzer Name und E-Mail. Genau dafür sind Structs da — Rusts Version von "Record":

struct Book {
    title: String,
    pages: u32,
}

fn main() {
    let b = Book {
        title: String::from("Der Rust-Weg"),
        pages: 312,
    };
    println!("{} hat {} Seiten", b.title, b.pages);
}

Ein Struct-Literal nennt jedes Feld mit Namen. Vergisst du eines, meckert der Compiler sofort (E0063) — statt zur Laufzeit ein halb initialisiertes Objekt zu erzeugen, wie es in vielen Sprachen möglich wäre.

Kurzschreibweisen und Update-Syntax

struct Book {
    title: String,
    pages: u32,
}

fn main() {
    let title = String::from("Kurze Note");
    let pages = 2;
    let note = Book { title, pages }; // Feld-Init-Kurzschreibweise

    let book = Book {
        pages: 312,
        ..note // REST aus note übernehmen
    };
    println!("{book:?}");
}

Zwei Übliche Werkzeuge: Book { title, pages } nutzt die Variable mit gleichem Namen (Feld-Init-Kurzschreibweise). ..note übernimmt alle übrigen Felder aus einer anderen Instanz.

Debug für println! ({:?})

println!("{b:?}") gibt die ganze Struktur aus — dafür braucht der Typ das Trait Debug. Du hängst einfach #[derive(Debug)] über die Struct-Definition und der Compiler generiert die Ausgabe für dich.

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p = Point { x: 3, y: -2 };
    println!("{p:?}");
}

Achtung: Structs bewegen sich wie Strings

Structs sind Copy-Typen nur, wenn alle Felder Copy sind. Sobald ein String-Feld dabei ist, verschiebt eine Zuweisung den Besitz — und mit der Update-Syntax ..base moved du die non-Copy-Felder aus base heraus ("partial move"). Danach ist base als Ganzes verbraucht.

Übung: das erste Buch

🧩 Übung m4-l1-e1

🔮 Vorhersage: Was passiert beim Ausführen?

Editor wird geladen…
KI-Tutor (sokratisch — keine Komplettlösungen)

✅ Wichtige Erkenntnisse

0/4

Haken setzen, um deinen Lernfortschritt zu markieren:

14

Methoden & impl-Blöcke

Lektion 14 von 4

Daten ohne Verhalten sind nur halb brauchbar. Methoden kommen in einen impl-Block — getrennt von den Daten, aber dem Typ zugeordnet:

struct Counter {
    count: u32,
}

impl Counter {
    fn new() -> Self {
        Counter { count: 0 }
    }

    fn increment(&mut self) {
        self.count += 1;
    }

    fn value(&self) -> u32 {
        self.count
    }
}

fn main() {
    let mut c = Counter::new();
    c.increment();
    c.increment();
    println!("count = {}", c.value());
}

Die drei Empfänger

Der erste Parameter einer Methode entscheidet, was sie mit der Instanz anstellen darf:

EmpfängerBedeutungTypisch für
&selfleiht read-onlyBerechnen, Lesen, Anzeigen
&mut selfleiht veränderlichZustand ändern wie increment
selfübernimmt BesitzVerbrauchende Umwandlungen, Builder

Counter::new hat gar kein self — es ist eine assoziierte Funktion (der Konstruktor-Klassiker), aufgerufen mit Counter::new(). Self ist die Abkürzung für den Typ selbst.

let c = Counter::new();
c

c besitzt den Counter — der Wert lebt auf dem Stack.

Schritt 1 von 4

Wann welcher Empfänger?

Default-Frage: Braucht die Methode den Besitz? Nein → &self (lesen) oder &mut self (ändern). self nur, wenn der Aufrufer den Wert danach bewusst nicht mehr braucht — der Compiler erzwingt das für beide Seiten.

Rust hat keinen versteckten this-Zeiger: Die Methode bekommt die Instanz explizit als ersten Parameter. Methodenaufrufe mit Punkt-Syntax (c.increment()) dereferenzieren automatisch — egal ob c, &mut c oder ein Box-Smartpointer dahintersteckt.

Methoden-WerkstattBereit
Editor wird geladen…

Übung: der Zähler

🧩 Übung m4-l2-e1

🔮 Vorhersage: Was passiert beim Ausführen?

Editor wird geladen…
KI-Tutor (sokratisch — keine Komplettlösungen)

✅ Wichtige Erkenntnisse

0/4

Haken setzen, um deinen Lernfortschritt zu markieren:

15

Tuple-Structs & das Newtype-Muster

Lektion 15 von 4

Manchmal brauchen Felder keine Namen — die Reihenfolge reicht:

struct Meters(u32);
struct Seconds(u32);

fn main() {
    let dist = Meters(120);
    println!("{} Meter", dist.0); // Zugriff per Index
}

Das ist eine Tuple-Struct: Meters(120) sieht aus wie ein Funktionsaufruf und speichert einen u32 — aber als eigenen Typ.

Newtype: Null Kosten, volle Sicherheit

Meters und Seconds verhalten sich exakt wie u32 im Speicher (gleiche Größe, gleiche Geschwindigkeit). Trotzdem kann der Compiler sie nicht verwechseln:

struct Meters(u32);
struct Seconds(u32);

impl Meters {
    fn add(self, other: Meters) -> Meters {
        Meters(self.0 + other.0)
    }
}

fn main() {
    let a = Meters(120);
    let b = Meters(80);
    println!("{} m", a.add(b).0);
    // a.add(Seconds(5)); // ❌ expected `Meters`, found `Seconds`
}

Dieses Muster heißt Newtype und ist in echtem Rust allgegenwärtig: IDs, Einheiten, Versionen — alles bekommt einen eigenen Typ, und „Vertauscher“-Bugs werden zu Compile-Fehlern. Mars Climate Orbiter lässt grüßen.

Unit-Structs: Typen ohne Daten

struct WIP;

fn main() {
    let _state = WIP;
}

Ein Unit-Struct hat gar keine Felder. Er dient als Markierung: Der Typ SELBST trägt die Information („hier ist noch nichts drin“), ohne ein Byte Daten zu kosten. Später im Kurs sehen wir ihn in State-Maschinen wieder.

Übung: Meters zusammenzählen

🧩 Übung m4-l3-e1

🔮 Vorhersage: Was passiert beim Ausführen?

Editor wird geladen…
KI-Tutor (sokratisch — keine Komplettlösungen)

✅ Wichtige Erkenntnisse

0/4

Haken setzen, um deinen Lernfortschritt zu markieren:

16

Mini-Projekt: Inventar

Lektion 16 von 4

Zeit, alles zusammenzubringen: ein Inventar aus Items mit Mengen — Structs, Vec, Methoden, associated function. Erst das Szenario aus dem Arbeitsleben:

Praxis-Szenario: Die Lagerverwaltung

Dein Team pflegt Bestände in einer Excel-Liste: zweimal derselbe Artikel, Tippfehler in den Namen, Summen per Hand. Bei der Inventur stimmt nichts. Du schlägst vor, die Domäne als Typen zu modellieren: Item mit Name und Menge, Inventory als Verwaltung mit Methoden — falsche Summen werden strukturell unmöglich.

Das Gerüst hast du teilweise schon aus Lektion 14. Die Übung lässt dich den letzten Teil selbst bauen — mit dem XP-Lohn fürs lösen ohne Hilfe:

🧩 Übung m4-l4-e1

🔮 Vorhersage: Was passiert beim Ausführen?

Editor wird geladen…
KI-Tutor (sokratisch — keine Komplettlösungen)

Was du in Modul 4 geschafft hast

  • Structs bündeln Daten mit benannten Feldern und initialisieren vollständig
  • impl-Blöcke trennen Verhalten von Daten; Empfänger wählen die Rechte
  • Newtypes machen Einheiten zur Compile-Zeit-Sache
  • Ein kleines Domänenmodell (Item + Inventory) steht und ist erweiterbar

✅ Wichtige Erkenntnisse

0/3

Haken setzen, um deinen Lernfortschritt zu markieren:

Modul-Checkpoint

Checkpoint: Modul 4

Bestehensgrenze: 80 %. Der Versuch wird bewertet und zählt für das Modul-Gate.

This site uses essential cookies for Stripe payments. No tracking cookies.