Это хорошее приложение для использования метатаблиц:
parent={
child={
{value="whatever"},
{value="blah"}
}
}
setmetatable(parent.child,{__index=parent.child[1]})
Если индекс не найден в дочерней таблице (например, «значение»), он будет найден в таблице со значением __index.метатаблицы (первый элемент child в этом случае).
Теперь существует проблема с приведенным выше кодом, который мы можем видеть следующим образом:
print(parent.child.value) -- prints whatever
parent.child[1]=nil --remove first child
print(parent.child.value) -- still prints whatever!
Это потому, что метатабельныйсохраняет ссылку на первую дочернюю таблицу, предотвращая ее получение.Обходной путь для такого рода вещей: A) сделать метатаблицу слабой таблицей, или B) сделать поле __index функцией, а не ссылаться на нее в таблице.
-- A)
setmetatable(parent.child, setmetatable(
{__index=parent.child[1]} -- metatable for the child table
{__mode='v'}-- metatable for the metatable, making it have weak keys
)
)
parent.child[1]=nil
print(parent.child.value) --returns nil
parent.child[1]={value='foo'}
print(parent.child.value) -- prints nil, the metatable references to a non-existant table.
-- hence solution B)
setmetatable(parent.child, {__index=function(t,k) return parent.child[1][k]})
print(parent.child.value) -- 'whatever'
parent.child[1]=nil
print(parent.child.value) -- nil
parent.child[1]={value='foobar'
print(parent.child.value) -- foobar, now it will always refer to the table at child[1], even when it changes.
Если вы действительно заинтересованычтобы прочитать метатаблицы, попробуйте прочитать Программирование на Lua, глава 13 и глава 17 (слабые таблицы) . Lua-Users wiki на MetaMethods также может быть интересным.