Lua元方法在从表中删除元素时触发

我正在寻找一种元方法(或解决方法),可以在从Lua表中删除元素时触发,类似于__newindex元方法。

理想情况下,它应该像下面这样工作:

local mytable = {}

local mt = {
  __newindex = function(t,k,v)
    rawset(t,k,v)
    -- 其他功能
  end,

  -- 这不存在
  __remove = function(t,k)
    -- 一些功能
  end
}

setmetatable(mytable,mt)

-- __newindex触发
mytable["key"] = value

-- __remove触发
mytable["key"] = nil

我尝试使用__gc元方法,但由于元方法仅在垃圾回收周期发生时触发,因此该实现无法使用。我无法控制垃圾回收,因为表(带有元方法)被传递给不同的脚本。

点赞
用户2420301
用户2420301

由于分配 nil 不会触发任何元方法,因此您必须使用显式删除函数,并执行您想要的元方法,然后将 nil 分配给表条目。

2017-02-22 09:35:54
用户5675002
用户5675002

可能的解决方法-不要将实际数据存储在表内。

让你的 mytable 充当代理,在某个影子表中存储实际值。它可以与 mytable 一起分配,或者数据可以直接存储在元表中(因此必须为每个 mytable 实例创建元表)。 这是一个示例(可以通过在元方法的名称键下写入数据轻松破坏,但您可以理解),数据将存储在元表中: http://ideone.com/eCOal3

local mytable = {}

local mt = {}

function mt.__newindex(t,k,new_value)
    local previous_value = mt[k]
    rawset(mt,k,new_value)

    if previous_value and new_value == nil then
        print "__remove() triggered"
    end
end
mt.__index = mt

setmetatable(mytable, mt)

mytable.key = 123
print(mytable.key)

mytable.key = nil
print(mytable.key)
2017-02-22 09:42:49