0Pricing
Lua Academy · Lektion

Einführung in Metatabellen

Setzen und lesen Sie Metatabellen mit setmetatable/getmetatable

Einführung in Metatabellen ist eine kostenlose Lua Academy-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Lua Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Lua Academy-Kurs umfasst insgesamt 4 Lektionen.

Was ist eine Metatabelle?

Eine Metatabelle ist eine gewöhnliche Lua-Tabelle, die das Verhalten einer anderen Tabelle steuert. Wenn Lua auf eine Operation trifft, die es für eine Tabelle nicht ausführen kann (etwa eine arithmetische Operation oder den Zugriff auf einen nicht vorhandenen Schlüssel), sucht es in der Metatabelle nach einer entsprechenden Metamethode. Dies ist L uas Erweiterungsmechanismus für Operatorüberladung und OOP.

local t = {}
local mt = {__index = function(_, k) return "default_" .. k end}

setmetatable(t, mt)

print(t.foo)    -- default_foo
print(t.bar)    -- default_bar
print(t[1])     -- default_1

setmetatable und getmetatable

setmetatable(t, mt) legt die Metatabelle von t auf mt fest und gibt t zurück. getmetatable(t) gibt die Metatabelle zurück oder nil, wenn keine vorhanden ist. Sie können eine Metatabelle vor Änderungen schützen, indem Sie mt.__metatable = "protected" setzen.

local t = {x = 10}
local mt = {}

setmetatable(t, mt)
print(getmetatable(t) == mt)   -- true

-- Protect metatable
mt.__metatable = "locked"
print(getmetatable(t))   -- locked
-- setmetatable(t, {})  -- ERROR: cannot change protected metatable

__index als Tabelle

Wenn __index eine Tabelle ist, sucht Lua den fehlenden Schlüssel in dieser Tabelle. Dies bildet die Grundlage der prototypbasierten Vererbung in Lua. Ist der Schlüssel auch in __index nicht vorhanden, prüft Lua die Metatabelle dieser Tabelle und setzt die Suche entlang der Kette fort.

local Animal = {sound = "...", legs = 4}

local Dog = setmetatable({sound = "Woof"}, {__index = Animal})
local Cat = setmetatable({sound = "Meow"}, {__index = Animal})

print(Dog.sound)   -- Woof (own field)
print(Dog.legs)    -- 4 (from Animal)
print(Cat.sound)   -- Meow
print(Cat.legs)    -- 4

__index als Funktion

Wenn __index eine Funktion ist, ruft Lua sie mit der Tabelle und dem fehlenden Schlüssel auf. Die Funktion kann den Wert dynamisch berechnen oder abrufen. Geben Sie aus __index nil zurück, um „Schlüssel nicht gefunden“ anzuzeigen.

local dynamic = setmetatable({}, {
  __index = function(t, k)
    if k:sub(1,4) == "get_" then
      local field = k:sub(5)
      return function(self) return self[field] end
    end
    return nil
  end
})

dynamic.name = "Lua"
local getter = dynamic.get_name
print(getter(dynamic))   -- Lua

rawget und rawset

rawget(t, k) liest einen Tabellenschlüssel, ohne __index auszulösen. rawset(t, k, v) setzt einen Schlüssel, ohne __newindex auszulösen. Verwenden Sie diese Funktionen, um Metamethoden zu umgehen, wenn Sie innerhalb einer Metamethode direkt auf eine Tabelle zugreifen müssen, damit keine Endlosrekursion entsteht.

local logged = setmetatable({}, {
  __newindex = function(t, k, v)
    print("Setting", k, "=", v)
    rawset(t, k, v)  -- bypass __newindex
  end
})

logged.x = 10   -- Setting x = 10
logged.x = 20   -- no log! key now exists in t
print(logged.x) -- 20

Mehrere Tabellen mit einer gemeinsamen Metatabelle

Eine einzelne Metatabelle kann von vielen Tabellen gemeinsam verwendet werden. So funktionieren Klassensysteme in Lua: Alle Instanzen einer Klasse verwenden dieselbe Metatabelle, die die Methoden enthält. Änderungen an der Metatabelle wirken sich auf alle Instanzen aus.

local Mt = {
  __index = {
    greet = function(self)
      print("Hello from " .. (self.name or "?"))
    end
  }
}

local a = setmetatable({name="Alice"}, Mt)
local b = setmetatable({name="Bob"},   Mt)

a:greet()   -- Hello from Alice
b:greet()   -- Hello from Bob

__metatable-Feld

Wenn Sie mt.__metatable auf einen beliebigen Wert setzen, gibt getmetatable diesen Wert anstelle der tatsächlichen Metatabelle zurück. Dadurch wird verhindert, dass Benutzer die Metatabelle untersuchen oder ersetzen können – nützlich für Kapselung und Sicherheit.

local secret = setmetatable({}, {
  __metatable = false,    -- hide metatable
  __index = {value = 42}
})

print(secret.value)        -- 42
print(getmetatable(secret)) -- false (not the real mt)
-- setmetatable(secret, {}) -- ERROR

Auf eine Metatabelle prüfen

Verwenden Sie getmetatable(t), um zu prüfen, ob ein Objekt eine bestimmte Metatabelle besitzt (zur Typprüfung). Da __metatable die tatsächliche Metatabelle verbergen kann, sollten Sie für zuverlässige isinstance-Prüfungen rawequal oder ein Markierungsfeld verwenden.

local MyClass = {}
MyClass.__index = MyClass
MyClass.__metatable = MyClass   -- use self as marker

function MyClass.new(x)
  return setmetatable({x=x}, MyClass)
end

local obj = MyClass.new(5)
print(getmetatable(obj) == MyClass)   -- true
print(obj.x)                           -- 5

Metatabellen für Nicht-Tabellen

Strings besitzen in Lua bereits eine Metatabelle (das string-Modul). Deshalb können Sie für jeden String s:upper() aufrufen. In reinem Lua können Sie Metatabellen nicht auf Strings, Zahlen oder boolesche Werte setzen – nur auf Tabellen und userdata.

local s = "hello"
local mt = getmetatable(s)

-- String metatable has __index = string library
print(mt.__index == string)   -- true

-- So all string functions are methods:
print(s:upper())              -- HELLO
print(s:rep(3, "-"))          -- hello-hello-hello

Debugging mit Metatabellen

Sie können eine Metamethode __tostring hinzufügen, um zu steuern, wie tostring() und print() eine Tabelle anzeigen. Das ist für das Debugging komplexer Objekte äußerst nützlich.

local Point = {}
Point.__index = Point
Point.__tostring = function(p)
  return string.format("Point(%g, %g)", p.x, p.y)
end

function Point.new(x, y)
  return setmetatable({x=x,y=y}, Point)
end

local p = Point.new(3, 4)
print(tostring(p))   -- Point(3, 4)
print(p)             -- Point(3, 4)  (print calls tostring)

Schnelltest

Was passiert, wenn Sie auf einen Schlüssel zugreifen, der in einer Tabelle mit einer Metatabelle nicht gefunden wird, deren __index auf eine andere Tabelle gesetzt ist?

Zusammenfassung: Metatabellen

Zusammenfassung:

  • setmetatable(t, mt) / getmetatable(t)
  • __index: Tabelle → Suche im Prototyp; Funktion → dynamische Weiterleitung
  • rawget/rawset umgehen Metamethoden
  • Gemeinsam verwendete Metatabellen ermöglichen klassenähnliches Verhalten
  • __metatable schützt die Metatabelle vor Untersuchungen
  • __tostring steuert die Ausgabe von print

Häufig gestellte Fragen

Ist die Lektion „Einführung in Metatabellen“ kostenlos?

Ja — der vollständige Text von „Einführung in Metatabellen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Lua Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Lua Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Einführung in Metatabellen“?

Setzen und lesen Sie Metatabellen mit setmetatable/getmetatable Du übst Lua Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Lua Academy zu starten?

Keine Vorkenntnisse erforderlich. Lua Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.

Wie lange dauert die Lektion „Einführung in Metatabellen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Lua Academy-Lektion Code schreiben und ausführen?

Ja. Jede Lua Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Einführung in Metatabellen
  2. __index und __newindex
  3. Arithmetische Metamethoden
  4. __tostring und __len
← Zurück zu Lua Academy