Это не возможно, чтобы иметь как чистое выражение, как:
t = { foo = this .. ' bar' }
потому что this
всегда будет выражаться без всякого отношения к ключу или таблицы. То есть вы не можете зафиксировать выражение как значение записи в таблице.
Возможно, что реализуется некоторый уровень косвенности с использованием metatables и функций, но это довольно сложно. Здесь мы проводим оценку времени выборки. Вы также можете пересчитать результаты.
local function indirect_table()
local uptable = {}
return setmetatable({}, {
__index = function (self, key)
local value = uptable[key]
return type(value) == 'function' and uptable[key](key) or value
end,
__newindex = function (self, key, value)
uptable[key] = value
--[[precompute, with no need for an uptable, or __index:
`rawset(self, key, value(key)`]]
end
})
end
local tab = indirect_table()
tab.foo = function (key) return key .. 'bar' end
print(tab.foo) --> 'foobar'
Примечание: в этом примере используется замыкание, но вы можете реализовать этот вид рисунка с использованием getmetatable
, а также.
Лично я бы абстрактное это в шаблон, который позволяет косвенный произвольные ключи и значения, а их действия быть указаны. Я считаю, что этот тип шаблонов будет в основном использоваться программно, а не вручную, где результаты ключевых значений зависят от полученных входов. Опять же, не красивая, но немного более надежная (необязательные действия).
local function I (_, value) return value end
local K = setmetatable({
__call = function (actor, key)
return actor.action(key, actor.value)
end
}, {
__call = function (K, value, action)
return setmetatable({ value = value, action = action or I }, K)
end
})
local T = setmetatable({
__newindex = function (self, key, value)
if getmetatable(value) == K then
value = value(key)
end
rawset(self, key, value)
end
}, {
__call = function (T, o)
return setmetatable(o or {}, T)
end
})
Простое использование:
local function concat (left, right) return left .. right end
local t = T {}
t.foo = K('bar', concat) -- with a common action
t.zar = K({}, unknown_action) -- without action (`nil`)
t.qux = 'qaz' -- standard
print(t.foo, t.zar, t.qux)
Это странно метапрограммированием. Я бы дважды проверял рассуждения о необходимости такого подхода. Возможно, вы попадаете в ловушку XY Problem? На самом деле это похоже на решение проблемы, которая не обязательно должна существовать в первую очередь.
Ну, это сработает для моего приведенного примера, так что это правильный ответ. Однако я имел в виду использование 'this' в качестве параметра анонимной функции, затронутой ключом, например' example = {["dummy"] = function (k = this) return k .. "example" end' , – psychoslave
@psychoslave, при предварительной обработке, если 'v' является функцией, выполните пример [k] = v (k)'. – lhf
@psychoslave Почему бы просто не пропустить ключ напрямую при вызове? – warspyking