Kiste
EN

Listen und Karten

9.1 Listen — die Grundlagen

nimm zahlen = [10, 20, 30, 40, 50]

sag zahlen[0]    // 10 (erstes Element)
sag zahlen[2]    // 30
sag länge(zahlen) // 5

9.1.5 Wenn der Index daneben liegt — sicherer Zugriff

Ein Zugriff außerhalb der Liste ist ein Laufzeitfehler und beendet das Programm:

nimm zahlen = [10, 20, 30]
sag zahlen[99]   // Index 99 außerhalb der Liste der Länge 3

Es gibt drei richtige Reaktionen — welche, hängt davon ab, warum der Index falsch sein kann:

1. Erwartbarer Fall (User-Eingabe, Suche, Datei-Zeilen — „kann legitim danebengehen"): prüfe vorher mit einem Wächter und gib nichts zurück. Der Aufrufer entscheidet den Default mit ?? (§15):

funktion hole_eintrag(daten, index) {
    wenn index < 0 oder index >= länge(daten) {
        gib nichts
    }
    gib daten[index]
}

nimm zahlen = [10, 20, 30]
sag hole_eintrag(zahlen, 1) ?? -1     // 20
sag hole_eintrag(zahlen, 99) ?? -1    // -1 statt Crash

Merke: Die Funktion meldet (nichts = „da ist nichts" — ehrlicher als ein erfundener Wert wie 0, der ja ein echter Eintrag sein könnte), der Aufrufer entscheidet (?? Default, oder wenn … == nichts mit eigener Reaktion).

2. Vorab-Prüfen unpraktisch (der Index kommt tief aus fremden Daten): versuche/fange um den Zugriff — Details in §11.3.

3. Programmierfehler (der Index kann eigentlich nie falsch sein): dann ist der Crash die richtige Reaktion! Er zeigt dir per Stacktrace (§11.3.5) sofort, wo dein Denkfehler liegt — ein stiller Default würde stattdessen mit falschen Werten weiterrechnen. In der Kiste-IDE klickst du die Fehlerzeile an und springst direkt zur Stelle.

Nicht übertreiben: Pack nicht jeden Listenzugriff in Wächter. Eine Schleife für i = 0 bis länge(xs) - 1 hat konstruktionsbedingt gültige Indizes — ein Wächter dort ist nur Rauschen, das den echten Schutz unsichtbar macht.

9.2 Listen verändern

Kiste-Listen sind veränderlich — du kannst Elemente anhängen, entfernen oder ersetzen. Die Funktionen sind eingebaut (kein nutze nötig):

nimm liste = [1, 2, 3]

füge_hinzu(liste, 4)        // liste ist jetzt [1, 2, 3, 4]
entferne_letztes(liste)     // liste ist jetzt [1, 2, 3], gibt den entfernten Wert zurück
liste[0] = 99               // liste ist jetzt [99, 2, 3]

Funktions-Stil statt Methoden-Stil: in Kiste rufst du füge_hinzu(liste, 4) auf — NICHT liste.füge_hinzu(4). Die Punkt-Notation ist Klassen vorbehalten (siehe §13). Listen sind eingebaute Werte und werden mit eingebauten Funktionen verändert.

Weitere Listen-Funktionen findest du im liste-Modul (§18) — sortieren, filtern, kombinieren etc.

9.3 Listen durchgehen

nimm zahlen = [10, 20, 30]
nimm summe = 0

wiederhole zahl in zahlen {
    summe += zahl
}

sag "Summe: " + summe   // "Summe: 60"

9.4 Karten (Dictionaries)

nimm konto = {
    "inhaber": "Sascha",
    "saldo": 1500.50,
    "aktiv": wahr
}

sag konto["inhaber"]   // "Sascha"
konto["saldo"] = 2000.00

Bracket-Notation für Karten, Punkt-Notation für Klassen: bei Karten greifst du IMMER mit karte["schlüssel"] zu. Punkt-Notation (konto.inhaber) ist nur für Klassen-Felder (siehe §13). Wenn du strukturierte Daten mit Punkt-Zugriff willst, definiere eine Klasse.

9.5 Destructuring — mehrere Werte auf einmal entpacken

Manchmal willst du mehrere Werte aus einer Liste oder Karte gleichzeitig in eigene Variablen packen. Dafür gibt's Destructuring:

// Liste destrukturieren
nimm [x, y, z] = [10, 20, 30]
// x = 10, y = 20, z = 30

// Karte destrukturieren
nimm person = {"name": "Sascha", "alter": 38}
nimm {name, alter} = person
// name = "Sascha", alter = 38

Mit Rest-Operator ...

Wenn du das erste holen und den Rest als Liste behalten willst:

nimm [erste, ...rest] = [1, 2, 3, 4]
// erste = 1, rest = [2, 3, 4]

Was passiert bei fehlenden Werten?

Situation Ergebnis
Liste hat zu wenig Elemente fehlende Variablen werden nichts
Karte hat einen Schlüssel nicht die Variable wird nichts
Wert ist gar keine Liste/Karte Laufzeit-Fehler
nimm [a, b, c] = [1, 2]              // c = nichts
nimm {name, beruf} = {"name": "S"}   // beruf = nichts

Im Funktionskopf

Karten-Destructuring direkt im Funktionsparameter — sehr praktisch, weil der Funktionskopf zeigt, was gebraucht wird:

funktion zeichne_punkt({x, y, farbe}) {
    sag "Punkt bei {x},{y} in {farbe}"
}

zeichne_punkt({"x": 10, "y": 20, "farbe": "rot"})
// "Punkt bei 10,20 in rot"

Was Kiste (noch) NICHT kann

Diese Formen sind in v1 nicht erlaubt — der Parser sagt klar Bescheid:

nimm {name: n} = person                  // Umbenennen kommt später
nimm {name, alter = 0} = person          // Standardwerte kommen später
nimm {adresse: {strasse}} = person       // Verschachteln kommt später
funktion f([a, b]) { }                   // Listen-Pattern in Param: nutze 2 Parameter

Mehr Details und Edge-Cases in docs/destructuring.md.