Метаметод __index
Часть раздела Logic & Flow путешествия по 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.
Это создает механизм резервирования (fallback), при котором одна таблица может предоставлять значения по умолчанию для другой. Исходная таблица сохраняет свои собственные значения, но любые отсутствующие ключи автоматически ищутся в резервной таблице.
Задание
ЛегкоНапишите функцию createCharacterWithDefaults, которая принимает name и level и возвращает таблицу персонажа со значениями характеристик по умолчанию.
Создайте таблицу персонажа с указанными именем и уровнем. Используйте метатаблицу с __index для предоставления значений по умолчанию для любых отсутствующих характеристик (health, mana, strength).
Логика:
- Создайте таблицу defaults с ключами:
health = 100,mana = 50,strength = 10 - Создайте таблицу персонажа с ключами:
name(переданное имя) иlevel(переданный уровень) - Создайте метатаблицу, где
__indexуказывает на таблицу defaults - Прикрепите метатаблицу к таблице персонажа с помощью
setmetatable() - Верните таблицу персонажа
Параметры:
name(string): Имя персонажаlevel(number): Уровень персонажа
Возвращает: Таблицу персонажа с именем, уровнем и характеристиками по умолчанию, доступными через метатаблицу (table)
Шпаргалка
Метаметод __index управляет тем, что происходит при попытке доступа к ключу, которого не существует в таблице.
Когда у таблицы есть метатаблица с полем __index, указывающим на другую таблицу, Lua будет искать недостающие ключи в этой таблице:
local defaults = {
health = 100,
speed = 10
}
local player = {name = "Alice"}
local meta = {__index = defaults}
setmetatable(player, meta)
print(player.name) -- Output: Alice
print(player.health) -- Output: 100Это создает резервный механизм (fallback), при котором одна таблица может предоставлять значения по умолчанию для другой. Исходная таблица сохраняет свои собственные значения, но любые недостающие ключи автоматически ищутся в резервной таблице.
Попробуйте сами
function createCharacterWithDefaults(name, level)
-- Напишите код здесь
end
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Logic & Flow
1Продвинутая итерация таблиц
Итерация с помощью pairs()Итерация с помощью ipairs()pairs() против ipairs()Повторение — Лист персонажа2Дополнительные функции библиотеки table
table.concat()Создание таблиц и unpack()table.sort()Пользовательская сортировка с помощью функцийИтоги — Таблица рекордов