在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
这次要介绍的内容比较少,就一个——弱引用table 1.无法超越人类智慧的智能——自动内存管理的缺陷 我们都知道,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
这段代码有点复杂,智商低于250的可能会看不懂。 首先以一个table,叫做t。 然后创建一个新的table——key1,这个key1作为t的key值,给t新增了一个字段,赋值为1。 同样的,key2也作为t的一个key值。 接着,调用了collectgarbage函数,可以不管它,我们只要知道,它会让lua进行一次垃圾回收。 最后输出t的所有字段,输出结果如下: [LUA-print] key1:1 [LUA-print] key2:1
但是,已经添加到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的所有字段都不存在了。 一旦其他地方对于key值的引用取消了(设置为nil),那么,这个table里的这个字段也会被删除。 随后,又执行了key1 = nil,此时,除了t本身以外,就没有任何地方对key1保持引用,所以t的key1字段也会被删除。 3.三种形式的弱引用 对于弱引用table,其实有三种形式: 1)key值弱引用,也就是刚刚说到的情况,只要其他地方没有对key值引用,那么,table自身的这个字段也会被删除。设置方法:setmetatable(t, {__mode = “k”}); 4.结束 好了,这次的内容比较少,其实书上有蛮多关于弱引用的例子的。 |
请发表评论