Menu
Coddy logo textTech

Форматирование строк

Часть раздела Object Oriented Programming путешествия по Lua на Coddy — урок 16 из 70.

Когда вы выводите объект напрямую, Lua показывает нечто малополезное, вроде table: 0x55a... — просто адрес в памяти. Метаметод __tostring позволяет вам точно определить, какая строка будет представлять ваш объект при его выводе на печать или преобразовании в текст.

В паттерне классов вы добавляете __tostring как функцию в таблицу вашего класса. Поскольку сам класс служит метатаблицей для экземпляров, Lua автоматически находит и использует эту функцию:

local Player = {}
Player.__index = Player

function Player:new(name, level)
    local instance = {}
    setmetatable(instance, self)
    instance.name = name
    instance.level = level
    return instance
end

function Player:__tostring()
    return "Player: " .. self.name .. " (Level " .. self.level .. ")"
end

Теперь, когда вы выводите экземпляр Player, Lua автоматически вызывает ваш метод __tostring:

local hero = Player:new("Luna", 5)
print(hero)  -- Вывод: Player: Luna (Level 5)

Обратите внимание, что __tostring использует синтаксис с двоеточием и получает self, предоставляя вам доступ ко всем данным экземпляра. Функция должна возвращать строку — вы можете отформатировать её так, как это удобно для вашего объекта, объединяя любые атрибуты в читаемое представление.

challenge icon

Задание

Легко

Давайте создадим класс Book, который умеет представлять себя! Когда вы напрямую выводите объект книги на печать, Lua будет отображать красиво отформатированную строку вместо непонятного адреса памяти — и все это благодаря метаметоду __tostring.

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

  • Book.lua: Определите класс Book, используя стандартный паттерн прототипа. Каждая книга должна хранить title и author. Добавьте конструктор :new(title, author) и реализуйте метаметод __tostring, чтобы при выводе книги на печать ее информация отображалась в читаемом формате.
  • main.lua: Подключите модуль Book, создайте экземпляры книг и выведите их напрямую, чтобы увидеть ваше пользовательское форматирование строк в действии.

Ваш метод __tostring должен возвращать строку именно в таком формате:

"[title]" by [author]

Обратите внимание, что название (title) в выходной строке заключено в двойные кавычки.

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

  1. Название первой книги
  2. Автор первой книги
  3. Название второй книги
  4. Автор второй книги

В основном файле создайте две книги, используя предоставленные входные данные, и выведите каждую книгу напрямую (не вызывая метод, а просто через print(book)). Каждая книга должна быть выведена на отдельной строке.

Например, если входные данные — The Hobbit, J.R.R. Tolkien, 1984 и George Orwell, вывод должен быть следующим:

"The Hobbit" by J.R.R. Tolkien
"1984" by George Orwell

Помните, что __tostring должен возвращать строку, и так как таблица вашего класса служит метатаблицей для экземпляров, Lua автоматически найдет и использует вашу функцию __tostring при выводе книги на печать.

Шпаргалка

Метаметод __tostring определяет, как объект представляется в виде строки при выводе на печать или преобразовании в текст.

Без __tostring при выводе объекта на печать отображается только его адрес в памяти:

print(someObject)  -- Вывод: table: 0x55a...

Добавьте __tostring как метод в ваш класс, чтобы настроить строковое представление:

local Player = {}
Player.__index = Player

function Player:new(name, level)
    local instance = {}
    setmetatable(instance, self)
    instance.name = name
    instance.level = level
    return instance
end

function Player:__tostring()
    return "Player: " .. self.name .. " (Level " .. self.level .. ")"
end

Когда вы выводите экземпляр на печать, Lua автоматически вызывает __tostring:

local hero = Player:new("Luna", 5)
print(hero)  -- Вывод: Player: Luna (Level 5)

Ключевые моменты:

  • Используйте синтаксис с двоеточием (:), чтобы метод получал self
  • Метод должен возвращать строку
  • Доступ к данным экземпляра осуществляется через self
  • Поскольку таблица класса служит метатаблицей, Lua находит __tostring автоматически

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

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

-- Считать входные данные
local title1 = io.read()
local author1 = io.read()
local title2 = io.read()
local author2 = io.read()

-- TODO: Создать два экземпляра книги, используя Book:new()


-- TODO: Вывести каждую книгу напрямую (просто используйте print(book))

quiz iconПроверьте себя

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

Все уроки раздела Object Oriented Programming