能否使用 LUA 元表来检测对象的 nil 值?

我想知道是否可以通过元表检测对象的 nil 值?

foo = {}
foo_mt = {
    __newindex = function (t, k, v)
        print (k, v)
        rawset (t, k, v)
      end
}

setmetatable (foo, foo_mt)

foo ['oof'] = 3

输出:oof  3

foo ['oof'] = nil

__newindex 不会被调用,那么是否还有其他可用的元表方法?
点赞
用户13619683
用户13619683

只是澄清一下,只有在之前的值为 nil 时才会触发 __newindex。 因此,以下代码将触发两次 __newindex:

foo = {}
foo_mt = {
    __newindex = function (t, k, v)
        print (k, v)
        rawset (t, k, v)
      end
}

setmetatable (foo, foo_mt)

foo['oof'] = nil
foo['oof'] = nil

如果 foo['oof'] 已经有一个非 nil 值,则不会调用 __newindex(因为索引已经存在)。

但是,如果您想捕获对表的所有修改,就像 Egor 指出的那样,您需要像空代理表那样的东西。

proxy = {}
foo = {}
foo_mt = {
  __newindex = function (t, k, v)
    print (k, v)
    rawset (proxy, k, v)
  end,
  __index = function(t, k)
    return rawget(proxy, k)
  end
}
setmetatable (foo, foo_mt)

foo['ok'] = true
foo['ok'] = nil
2020-08-29 05:39:31