Menu
Coddy logo textTech

Die __newindex-Metamethode

Teil des Abschnitts Logik & Programmablauf der Lua-Journey von Coddy. Lektion 19 von 54.

Sie haben gelernt, wie __index steuert, was passiert, wenn Sie versuchen, einen Schlüssel zu lesen, der in einer Tabelle nicht existiert. Jetzt werden Sie sein Gegenstück entdecken: __newindex, das steuert, was passiert, wenn Sie versuchen, ein Schlüssel-Wert-Paar hinzuzufügen oder zu ändern.

Die __newindex-Metamethode wird immer dann ausgelöst, wenn Sie versuchen, einem Schlüssel einen Wert zuzuweisen, der derzeit nicht in der Tabelle existiert. Dies gibt Ihnen die Möglichkeit, Änderungen abzufangen und zu steuern, bevor sie stattfinden.

Hier ist ein einfaches Beispiel, das verhindert, dass neue Schlüssel zu einer Tabelle hinzugefügt werden:

local readOnly = {}
local meta = {
    __newindex = function(table, key, value)
        print("Cannot add key: " .. key)
    end
}

setmetatable(readOnly, meta)

readOnly.name = "Alice"  -- Ausgabe: Cannot add key: name
print(readOnly.name)     -- Ausgabe: nil

Wenn Sie versuchen, readOnly.name = "Alice" zu setzen, sieht Lua, dass name in der Tabelle nicht existiert. Anstatt es hinzuzufügen, ruft Lua die __newindex-Funktion mit drei Argumenten auf: die Tabelle selbst, der zu setzende Schlüssel und der zugewiesene Wert.

In diesem Beispiel gibt die Funktion einfach eine Nachricht aus und speichert eigentlich nichts.

Du kannst auch __newindex verwenden, um Daten zu validieren, bevor sie in deine Tabelle aufgenommen werden:

local player = {}
local meta = {
    __newindex = function(t, key, value)
        if key == "health" and type(value) ~= "number" then
            print("Health must be a number!")
        else
            rawset(t, key, value)
        end
    end
}

setmetatable(player, meta)

player.health = "high"  -- Ausgabe: Health must be a number!
player.health = 100     -- Erlaubt

Beachten Sie die Verwendung von rawset() im zweiten Beispiel. Diese Funktion umgeht die Metatabelle und setzt den Wert direkt in der Tabelle.

Ohne dies würde das Setzen des Wertes __newindex erneut auslösen und so eine Endlosschleife erzeugen.

challenge icon

Aufgabe

Einfach
Schreibe eine Funktion createValidatedTable, die key und value entgegennimmt und eine Tabelle zurückgibt, die für neue Schlüssel nur Zeichenfolgenwerte akzeptiert.

Erstelle eine leere Tabelle und verknüpfe sie mit einer Metatabelle mit __newindex, die den Werttyp überprüft. Wenn jemand versucht, einen Wert hinzuzufügen, der keine Zeichenfolge ist, verwende rawset(), um stattdessen die Zeichenfolge "invalid" zu speichern. Zeichenfolgenwerte werden normal mit rawset() gespeichert.

Logik:

  • Erstelle eine leere Tabelle
  • Erstelle eine Metatabelle mit __newindex, die die Tabelle, den Schlüssel und den Wert entgegennimmt
  • Überprüfe innerhalb von __newindex, ob der Wert eine Zeichenfolge ist, indem du type(value) == "string" verwendest
  • Wenn es eine Zeichenfolge ist, verwende rawset(t, key, value), um sie zu speichern
  • Wenn es keine Zeichenfolge ist, verwende rawset(t, key, "invalid"), um stattdessen "invalid" zu speichern
  • Verknüpfe die Metatabelle mithilfe von setmetatable() mit der Tabelle
  • Verwende rawset(), um das anfängliche Schlüssel-Wert-Paar zur Tabelle hinzuzufügen, wobei die Metatabelle umgangen wird
  • Gib die Tabelle zurück

Parameter:

  • key (Zeichenfolge): Der anfängliche Schlüssel, der zur Tabelle hinzugefügt werden soll
  • value (Zeichenfolge): Der anfängliche Wert, der zur Tabelle hinzugefügt werden soll

Rückgabe: Eine Tabelle mit Validierung, die nur Zeichenfolgenwerte akzeptiert und das anfängliche Schlüssel-Wert-Paar enthält (Tabelle)

Probier es selbst

function createValidatedTable(key, value)
    -- Code hier schreiben
end
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Logik & Programmablauf

Übe selbstständig: Online-Lua-Compiler