(转载)【笨木头Lua专栏】基础补充22:弱引用table

这次要介绍的内容比较少,就一个——弱引用table

笨木头花心贡献,哈?花心?不,是用心~

转载请注明,原文地址:http://www.benmutou.com/archives/1808

文章来源:笨木头与游戏开发

1.无法超越人类智慧的智能——自动内存管理的缺陷

我们都知道,Lua是具备自动内存管理的,好吧,也许有些朋友不知道。

我们只管创建对象,无须删除对象(当然,对于不要的对象你需要设置一下nil值),Lua会自动删除那些被认为是垃圾的对象。

问题就出现在,什么对象才是垃圾对象,有些时候,我们很清楚某个对象是垃圾,但是,Lua却无法发现。

比如这样一个例子:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

    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

这很符合常理,也在我们的预计当中,虽然我们在给t赋值之后,key1和key2都赋值为nil了。

但是,已经添加到table中的key值是不会因此而被当做垃圾的。

换句话说,key1本身已经是nil值,但它曾经所指向的内容依然存放在t中。key2也是一样的情况。

所以我们最后还是能输出key1和key2的name字段。

2.颠覆你的认知——弱引用table

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

应该如何实现?

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

我们来看看下面的代码,和之前几乎一样,只是加了一句代码:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

    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执行垃圾回收的时候,并不一定是立刻生效的。

我们刚刚只是为了测试,而强制执行了垃圾回收。

4.结束

好了,这次的内容比较少,其实书上有蛮多关于弱引用的例子的。

关于Lua的最基础部分,到这里算是结束了。

后面的内容是一些库的介绍,以及更深入的一些内容(C和Lua间调用、自定义类型、线程、内存管理)。

接下来可能会放缓文章更新速度,因为好多库的介绍,不知道有没有必要用文章记录下来。

可能而已~

原文地址:http://www.benmutou.com/archives/1808

原文地址:https://www.cnblogs.com/wodehao0808/p/8617266.html

时间: 2024-07-31 03:41:09

(转载)【笨木头Lua专栏】基础补充22:弱引用table的相关文章

【笨木头Lua专栏】基础补充04:迭代器初探

今天学习的内容还蛮有意思的,让我兴奋了一下~ 笨木头花心贡献,哈?花心?不,是用心~ 转载请注明,原文地址: http://www.benmutou.com/archives/1714 文章来源:笨木头与游戏开发 1.迭代器 什么是迭代器?别傻了,我最讨厌的就是名词解释了,反正就是用来遍历集合的一种方式. 比如,我们最常用的pairs,如下代码: local t = {"fdsd", "445"}; for k, v in pairs(t) do print(&qu

(转载)【笨木头Lua专栏】基础补充20:面向对象——类和继承

终于来了,在Lua中的面向对象编程,相信目前学习Lua的大部分人都是为了开发手机网游吧.而且基本都是奔着脚本语言的热更新特性去的,所以全脚本开发变得十分流行. 对于普及不太广的Lua(相对于C++.Java等主流语言),需要短时间上手开发游戏,对新手而言不算简单.所以大家才更习惯于继续用面向对象思想去折腾Lua吧~ 好了,不唠叨了,我最不喜欢唠叨了.(小若:是是是,你一点都不唠叨,赶紧开讲!) 笨木头花心贡献,哈?花心?不,是用心~ 转载请注明,原文地址:http://www.benmutou.

(转载)【笨木头Lua专栏】基础补充21:面向对象——多重继承、私密性

在Lua中的多重继承和私密性可能用得比较少,也可能只是我个人用得比较少. 本来想偷懒不写这文章的,因为我今天刚买了个漂移板,连起步都还没学会啊,想多学一会. 咳咳,本着坚持不懈.负责到底的态度,我还是决定随便写几句~(小若:随便写几句是几吨意思啊?!) 笨木头花心贡献,哈?花心?不,是用心~ 转载请注明,原文地址:http://www.benmutou.com/archives/1800 文章来源:笨木头与游戏开发 1.多重继承之在多个类中查找一个字段 我发现这些高(shen)智(jing)商(

【笨木头Lua专栏】基础补充02:函数的几个特别之处

没想到距离上一篇基础补充已经过了1年多了,近期准备捡回Lua,把基础都补补,今天来聊聊Lua的函数吧~ 0.环境 我突然对Lua又大感兴趣的最主要原因是,Cocos Code IDE開始浮出水面了,它是Cocos2d-x官方出的一款专门针对Cocos2d-x+Lua或JS的IDE.试着用了,尽管不能说非常完美.但,非常值得期待. 所以,本文使用的Lua编辑器就选它了,大家就任意吧~ 笨木头花心贡献,哈?花心?不.是用心~ 转载请注明,原文地址:http://www.benmutou.com/ar

【笨木头Lua专栏】基础补充06:简单的错误处理

昨天遇到另外一位独立游戏开发者,所以多聊了一会,然后-然后就没有看书了.(小若:借口!借口!) 今天来聊聊错误处理吧,不过毕竟这只是前面的章节,书上的内容似乎有点一笔带过的味道. 没关系,简单更好~ 笨木头花心贡献,哈?花心?不,是用心~ 转载请注明,原文地址: http://www.benmutou.com/archives/1728 文章来源:笨木头与游戏开发 1.红色警报--error 我们应该能经常看到类似以下的错误信息: [LUA-print] LUA ERROR: [string "

【笨木头Lua专栏】基础补充04:for循环与迭代器的秘密

上一篇我们介绍了,可以使用for循环来完成迭代器的调用,十分简洁. 那么,具体这for循环做了什么呢?我当然没有去看源码,我只是看书而已. 资料来源于<Lua程序设计>第二版,如果这本书的内容没有错的话,那么,本篇文章理论上也不会有错~ 笨木头花心贡献,哈?花心?不,是用心~ 转载请注明,原文地址: http://www.benmutou.com/archives/1717 文章来源:笨木头与游戏开发 1.返回两个值的迭代器 pairs是能遍历table的key和value的,而我们之前写的d

【笨木头Lua专栏】基础补充05:迭代器番外篇

关于迭代器的内容, 还有一点点,不过已经无关紧要了,应该算是一种扩展吧,就一起来开开眼界好了~ 笨木头花心贡献,哈?花心?不,是用心~ 转载请注明,原文地址: http://www.benmutou.com/archives/1721 文章来源:笨木头与游戏开发 1.避免创建闭合函数 我们之前一直在说的迭代器,都是要创建闭合函数,但,大家有没有想过,有了恒定状态和控制变量之后,是不是就不需要闭合函数了? 先来回顾一下之前的迭代器函数: function dieDaiQi(t) local i =

【笨木头Lua专栏】基础补充07:协同程序初探

哎.周五晚上我都还这么努力看书.真是好孩子.(小若:不想吐槽了) 事实上我都准备rs=1&u=http%3A%2F%2Fwww%2Ebenmutou%2Ecom%2Farchives%2F1733&p=baidu&c=news&n=10&t=tpclicked3_hc&q=25013069_cpr&k=%CD%E6%D3%CE%CF%B7&k0=%B4%F2%D3%A1&kdi0=1&k1=%D7%C0%D7%D3&k

Lua 弱引用table

本文转载于:http://www.benmutou.com/archives/1808 这次要介绍的内容比较少,就一个——弱引用table 1.无法超越人类智慧的智能——自动内存管理的缺陷 我们都知道,Lua是具备自动内存管理的,好吧,也许有些朋友不知道. 我们只管创建对象,无须删除对象(当然,对于不要的对象你需要设置一下nil值),Lua会自动删除那些被认为是垃圾的对象. 问题就出现在,什么对象才是垃圾对象,有些时候,我们很清楚某个对象是垃圾,但是,Lua却无法发现. 比如这样一个例子: t