Menu
CoddyTech

Конкатенация объектов

Часть раздела Объектно-ориентированное программирование путешествия по Lua на Coddy. Урок 28 из 70.

Оператор .. в Lua объединяет строки, но что, если вы хотите объединить объект со строкой? Метаметод __concat позволяет точно определить, как это должно работать.

Когда Lua встречает a .. b и у одного из операндов есть метаметод __concat, он вызывает эту функцию с обоими значениями. Это полезно, когда вы хотите, чтобы объекты естественно вписывались в строковые выражения.

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

Обрати внимание: функция проверяет, какой операнд является строкой. Поскольку .. можно использовать как "Hello " .. obj или obj .. "!", твой метаметод должен обрабатывать оба случая.

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

print("Dr. " .. person)      -- Вывод: Dr. Ada Lovelace
print(person .. " PhD")      -- Вывод: Ada Lovelace PhD

Как и другие метаметоды операторов, __concat по соглашению записывается с точкой и получает оба операнда в качестве аргументов. Ключевое отличие от арифметических метаметодов заключается в том, что обычно вы работаете со смешанными типами: ваш объект и строка.

challenge icon

Задание

Легко

Давайте создадим класс Title, который естественно встраивается в строковые выражения с помощью оператора ... Это полезно, когда нужно удобным и понятным образом объединять объекты со строками, например добавлять к титулу человека почётные обращения или суффиксы.

Вы распределите код по двум файлам:

  • Title.lua: Определите класс Title с полем text, в котором хранится строка титула. Добавьте конструктор :new(text) и реализуйте метаметод __concat. Метаметод должен обрабатывать оба случая: когда строка стоит перед объектом ("prefix" .. obj) и когда строка стоит после него (obj .. "suffix"). Результат должен соответствующим образом объединять строку и текст титула.
  • main.lua: Подключите модуль Title, создайте экземпляр титула и продемонстрируйте конкатенацию в обоих направлениях.

Вы получите три входных значения:

  1. Текст титула (например, "Engineer")
  2. Строку-префикс, которую нужно поместить перед титулом (например, "Senior ")
  3. Строку-суффикс, которую нужно поместить после титула (например, " III")

В основном файле создайте объект Title с заданным текстом. Затем выполните две операции конкатенации и выведите результат каждой на отдельной строке:

  1. Объедините строку-префикс с объектом титула
  2. Объедините объект титула со строкой-суффиксом

Например, если входные значения — Engineer, Senior и III, вывод должен быть таким:

Senior Engineer
Engineer III

Первая строка показывает префикс, объединённый с титулом, а вторая — титул, объединённый с суффиксом. Метаметод __concat позволяет естественно объединять строки таким образом!

Попробуйте сами

-- Считать входные данные
local titleText = io.read()
local prefix = io.read()
local suffix = io.read()

-- Подключить модуль Title
local Title = require('Title')

-- TODO: Создать экземпляр Title с заданным titleText

-- TODO: Объединить prefix с объектом title и вывести результат

-- TODO: Объединить объект title с suffix и вывести результат
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Lua