Menu
Coddy logo textTech

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

Часть раздела Объектно-ориентированное программирование путешествия по 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

Обратите внимание: function проверяет, какой operand является string. Поскольку .. можно использовать как "Hello " .. obj или obj .. "!", ваш metamethod должен handle both cases.

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

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

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

challenge icon

Задание

Легко

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

Вы организуете код в двух файлах:

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

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

  1. Текст заголовка (например, "Engineer")
  2. String prefix, который нужно разместить перед заголовком (например, "Senior ")
  3. String suffix, который нужно разместить после заголовка (например, " III")

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

  1. Объедините string prefix с object заголовка
  2. Объедините object заголовка с string suffix

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

Senior Engineer
Engineer III

В первой строке prefix объединён с заголовком, а во второй строке заголовок объединён с suffix. Ваш метаметод __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