Lua中metatable和__index的联系
Lua中metatable和__index的联系
可以参考 http://blog.csdn.net/xenyinzen/article/details/3536708
来源 http://blog.csdn.net/fishe_r/article/details/77530369
最近学习lua今天突然对metatable和__index之间的关系有点不清楚,上网查了下加深了对metatable的理解,记录一下
还是用代码来解释,下面有图解,metatable和__index主要用于继承相关,有两种方式:
test.lua
local test = {}
function test:new()
self.__index = self
return setmetable({}, self)
end
function test:say()
print("111")
end
local t1 = test:new()
t1.say()
local t2 = t1:new()
t2.say()
return test
test2.lua
local test2 = {}
test2.__index = test2
function test2:new()
return setmetatable({}, self) -- 这里的self 替换成 test2 试试
end
function test2:say()
print("222")
end
local 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()
...
end
function 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详解
转自:http://www.jb51.net/article/56690.htm Lua 中 metatable 是一个普通的 table,但其主要有以下几个功能: 1.定义算术操作符和关系操作符的行 ...
- lua学习:lua中“类”的实现
在之前的面试遇到考用lua实现类的题目.现在就补补这块知识点. 我们都知道Lua中的table是一个对象.拥有状态,拥有self,拥有独立于创建者和创建地的生命周期. 一个类就是一个创建对象的模具.L ...
- lua 14 metatable (类似操作符重载)
转自:http://www.runoob.com/lua/lua-metatables.html 感性认识: “Lua中Metatable这个概念, 国内将他翻译为元表. 元表为重定义Lua中任意一个 ...
- 【Lua】Lua中__index与元表(转)
转载于:http://blog.csdn.net/xocoder/article/details/9028347 Lua的表本质其实是个类似HashMap的东西,其元素是很多的Key-Value对,如 ...
- lua中的metatable和metamethod
--元表和元方法给lua里的值设定一些操作,让我们可以对这些操作自定义 --创建一个新的table变量时,它是不存在元表的 --在Lua中,只能设置table的元表,其他类型的值的元表,只能通过C代码 ...
- Lua中的元表(metatable)、元方法(metamethod)详解
在第一次看见这两样东西的时候,可能会觉得它很深奥,但其实很好理解,虽然实际上它可能真的很深奥.(小若:停!滚粗.) 1.知道为什么1 + 1 = 2吗? 为什么在Lua中,1+1会等于2呢?(小若:难 ...
- lua元表Metatable
Lua 中的每个值都可以用一个 metatable. 这个 metatable 就是一个原始的 Lua table , 它用来定义原始值在特定操作下的行为. 你可以通过在 metatable 中的特定 ...
- lua 中的面向对象
lua 是一种脚步语言,语言本身并不具备面向对象的特性. 但是我们依然可以利用语言的特性,模拟出面向对象的特性. 面向对象的特性通常会具备:封装,继承,多态的特性,如何在lua中实现这些特性,最主要的 ...
- Lua中的weak表——weak table
弱表(weak table)是一个很有意思的东西,像C++/Java等语言是没有的.弱表的定义是:A weak table is a table whose elements are weak ref ...
随机推荐
- Dynamic web module 版本之间的区别
Servlet 3十二月2009开发平台标准版6,6可插性,易于开发,异步ser vlet,安全,文件上传Servlet 2.5九月2005开发平台标准版5,5需要平台标准版5,支持注释Servlet ...
- multimap 和priority_queue详解
上一期是关于STL和并查集结合的例题,也附了STL中部分容器的使用摘要,由于是从网上东拼西凑的,感觉有的关键点还是没解释清楚,现在从其中摘出两个容器,用例题对它们的用法进行进一步解释. 以下是例题的介 ...
- angular 学习笔记
每天进步一点点,学习笔记 笔记来自 angular权威指南 如果想要屏蔽浏览器对表单的默认验证行为,可以在表单元素上添加 novalidate 标记. 而按钮标签则完全忽略 hr e f 属性,并不 ...
- filter的两种使用方法
1. 在模板中使用filter 我们可以直接在{{}}中使用filter,跟在表达式后面用 | 分割,语法如下: {{ expression | filter }} 也可以多个filter连用,上一个 ...
- 一个基于Asp.net MVC的博客类网站开源了!
背景说明: 大学时毕业设计作品,一直闲置在硬盘了,倒想着不如开源出来,也许会对一些人有帮助呢,而且个人觉得这个网站做得还是不错了,毕竟是花了不少心思,希望对你有所帮助. github地址:https: ...
- 【转】NoClassDefFoundError和ClassNotFoundException
调试Hadoop源码时,一运行就报这个错误,后来发现是maven配置时,scope配置的问题, MAVEN Scope使用 相关链接:http://acooly.iteye.com/blog/178 ...
- H5音频处理的一些小知识
前 言 LiuDaP 十一过后,小编要做一个关于音乐播放器的项目,要用到大量H5音频处理的内容,于是在十月一日国庆黄金周闲暇之际,自己学习了一下H5音频的相关内容.虽然自学的没有那么深入,但是对 ...
- windows访问控制列表 --ACL(Access Control List)
1.定义 ACL是一个windows中的表示用户(组)权限的列表. Access Control List(ACL) Access Control Entry(ACE) ... 2.分类 ACL分为两 ...
- wxPython中按钮、文本控件的简单运用
本节学习图形用户界面 ------------------------ 本节介绍如何创建python程序的图形用户界面(GUI),也就是那些带有按钮和文本框的窗口.这里介绍wxPython : 下载地 ...
- c# 【MVC】WebApi开发实例
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using S ...