lua中的弱表理解

  • 为什么要引入弱表?

    我们都知道,lua具有自动内存管理,我们只管创建对象,无需删除对象,对于不再需要的对象只需要简单置为nil,

lua会自动删除那些被认为是垃圾的数据;问题就在于,什么对象才是垃圾对象呢?有时候,程序员很清楚的知道某个对象

是垃圾,而lua却无法发现;

比如下面的例子:

t = {
    
    };

-- 使用一个table作为t的key值
key1 = {
    
    name = "key1"};
t[key1] = 1;
key1 = nil;

-- 又使用一个table作为t的key值
key2 = {
    
    name = "key2"};
t[key2] = 1;
key2 = nil;

for key, value in pairs(t) do
    print(key.name .. ":" .. value);
end
-- 强制进行一次垃圾收集
collectgarbage();

for key, value in pairs(t) do
    print(key.name .. ":" .. value);
end

执行结果如下:

key1:1
key2:1
key1:1
key2:1

代码首先创建了一个空表t,接着创建了一个表key1,然后将key1作为t的键,赋值为1,最后将key1置nil;

key2表也是一样的操作;

接着程序执行了一次collectgarbage()强制进行一次垃圾回收,此时key1和key2表都被置nil,但是并没有被强制回收,

换句话说,虽然key1本身为nil,但是他先前指向的内容并没有被删除,因为这个内容被保存在了t中;

那么,如果我们希望在将key1置为nil时,他指向的内容就被清空,不管t中是否引用了这个内容,该怎么做?

我们来看如下的代码:

t = {
    
    };
-- 给t设置一个元表,增加__mode元方法,赋值为"k"
setmetatable(t, {
    
    __mode = "k"});

-- 使用一个table作为t的key值
key1 = {
    
    name = "key1"};
t[key1] = 1;
key1 = nil;

-- 又使用一个table作为t的key值
key2 = {
    
    name = "key2"};
t[key2] = 1;
key2 = nil;

for key, value in pairs(t) do
    print(key.name .. ":" .. value);
end
-- 强制进行一次垃圾收集
collectgarbage();

for key, value in pairs(t) do
    print(key.name .. ":" .. value);
end

以上代码在创建了表t后,立即将t设置为元表,元表里面有一个__mode字段,值为"k",通过运行结果,我们知道

在执行collectgarbage()之前,能够输出t中的元素,但是执行垃圾回收之后,就不能再次输出t中的元素的,这是因为

将表设置为元表后,通过__mode = "k"将其指定为对键的弱引用,也就是说,一旦表中的某个键被垃圾回收,t中会删除

这个键对应的元素;

  • 三种形式的弱引用

    lua中提供了以下三种形式的弱引用:

(1)key值弱引用,也就是刚刚上面提到的那种形式的弱引用,只要其他地方没有对key值得引用,那么table自身

的这个字段也会被删除,设置方法:setmetatable(t, { __mode = "k"});

(2)value值弱引用,类似的,只要其他地方没有对value值得引用,table的这个value所在的字段也会被删除,

设置方法:setmetatable(t, { __mode = "v"});

(3)key和value弱引用,规则一样,只要key或者value中一个在其他地方没有引用,table中对应的字段就被

删除,设置方法:setmetatable(t, { __mode = "kv"});

  • 为什么要引入弱表?

    我们都知道,lua具有自动内存管理,我们只管创建对象,无需删除对象,对于不再需要的对象只需要简单置为nil,

lua会自动删除那些被认为是垃圾的数据;问题就在于,什么对象才是垃圾对象呢?有时候,程序员很清楚的知道某个对象

是垃圾,而lua却无法发现;

比如下面的例子:

猜你喜欢

转载自blog.csdn.net/m1234567q/article/details/114378065
今日推荐