Конкатенация объектов
Часть раздела Объектно-ориентированное программирование путешествия по 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 и строкой.
Задание
ЛегкоДавайте создадим класс Title, который сможет естественно использоваться в выражениях со строками с помощью оператора ... Это полезно, когда нужно объединять объекты со строками понятным и интуитивным способом, например добавлять почётные обращения или суффиксы к званию человека.
Вы организуете код в двух файлах:
Title.lua: определите свой класс Title с полемtext, в котором хранится строка заголовка. Добавьте конструктор:new(text)и реализуйте метаметод__concat. Ваш метаметод должен обрабатывать оба случая: когда string находится перед object ("prefix" .. obj) и когда string находится после него (obj .. "suffix"). result должен соответствующим образом объединять string с text заголовка.main.lua: подключите свой модуль Title, создайте instance заголовка и продемонстрируйте конкатенацию в обоих направлениях.
Вы получите три входных значения:
- Текст заголовка (например, "Engineer")
- String prefix, который нужно разместить перед заголовком (например, "Senior ")
- String suffix, который нужно разместить после заголовка (например, " III")
В основном файле создайте Title с заданным text. Затем выполните две конкатенации и выведите каждый result в отдельной строке:
- Объедините string prefix с object заголовка
- Объедините 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 и вывести результат
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Концепция 'self'
Таблицы с функциямиЯвный 'self'Синтаксис с двоеточиемТочка против двоеточияИтоги — Движущаяся точка4Проект: Цифровой банк
Настройка проектаМетод пополнения7Полиморфизм и переопределение
Переопределение методовВызов родительских методовУтиная типизацияОбщий интерфейсПроверка типаИтоги — Роли сотрудников2Паттерн прототипа класса
Концепция прототипаСвязывание через __indexКонструктор :new()Инициализация атрибутовНезависимые экземплярыИтоги — Автозавод5Перегрузка операторов в ООП
Сложение объектовВычитание объектовКонкатенация объектовСравнение объектов (<, >)Повторение — Математика кошелька8Инкапсуляция
Соглашения об именованииЗамыкания для приватностиДоступ через замыканияТаблицы только для чтенияЛогика валидацииИтоги — Защищенное хранилище11Паттерны проектирования (Lite)
Фабричные функцииТаблица SingletonПаттерн IteratorObserver (Слушатель)Итоги — Logger Factory3Состояние и поведение объектов
Переменные экземпляраГеттерыСеттерыВычисляемые свойстваФорматирование строкПроверка на равенствоПовторение — Оценка студента6Основы наследования
Настройка наследованияНаследование методовРасширение конструктораДобавление дочерних методовОбщее и уникальноеИтоги: Иерархия фигурПотренируйтесь самостоятельно: Онлайн-компилятор Lua