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

首先以一个table,叫做t。然后创建一个新的table——key1,这个key1作为t的key值,给t新增了一个字段,赋值为1。同样的,key2也作为t的一个key值。接着,调用了collectgarbage函数,可以不管它,我们只要知道,它会让lua进行一次垃圾回收。最后输出t的所有字段,输出结果如下:

[LUA-print] key1:1
[LUA-print] key2:1

虽然我们在给t赋值之后,key1和key2都赋值为nil了。但是,已经添加到table中的key值是不会因此而被当做垃圾的。换句话说,key1本身已经是nil值,但它曾经所指向的内容依然存放在t中。key2也是一样的情况。所以我们最后还是能输出key1和key2的name字段。



2.弱引用table

举例的只是正常情况,那么,如果我们把某个table作为另一个table的key值后,希望当table设为nil值时,另一个table的那一条字段也被删除。

应该如何实现?

这时候就要用到弱引用table了,弱引用table的实现也是利用了元表。

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

留意,在t被创建后,立刻给它设置了元表,元表里有一个__mode字段,赋值为”k”字符串。

如果这个时候大家运行代码,会发现什么都没有输出,因为,t的所有字段都不存在了。

这就是弱引用table的其中一种,给table添加__mode元方法,如果这个元方法的值包含了字符串”k”,就代表这个table的key都是弱引用的。

一旦其他地方对于key值的引用取消了(设置为nil),那么,这个table里的这个字段也会被删除。
 
通俗地说,因为t的key被设置为弱引用,所以,执行t[key1] = 1后,t中确实存在这个字段。

随后,又执行了key1 = nil,此时,除了t本身以外,就没有任何地方对key1保持引用,所以t的key1字段也会被删除。




3.三种形式的弱引用

对于弱引用table,其实有三种形式:

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执行垃圾回收的时候,并不一定是立刻生效的。
我们刚刚只是为了测试,而强制执行了垃圾回收。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值