Skip to content
Zurück zu den Lernmaterialien

Modul 4 — Structs & Methoden

6. September 2026~3 min read
Lektion von 0/ abgeschlossen
Modul 4 — Structs & Methoden

Structs: Daten bündeln

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.

📝 Schnellprüfung

Was gibt dieses Programm aus?

Ü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

Haken setzen, um deinen Lernfortschritt zu markieren:

    Lektion von 0/ abgeschlossen
    Modul 4 — Structs & Methoden

    Methoden & impl-Blöcke

    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.

    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.

    📝 Schnellprüfung

    Wie erstellst du einen neuen Counter ohne bestehende Instanz?

    Ü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

    Haken setzen, um deinen Lernfortschritt zu markieren:

      Lektion von 0/ abgeschlossen
      Modul 4 — Structs & Methoden

      Tuple-Structs & das Newtype-Muster

      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.

      📝 Schnellprüfung

      Warum ist `a.add(Seconds(5))` ein Compile-Fehler, obwohl beide u32 sind?

      Ü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

      Haken setzen, um deinen Lernfortschritt zu markieren:

        Lektion von 0/ abgeschlossen
        Modul 4 — Structs & Methoden

        Mini-Projekt: Inventar

        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

        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.

          Bereit, dein Wissen zu testen?

          Probiere unsere Übungsprüfungen mit Hunderten von realistischen Fragen aus.

          Üben starten →

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