Lua 学习笔记——metatable和__index
来源:互联网 发布:知乎 教育培训 编辑:程序博客网 时间:2024/05/22 06:14
最近学习lua今天突然对metatable和__index之间的关系有点不清楚,上网查了下加深了对metatable的理解,记录一下
还是用代码来解释,下面有图解,metatable和__index主要用于继承相关,有两种方式:
test.lua
local test = {}function test:new() self.__index = self return setmetable({}, self)endfunction test:say() print("111")endlocal t1 = test:new()t1.say()local t2 = t1:new()t2.say()return test
test2.lua
local test2 = {}test2.__index = test2function test2:new() return setmetatable({}, self) -- 这里的self 替换成 test2 试试endfunction test2:say() print("222")endlocal t3 = test2:new()t3.say()local t4 = t3:new()t4.say() -- 这一步会报错return test2
上面的代码test.lua中t1,t2都能访问到new和say方法,但是test2中只有直接通过test2:new()生成的对象(t3)才能访问new和say方法,而通过test2:new()生成的子对象生成的对象(t4)则访问不到new和say方法
要解释上述问题,首先要知道lua从table中查找一个key时的流程,当从表t中查找k时:
- t中是否有k,有则返回,无则第2步
- t是否有metatable,无则返回nil,有则第3步
- t的metatable中是否有__index方法,无则返回nil,有则查找 __index对应的table或者方法
所以我们一步步分析test.lua中的代码:
local test = {}function test:new() ...endfunction test:say() ...end
这一句就是创建了一个table,我们用方块表示table则就是下面这样:
接下来实例化一个对象:
local t1 = test:new()
这里调用test:new(),相当于test.new(test),函数中的self为test,所以这一步改变了test表,结果用图表示为:
图中椭圆表示__index函数,__index指向test自身,可以看到这时test表和上面不一样,而t1是一个新生成的表,这个表的metable为test,但是t1本身没有其他内容
再来看最后一步
local t2 = t1:new()
此时结果为:
这一步new函数中的的self为t1,所以最后改变了t1的__index指向t1,生成新的表t2的metatable为t1,由于t1和t2都有metatable并且metatable中都有__index方法所以都可以访问test中的new和say方法,即使它们自身没有这两个方法
再来看test2.lua中有什么不同,同理按照上面的分析有三个图,就不一一解释了
唯一不同的地方就在于__index方法的设置,在test2.lua中 __index只在test2表中设置,在继承过程中,并没有设置对应的__index方法,所以t3可以访问到new和say,但是t4则不可以
不过由此引出我一个问题,我们可以看到lua中查找不存在的k时,最终起作用的其实是__index方法,类似的还有操作符元方法等,但是却要先找metatable,然后找metatable里面的这些元方法,metatable在这里是相当于一个代理一样的作用,那么为什么不能直接在自身的表中设置,为什么要有metatable这个中间表??
猜想一:可能是模块化的考虑也就是把这些元方法集中在一起
- 但是lua中有一个常用的用法就是 __index指向自身,上述例子就是这样,那么这个table里面本身就有元方法和自己的数据,而lua也没有说不推荐这么做,所以也不符合模块化的考虑
猜想二:可能是为了多个table方便共享同一个metatable
- 问题是直接在自身table中设置__index指向同一个metatable也可以达到这种效果
猜想三:刚刚想到如果没有metatable的话,直接用__index指向要设置的元表,那么如果我想把自身作为基类,用__index指向自身,就会陷入死循环
- 不知道是不是因为这点才引入了metatable这么一个中间代理
所以不清楚这部分的设计理念是什么,如果有知道的可以留言下
- Lua 学习笔记——metatable和__index
- Lua学习笔记五——metatable
- 0基础lua学习(十五)metatable和__index 实现的继承
- Lua metatable 与 __index方法
- 【lua metatable、__index __newindex是什么】
- lua学习笔记——元表(Metatable)
- Lua——metatable和metamethods
- 解析Lua中关于Metatable学习笔记
- lua学习笔记_metatable,__index,__newindex
- Lua笔记12 metatable 和metamethod
- LUA中的metatable笔记
- Lua笔记15 __index
- lua学习之metatable
- lua metatable/metamethod学习
- lua中metatable学习
- Lua __index和__newindex
- Lua——3.元表Metatable
- Lua笔记13 table 的__add和__index 方法
- linux下安装zookeeper
- 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是 100 的程序,并输出所有的可能性
- 黑科技-------咖啡装逼利器
- 关于 移动 电信 联通 运营商数据抓取 通话记录 京东淘宝学信网数据抓取 失信报告,网贷黑名单,央行征信报告数据抓取
- 来听听外国UX设计师的22句话
- Lua 学习笔记——metatable和__index
- mysql innodb引擎 sql优化经验总结
- 使用原生方法获取地址栏参数
- Centos7安装并配置mysql5.6
- Linux-ubuntu连接投影仪失败(分辨率不匹配)问题解决
- Hive环境搭建
- 存在多个版本的python时,如何为特定的版本安装包
- java多线程(四)wait() notify() notifyall()
- “Host is blocked because of many connection errors”问题解决