__tostring und __len
Steuern Sie die Zeichenkettendarstellung und den #-Operator über Metamethoden
__tostring und __len ist eine kostenlose Lua Academy-Lektion auf CoddyKit. Dies ist Lektion 4 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.
__tostring-Metamethode
__tostring wird aufgerufen, wenn tostring(obj) aufgerufen wird, und auch von print() (das für jedes Argument tostring aufruft). Definieren Sie die Metamethode, um eine gut lesbare Darstellung Ihrer benutzerdefinierten Objekte bereitzustellen.
local Point = {}
Point.__index = Point
Point.__tostring = function(p)
return string.format("Point(%.2f, %.2f)", p.x, p.y)
end
function Point.new(x,y)
return setmetatable({x=x,y=y}, Point)
end
local p = Point.new(3.14, 2.72)
print(p) -- Point(3.14, 2.72)
print(tostring(p)) -- Point(3.14, 2.72)__len für Sequenzen
__len wird aufgerufen, wenn der Operator # auf eine Tabelle mit dieser Metamethode angewendet wird. In Lua 5.2+ wird __len für Tabellen immer aufgerufen; in 5.1 nur für userdata. Verwenden Sie die Metamethode, um die „Länge“ benutzerdefinierter Container zu definieren.
local Queue = {}
Queue.__index = Queue
Queue.__len = function(q) return q._tail - q._head + 1 end
function Queue.new()
return setmetatable({_data={},_head=1,_tail=0}, Queue)
end
function Queue:push(v)
self._tail = self._tail + 1
self._data[self._tail] = v
end
function Queue:pop()
if self._head > self._tail then return nil end
local v = self._data[self._head]
self._head = self._head + 1
return v
end
local q = Queue.new()
q:push("a"); q:push("b"); q:push("c")
print(#q) -- 3Aussagekräftiges __tostring für Debugging
Ein gutes __tostring enthält den Typnamen und wichtige Schlüssel. Bei verschachtelten Objekten rufen Sie tostring rekursiv auf. Dadurch wird das Debugging deutlich einfacher als mit der standardmäßigen Ausgabe "table: 0x...".
local function tableToString(t, depth)
depth = depth or 0
if depth > 3 then return "{...}" end
local parts = {}
for k, v in pairs(t) do
if type(v) == "table" then
parts[#parts+1] = k.."="..tableToString(v, depth+1)
else
parts[#parts+1] = k.."="..tostring(v)
end
end
return "{"..table.concat(parts,", ").."}"
end
local obj = {name="test", data={x=1,y=2}, active=true}
print(tableToString(obj))__len im Vergleich zum #-Operator
Bei Tabellen ohne eine __len-Metamethode sucht #t eine beliebige Grenze der Sequenz (bei der t[i] ~= nil und t[i+1] == nil gilt). Bei Lücken in der Tabelle ist das Ergebnis unvorhersehbar. Mit __len können Sie eine verbindliche, konsistente Länge definieren.
-- Table with hole: # is unpredictable
local t = {10, 20, nil, 40}
print(#t) -- could be 2 or 4, undefined!
-- Custom container with authoritative length
local SafeList = {}
SafeList.__index = SafeList
SafeList.__len = function(s) return s._size end
function SafeList.new()
return setmetatable({_data={}, _size=0}, SafeList)
end
function SafeList:add(v)
self._size = self._size + 1
self._data[self._size] = v
end
local s = SafeList.new()
s:add(1); s:add(nil); s:add(3)
print(#s) -- 3 (always correct)__tostring in Fehlermeldungen
Wenn Sie Fehlerobjekte verwenden (Tabellen anstelle von Strings), werden Fehlermeldungen durch die Definition von __tostring lesbar, wenn der Fehler weitergereicht und in einen String umgewandelt wird.
local function makeError(code, msg)
return setmetatable(
{code=code, message=msg},
{__tostring = function(e)
return string.format("Error[%d]: %s", e.code, e.message)
end}
)
end
local ok, err = pcall(function()
error(makeError(404, "resource not found"))
end)
if not ok then
-- err is the error object (table)
print(tostring(err)) -- may show table address...__tostring mit Vererbung
Wenn Sie objektorientierte Programmierung auf Prototypbasis verwenden, definieren Sie __tostring in der Klassenmetatabelle. Alle Instanzen verwenden automatisch das __tostring der Klasse, da die Metatabelle der Instanz DIE Klassentabelle ist.
local Animal = {}
Animal.__index = Animal
Animal.__tostring = function(a)
return string.format("%s(%s)", a._type or "Animal", a.name or "?")
end
function Animal.new(name, atype)
return setmetatable({name=name, _type=atype}, Animal)
end
local cat = Animal.new("Whiskers", "Cat")
local dog = Animal.new("Rex", "Dog")
print(cat) -- Cat(Whiskers)
print(dog) -- Dog(Rex)Eine Menge mit __len und __tostring implementieren
Kombinieren Sie __len und __tostring in einem Typ, um eine vollständige, benutzerfreundliche Implementierung einer Menge zu erstellen.
local Set = {}
Set.__index = Set
Set.__len = function(s) return s._size end
Set.__tostring = function(s)
local items = {}
for k in pairs(s._data) do items[#items+1]=tostring(k) end
table.sort(items)
return "Set{" .. table.concat(items,", ") .. "}"
end
function Set.new(...)
local obj = setmetatable({_data={},_size=0}, Set)
for _, v in ipairs({...}) do
if not obj._data[v] then obj._data[v]=true; obj._size=obj._size+1 end
end
return obj
end
local s = Set.new(3,1,4,1,5,9,2,6)
print(#s) -- 7 (duplicates removed)
print(tostring(s)) -- Set{1, 2, 3, 4, 5, 6, 9}Numerische Objekte mit beiden Metamethoden
Erstellen Sie einen Bruchtyp mit __tostring für die Anzeige und __len als Ziffernanzahl (oder als domänenspezifische Kennzahl).
local Frac = {}
Frac.__index = Frac
local function gcd(a,b) return b==0 and a or gcd(b,a%b) end
function Frac.new(n,d)
local g = gcd(math.abs(n), math.abs(d))
return setmetatable({n=n//g, d=d//g}, Frac)
end
Frac.__tostring = function(f)
if f.d==1 then return tostring(f.n) end
return f.n .. "/" .. f.d
end
Frac.__add = function(a,b)
return Frac.new(a.n*b.d + b.n*a.d, a.d*b.d)
end
local a = Frac.new(1,2)
local b = Frac.new(1,3)
print(a + b) -- 5/6Das standardmäßige Verhalten von print überschreiben
Lua ruft für jedes durch Tabulatoren getrennte Argument von print tostring auf. Wenn __tostring definiert ist, werden Ihre Objekte in jeder print-Anweisung, Fehlermeldung oder String-Interpolation, die tostring verwendet, sinnvoll dargestellt.
local Color = {}
Color.__index = Color
Color.__tostring = function(c)
return string.format("#%02X%02X%02X", c.r, c.g, c.b)
end
function Color.new(r,g,b)
return setmetatable({r=r,g=g,b=b}, Color)
end
local red = Color.new(255,0,0)
local green = Color.new(0,255,0)
local blue = Color.new(0,0,255)
print(red, green, blue)
-- #FF0000 #00FF00 #0000FF__name in Lua 5.3+
Lua 5.3+ unterstützt ein __name-Feld in der Metatabelle, das von den standardmäßigen Fehlermeldungen zur Identifizierung des Typs verwendet wird. Es beeinflusst tostring() zwar nicht direkt, erscheint aber in Laufzeitfehlermeldungen, wenn Sie ungültige Operationen für den Typ ausführen.
local MyType = {}
MyType.__index = MyType
MyType.__name = "MyType" -- used in error messages
MyType.__tostring = function(t)
return "MyType(" .. tostring(t.value) .. ")"
end
local obj = setmetatable({value=42}, MyType)
print(obj) -- MyType(42)
-- Error message will say "MyType" instead of "table"
-- pcall(function() local x = obj + 1 end)Schnelltest
Wann wird __tostring aufgerufen?
Zusammenfassung: __tostring und __len
Zusammenfassung:
__tostring: wird vontostring()undprint()aufgerufen__len: wird von#objaufgerufen und liefert die verbindliche Länge für benutzerdefinierte Container- Definieren Sie
__tostringin Klassentabellen, damit es für alle Instanzen gilt - Verwenden Sie
__len, wenn die rohe Tabellenstruktur nicht die korrekte Länge für#liefert __name(5.3+) benennt den Typ in Fehlermeldungen
Häufig gestellte Fragen
Ist die Lektion „__tostring und __len“ kostenlos?
Ja — der vollständige Text von „__tostring und __len“ 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 „__tostring und __len“?
Steuern Sie die Zeichenkettendarstellung und den #-Operator über Metamethoden 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 4 von 4.
Wie lange dauert die Lektion „__tostring und __len“?
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
- Einführung in Metatabellen
- __index und __newindex
- Arithmetische Metamethoden
- __tostring und __len