如何解决所需值的完整路径
如何获取表中所需值的完整路径?我想通过代理表跟踪另一个表中的更改。
我知道我需要在其中使用元表和__index。但是我还没有想出一个跟踪器。
示例表结构:
Objects = {
Panel = { layer = 1,x = 600,y = 328,w = 331,h = 491;
objects = {
label = { layer = 1,x = 0,y = 0,text = 'header' };
Window = { layer = 2,x = 400,y = 100,w = 100,h = 100;
objects = {
label = { layer = 1,text = 'lorem ipsum dorem' };
};
};
};
};
};
路径:Objects.Panel.objects.Window.objects.label.text
我试图为每个表创建一个元表并将每个对__index的调用的结果收集到一个表中,以便大致了解检索或更改了哪些键和值,以便将这些值与其他表同步
解决方法
这将证明自己运行缓慢,内存效率低下。无论如何,您是对的:代理并根据自己的喜好处理__index
和__newindex
元方法。话虽如此,您还需要以某种方式跟踪代理的状态。
您可以尝试使用一些闭包和高值来隐藏它,但是简单的方法是将信息直接存储在代理表中:
function make_tracker (o,name)
local mt = {}
mt.__index = function (proxy,key)
local path = {unpack(rawget(proxy,"__path"))} -- Stupid shallow copy
local object = rawget(proxy,"__to")
table.insert(path,key)
if type(object[key]) == "table" then
return setmetatable({__to = object[key],__path = path},mt)
else
return table.concat(path,".") .. " = " .. tostring(object[key])
end
end
return setmetatable({__to = o,__path = {name}},mt)
end
__to
字段指示代理应该指向哪个代理,并且__path
包含我们迄今为止已侵入的字段。它会做一个浅表复制,以便可以使用带有局部变量的子代理。您可以使用name
参数来初始化第一个表的名称,因为您根本不知道这一点。您可以这样使用它:
local tObjects = make_tracker(Objects,"Objects")
local subproxy = tObjects.Panel.objects.Window
print(subproxy.objects.label.text)
print(tObjects.Panel.objects.label.text)
print(subproxy.x)
-- prints:
-- Objects.Panel.objects.Window.objects.label.text = lorem ipsum dorem
-- Objects.Panel.objects.label.text = header
-- Objects.Panel.objects.Window.x = 400
当然,我怀疑您想要的是将路径附加到原始值。修改else
块的内部:
return table.concat(path,".") .. " = " .. tostring(object[key])
根据您的需求,例如:
register_tracked_path(table.concat(path,"."))
return object[key]
如果要处理值的修改,则需要使用类似的__newindex
扩展元表。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。