Menu
CoddyTech

Метаметод __index

Часть раздела Логика и управление потоком путешествия по Lua на Coddy. Урок 18 из 54.

Теперь, когда ты знаешь, как прикреплять метатаблицы к таблицам, пришло время узнать о самом важном метаметоде: __index. Этот метаметод определяет, что происходит, когда ты пытаешься получить доступ к ключу, которого нет в таблице.

Обычно, когда вы ищете ключ, которого нет в таблице, Lua возвращает nil. Но если у таблицы есть метатаблица с полем __index, Lua проверит это поле. Если __index указывает на другую таблицу, Lua будет искать ключ там:

local defaults = {
    health = 100,
    speed = 10
}

local player = {name = "Alice"}
local meta = {__index = defaults}

setmetatable(player, meta)

print(player.name)    -- Вывод: Alice
print(player.health)  -- Вывод: 100

В этом примере у player есть только ключ name. Когда вы обращаетесь к player.health, Lua не находит его в player, поэтому проверяет поле __index метатаблицы. Поскольку __index указывает на таблицу defaults, Lua ищет там и находит health = 100.

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

__index также может быть функцией. Если ключ отсутствует, Lua вызывает её, передавая таблицу и ключ, и использует возвращённое ею значение:

local scores = {alice = 12}

setmetatable(scores, {
    __index = function(t, key)
        return 0  -- каждое отсутствующее имя считается равным 0
    end
})

print(scores.alice)  -- Вывод: 12
print(scores.bob)    -- Вывод: 0

Таблица задаёт фиксированные значения по умолчанию; функция может вычислить значение для любого отсутствующего ключа.

challenge icon

Задание

Легко

Напиши функцию createCharacterWithDefaults, которая принимает name и level и возвращает таблицу персонажа со значениями характеристик по умолчанию.

Создай таблицу персонажа с указанными именем и уровнем. Используй метатаблицу с __index, чтобы задавать значения по умолчанию для всех отсутствующих характеристик (здоровье, мана, сила).

Логика:

  • Создай таблицу defaults с ключами: health = 100, mana = 50, strength = 10
  • Создай таблицу персонажа с ключами: name (указанное имя) и level (указанный уровень)
  • Создай метатаблицу с __index, указывающим на таблицу defaults
  • Присоедини метатаблицу к таблице персонажа с помощью setmetatable()
  • Верни таблицу персонажа

Параметры:

  • name (строка): имя персонажа
  • level (число): уровень персонажа

Возвращает: таблицу персонажа с именем, уровнем и характеристиками по умолчанию, доступными через метатаблицу (таблица)

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

function createCharacterWithDefaults(name, level)
    -- Напишите код здесь
end
quiz iconПроверьте себя

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

Все уроки раздела Логика и управление потоком

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