如何在Lua中删除一个表?

4
让我们看下面的代码。
do
    local a = {1,2,3}
    function a:doSth()
        self = nil
    end

    a:doSth()

    if a then
        print("Still has a...")
    end
end

我发现这种方法不起作用。表格a仍然存在,为什么呢? 我知道a=nil可以回收表格a所占用的内存。 如何直接获取由表格a持有的内存并释放内存,就像C++中的delete一样?

2个回答

4
function a:doSth()
    self = nil
end

是语法糖,用于

function a.doSth(self)
    self = nil
end

在您上面的代码中,对于表格值{1,2,3}有两个不同的引用,一个是通过local a,另一个是通过函数内部的self。将其中一个引用设为nil并不会改变对该表格的其他引用。

为了使该表格被视为垃圾回收集合的一部分,您必须确保没有引用指向它。例如:

function a:doSth()
    a = nil
end

这将释放对 a 的引用,但仍有来自 self 的引用,但当函数结束时,它会自动超出范围。在函数调用之后,{1,2,3} 将在下一个循环中被 gc 收集,假设没有其他东西引用该表。


但是如何直接获取表'a'所持有的内存地址,并像C++中的'delete'一样释放内存呢?谢谢。 - NiklausTseng
1
答案是你不需要这样做。Lua是一种垃圾回收的脚本语言,其中的安全性意味着不允许您在如此低的级别上手动操纵资源。您能够做到的最接近的方法是将引用设置为nil,然后调用collectgarbage() - greatwolf
你不需要将变量设置为 nil。你只需要停止引用该表即可。一种方法是限制变量的作用域。另一种方法是将其设置为新表,这使您可以编写假定始终引用某个表的代码。 - Tom Blodget

1
你可以做到这个:

a = nil
collectgarbage()

然而,我不建议仅为了释放一个表格而运行完整的垃圾回收循环。垃圾回收需要时间,最好让Lua在适当时候运行它。


仅仅使用collectgarbage()是不够的。只有在没有其他对同一张表的引用时,它才能起作用。 - Alexander Altshuler
通过查看 OP 的示例代码,我们可以假设没有其他引用。 - kikito

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接