Lua 5.1为表的__gc元方法提供的解决方案。

我目前面临的问题是,在Lua 5.1中无法使用__gc方法来处理表格,因为它们是在Lua 5.2中实现的。但是,我想一旦Lua表格被回收,就释放分配的本地资源。是否可以制定一种解决方案,使我在Lua 5.1中获得类似于Lua 5.2中__gc元方法的功能?

点赞
用户234175
用户234175

在Lua 5.1中,__gc 元方法仅适用于 userdata 类型的元素。自然地,任何黑客或变通方法都必须以某种方式涉及 userdata。通常无法从Lua端创建新 userdata,但是有一个名为 _hidden_ 的不公开文档函数 newproxy 可以做到这一点。

newproxy 接受可选的布尔或 userdata 参数。如果您传递 true,则会得到一个带有新元表的 userdata。如果您传递另一个 userdata,则新的 userdata 将被分配与传入的元 userdata 相同的元表。

因此,您现在可以随便拼凑一个函数,使得 __gc 在表格上工作:

function setmt__gc(t, mt)
  local prox = newproxy(true)
  getmetatable(prox).__gc = function() mt.__gc(t) end
  t[prox] = true
  return setmetatable(t, mt)
end

为了确认其行为的快速测试 :

iscollected = false
function gctest(self)
  iscollected = true
  print("cleaning up:", self)
end

test = setmt__gc({}, {__gc = gctest})
collectgarbage()
assert(not iscollected)

test = nil
collectgarbage()
assert(iscollected)

IDEOne Demo

请注意,Lua 5.2及以后版本不再具有 newproxy,因为在表格上官方支持了 __gc

2014-12-11 21:53:18