--13.4.4 监控表 t = {} -- original table (created somewhere) --这是原始表 我们要监控的 -- keep a private access to original table local _t = t --保存起来 赋值给 _t -- create proxy t = {} --创建代理表 -- create metatable local mt = { __index = function (t,k) print("*access to element " .. tostring(k)) return _t[k] -- access the original table end, __newindex = function (t,k,v) print("*update of element " .. tostring(k) .. " to " .. tostring(v) .. " 原始值:" .. tostring(_t[k])) _t[k] = v -- update original table end } setmetatable(t, mt) --这样我们对 原始表t的访问都将通过 代理表 t中转 有点hook的感觉?.. t['key2']=112; print(t['key1'],t['key2']) --(注意:不幸的是,这个设计不允许我们遍历表。 -- Pairs函数将对proxy进行操作,而不是原始的表。) -- create private index --如果我们想监控多张表,我们不需要为每一张表都建立一个不同的metatable。 --我们只要将每一个proxy和他原始的表关联,所有的proxy共享一个公用的metatable即可。 --将表和对应的proxy关联的一个简单的方法是将原始的表作为proxy的域, --只要我们保证这个域不用作其他用途。 --一个简单的保证它不被作他用的方法是创建一个私有的没有他人可以访问的key。 --将上面的思想汇总,最终的结果如下: local index = {} -- create metatable local mt = { __index = function (t,k) print("*access to element " .. tostring(k)) return t[index][k] -- access the original table end __newindex = function (t,k,v) print("*update of element " .. tostring(k) .. " to " .. tostring(v)) t[index][k] = v -- update original table end } function track (t) local proxy = {} proxy[index] = t--吧原始表放到了 代理表的域内`` key用的 独一无二的 index表作为key setmetatable(proxy, mt) return proxy end --现在,不管什么时候我们想监控表t,我们要做得只是t=track(t)。