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: nilWenn 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 -- ErlaubtBeachten 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.
Aufgabe
EinfachSchreibe 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 dutype(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 sollvalue(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
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Logik & Programmablauf
1Fortgeschrittene Tabelleniteration
Iterieren mit pairs()Iterieren mit ipairs()pairs() vs. ipairs()Zusammenfassung – Charakterbogen4Einführung in Metatables
Was ist eine Metatable?setmetatable & getmetatableDie __index-MetamethodeDie __newindex-MetamethodeDie __tostring-MetamethodeArithmetische Metamethoden Teil 1Arithmetische Metamethoden Teil 2Rückblick – Read-Only-Tabelle2Weitere Funktionen der Tabellenbibliothek
table.concat()Tabellenkonstruktion & unpack()table.sort()Eigene Sortierung mit FunktionenRückblick – Highscore-TabelleÜbe selbstständig: Online-Lua-Compiler