#lua
#lua
Вопрос:
Следующий сеанс показывает, что я пытался. Должно быть, я где-то неправильно прочитал какую-то документацию, в которой (как мне показалось) говорилось, что элемент __index в метатаблице предоставляет значение по умолчанию, когда таблица не предоставляет элемент для этого ключа. Дело в том, что это не работает с самими метатаблицами, но я понятия не имею, почему нет. Где в документации это объясняется, и что я могу с этим поделать в таких случаях?
Спасибо!
> a = {}
> b = {}
> setmetatable(a,b)
table: 0000000002631ae0
> c = { __tostring = function(x) return "X" end }
> setmetatable(b,{ __index=c })
table: 0000000002631560
>
> print(a)
table: 0000000002631ae0
> -- I was expecting: X
> print(getmetatable(a).__tostring)
function: 0000000002633840
> print(tostring(a))
table: 0000000002631ae0
> -- Again, expecting X
> print(getmetatable(a).__tostring(a))
X
>
Вот еще один пример.
> a = {}
> b = {}
> setmetatable(a,b)
table: 0000000002631fe0
> c = { __add = function(x,y) return "X" end }
> setmetatable(b,{ __index=c })
table: 00000000026316a0
>
> print(a a)
stdin:1: attempt to perform arithmetic on a table value (global 'a')
stack traceback:
stdin:1: in main chunk
[C]: in ?
>
Таким образом, эта проблема не относится к print и tostring . Конечно, в реальных ситуациях я хочу иметь много разных объектов, разделяющих множество метатаблических значений, без необходимости копировать все каждый раз…
Ответ №1:
Это связано __index
с операциями индексации, такими как tbl.var
. Lua не использует __index
для получения других метаметодов (например __tostring
).
Вы используете print
который вызывает __tostring
непосредственно из метатаблицы, здесь он не используется __index
.
__index: таблица операций доступа к индексации [ключ]
Узнайте больше: https://www.lua.org/manual/5.4/manual.html#2.4
Решением было бы объединение метатаблиц c
с b
.
setmetatable(b,{ __tostring = c.__tostring })
print(b) -- X
Комментарии:
1. Я не знаю, где описан tbl.var. Но это не относится к print и __tostring . Я добавил еще один пример…
2. @SadieKaye Хорошо, немного перефразируя, Lua не использует __index для получения других метаметодов. Это влияет на __tostring, __add, __sub, __mul, __mode, __pairs и т. Д. (Все они)
3. Итак, вопросы.. где это задокументировано и что мне с этим делать?
4. @SadieKaye Это конкретно не задокументировано, но в нем упоминается, когда вызывается __index . lua.org/manual/5.4/manual.html#2.4 > __index: операция доступа к индексации «таблица [ключ]»
5. @SadieKaye: Это задокументировано здесь . «Lua запрашивает метаметоды в метатаблицах, используя необработанный доступ (см. rawget )».