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

时间:2017-02-22 09:03:45

标签: lua

我正在寻找一种从类似于__newindex元方法的lua表中删除元素时触发的元方法(或变通方法)。

理想情况下,它的工作方式如下:

local mytable = {}

local mt = {
  __newindex = function(t,k,v)
    rawset(t,k,v)
    -- some other functionality
  end,

  -- This does not exist
  __remove = function(t,k)
    --some functionality
  end
}

setmetatable(mytable,mt)

-- __newindex fires
mytable["key"] = value

-- __remove fires
mytable["key"] = nil

我尝试使用__gc元方法,但由于metamethod仅在垃圾收集周期发生时触发,因此在此实现中无法使用。我无法控制垃圾收集,因为表(使用metamethods)被传递给另一个脚本。

2 个答案:

答案 0 :(得分:1)

由于根本不分配nil fires而不是metamethod,你将不得不求助于一个显式的删除函数,它可以执行你想要的metamethod做什么,然后将nil分配给表项。

答案 1 :(得分:1)

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

让您的mytable充当代理,并将实际值存储在某个影子表中。它可能与mytable一起分配,或者数据可以直接存储在metatable中(因此必须按mytable实例创建metatable)。 这里有一个例子(通过在元方法和名称键下编写数据很容易打破,但你知道了),数据将存储在metatable中: 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)