Menu
Coddy logo textTech

Objekte verketten

Teil des Abschnitts Object Oriented Programming der Lua-Journey von Coddy — Lektion 28 von 70.

Der ..-Operator in Lua verknüpft Strings, aber was ist, wenn Sie ein Objekt mit einem String kombinieren möchten? Die __concat-Metamethode lässt Sie genau definieren, wie dies funktionieren soll.

Wenn Lua auf a .. b stößt und ein Operand eine __concat-Metamethode besitzt, ruft es diese Funktion mit beiden Werten auf. Dies ist nützlich, wenn Sie möchten, dass sich Objekte natürlich in String-Ausdrücke einfügen.

local Name = {}
Name.__index = Name

function Name:new(first, last)
    local obj = {first = first, last = last}
    setmetatable(obj, Name)
    return obj
end

function Name.__concat(a, b)
    if type(a) == "string" then
        return a .. b.first .. " " .. b.last
    else
        return a.first .. " " .. a.last .. b
    end
end

Beachten Sie, dass die Funktion prüft, welcher Operand der String ist. Da .. sowohl als "Hello " .. obj als auch als obj .. "!" verwendet werden kann, sollte Ihre Metamethode beide Fälle behandeln.

local person = Name:new("Ada", "Lovelace")

print("Dr. " .. person)      -- Ausgabe: Dr. Ada Lovelace
print(person .. " PhD")      -- Ausgabe: Ada Lovelace PhD

Wie andere Operator-Metamethoden verwendet __concat die Punkt-Syntax und erhält beide Operanden als Argumente. Der Hauptunterschied zu arithmetischen Metamethoden besteht darin, dass Sie normalerweise mit gemischten Typen arbeiten – Ihrem Objekt und einem String.

challenge icon

Aufgabe

Einfach

Lassen Sie uns eine Title-Klasse erstellen, die sich mithilfe des ..-Operators natürlich in String-Ausdrücke einfügt. Dies ist nützlich, wenn Sie Objekte auf lesbare und intuitive Weise mit Strings kombinieren möchten – zum Beispiel, um Ehrentitel oder Suffixe zu einem Titel einer Person hinzuzufügen.

Sie werden Ihren Code auf zwei Dateien aufteilen:

  • Title.lua: Definieren Sie Ihre Title-Klasse mit einem text-Feld, das den Titel-String speichert. Fügen Sie einen :new(text)-Konstruktor hinzu und implementieren Sie die __concat-Metamethode. Ihre Metamethode sollte beide Fälle abdecken: wenn ein String vor dem Objekt steht ("prefix" .. obj) und wenn ein String danach steht (obj .. "suffix"). Das Ergebnis sollte den String angemessen mit dem Text des Titels kombinieren.
  • main.lua: Binden Sie Ihr Title-Modul ein, erstellen Sie eine Title-Instanz und demonstrieren Sie die Verkettung aus beiden Richtungen.

Sie erhalten drei Eingaben:

  1. Der Titeltext (z. B. "Engineer")
  2. Ein Präfix-String, der vor den Titel gesetzt wird (z. B. "Senior ")
  3. Ein Suffix-String, der nach dem Titel gesetzt wird (z. B. " III")

Erstellen Sie in Ihrer Hauptdatei einen Title mit dem angegebenen Text. Führen Sie dann zwei Verkettungen durch und geben Sie jedes Ergebnis in einer separaten Zeile aus:

  1. Verketten Sie den Präfix-String mit dem Title-Objekt
  2. Verketten Sie das Title-Objekt mit dem Suffix-String

Wenn die Eingaben beispielsweise Engineer, Senior und III sind, sollte die Ausgabe wie folgt aussehen:

Senior Engineer
Engineer III

Die erste Zeile zeigt das mit dem Titel kombinierte Präfix, und die zweite Zeile zeigt den mit dem Suffix kombinierten Titel. Ihre __concat-Metamethode macht diese natürliche String-Mischung möglich!

Spickzettel

Die Metamethode __concat ermöglicht es Ihnen, benutzerdefiniertes Verhalten für den Verkettungsoperator .. zu definieren, wenn Sie mit Objekten arbeiten.

Wenn Lua auf a .. b stößt und ein Operand eine __concat-Metamethode besitzt, ruft es diese Funktion mit beiden Werten auf.

Grundlegende Implementierung

local MyClass = {}
MyClass.__index = MyClass

function MyClass:new(value)
    local obj = {value = value}
    setmetatable(obj, MyClass)
    return obj
end

function MyClass.__concat(a, b)
    if type(a) == "string" then
        return a .. b.value
    else
        return a.value .. b
    end
end

Handhabung beider Operanden-Reihenfolgen

Da .. sowohl als "string" .. obj oder obj .. "string" verwendet werden kann, sollte Ihre Metamethode prüfen, welcher Operand der String ist, und beide Fälle behandeln:

function Name.__concat(a, b)
    if type(a) == "string" then
        return a .. b.first .. " " .. b.last
    else
        return a.first .. " " .. a.last .. b
    end
end

Anwendungsbeispiel

local person = Name:new("Ada", "Lovelace")

print("Dr. " .. person)      -- Output: Dr. Ada Lovelace
print(person .. " PhD")      -- Output: Ada Lovelace PhD

Wie andere Operator-Metamethoden verwendet __concat die Punkt-Syntax und erhält beide Operanden als Argumente.

Probier es selbst

-- Eingaben lesen
local titleText = io.read()
local prefix = io.read()
local suffix = io.read()

-- Das Modul Title laden
local Title = require('Title')

-- TODO: Erstelle eine Title-Instanz mit dem gegebenen titleText

-- TODO: Verknüpfe prefix mit dem title-Objekt und gib das Ergebnis aus

-- TODO: Verknüpfe das title-Objekt mit suffix und gib das Ergebnis aus
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 Object Oriented Programming