【Lua】Lua中__index与元表(转)
转载于:http://blog.csdn.net/xocoder/article/details/9028347
Lua的表本质其实是个类似HashMap的东西,其元素是很多的Key-Value对,如果尝试访问了一个表中并不存在的元素时,就会触发Lua的一套查找机制,也是凭借这个机制,才能够实现“面向对象”的。
举例说明:
- tempTable = {}
- print(tempTable.memberA) --这里试图打印tempTable并不存在的成员memberA
执行结果:nil
输出为nil的原因很简单,tempTable中并没有memberA这个成员,这符合我们平时对HashMap的认知。但对于Lua表,如果tempTable有元表,情况就不同了。
什么是元表:
我的理解中,元表像是一个备用查找表,说白了假设表A的元表是B,那么如果在A中找不到的东西就会尝试在B中去找。
__index元方法:
按照之前的说法,如果A的元表是B,那么如果访问了一个A中不存在的成员,就会访问查找B中有没有这个成员。这个过程大体是这样,但却不完全是这样,实际上,即使将A的元表设置为B,而且B中也确实有这个成员,返回结果仍然会是nil,原因就是B的__index元方法没有赋值。按照我的理解,__index方法是用来确定一个表在被作为元表时的查找方法。这么说有点绕。所以:
举个例子:)
- father = {
- house=1
- }
- son = {
- car=1
- }
- setmetatable(son, father) --把son的metatable设置为father
- print(son.house)
输出的结果是nil,但如果把代码改为
- father = {
- house=1
- }
- father.__index = father -- 把father的__index方法指向自己
- son = {
- car=1
- }
- setmetatable(son, father)
- print(son.house)
输出的结果为1,符合预期
这样一来,结合上例,来解释__index元方法的含义:
在上述例子中,访问son.house时,son中没有house这个成员,但Lua接着发现son有元表father,于是此时father被当做元表来查找,此时,Lua并不是直接在father中找名为house的成员,而是调用father的__index方法,如果__index方法为nil,则返回nil,如果是一个表(上例中father的__index方法等于自己,就是这种情况),那么就到__index方法所指的这个表中查找名为house的成员,于是,最终找到了house成员。
注:__index方法除了可以是一个表,还可以是一个函数,如果是一个函数,__index方法被调用时将返回该函数的返回值。
到这里,总结一下Lua查找一个表元素时的规则,其实就是如下3个步骤:
1.在表中查找,如果找到,返回该元素,找不到则继续
2.判断该表是否有元表,如果没有元表,返回nil,有元表则继续
3.判断元表有没有__index方法,如果__index方法为nil,则返回nil;如果__index方法是一个表,则重复1、2、3;如果__index方法是一个函数,则返回该函数的返回值
【Lua】Lua中__index与元表(转)的更多相关文章
- 对lua继承中self.__index = self的释疑
首先看看从lua表中查找一个键时的流程: -- 当从表t中查找键k时,lua处理如下: -- 1.t中是否有k,有则直接返回值,否则第2步 -- 2.t是否有元表, 无则返回nil, 有则第3步 -- ...
- Lua语言中的__index,__newindex,rawget和rawset
转自:http://blog.csdn.net/wangbin_jxust/article/details/12108189 在谈及Lua中的__index,__newindex,rawget和raw ...
- Lua中__index和__newindex实践
[具有默认值的table] 我们都知道,table中的任何字段的默认值都是nil,但是通过元表,我们可以很容易的修改这一规定,代码如下: function setDefault(tb, default ...
- 【openresty】向lua代码中传递参数
前面介绍FormInputNginxModule模块时,明白了openresty如何获取post提交的数据. 然后,如果需要通过lua处理这些数据,需要把数据作为参数传递到lua中,lua获取了这些数 ...
- 在lua脚本中使用我们自定义的精灵类
首先创建cocos2dx-lua项目,然后在项目中添加我们的自定义精灵类:这里Himi类名为:HSprite // // HSprite.h // cocos2dx_lua_tests_by_Himi ...
- [译] Closures in Lua - Lua中的闭包
原文:(PDF) . 摘要 一等(first-class)函数是一种非常强大的语言结构,并且是函数式语言的基础特性.少数过程式语言由于其基于栈的实现,也支持一等函数.本文讨论了Lua 5.x用于实现一 ...
- 理解lua 语言中的点、冒号与self
转载自: http://blog.csdn.net/wangbin_jxust/article/details/12170233 lua编程中,经常遇到函数的定义和调用,有时候用点号调用,有时候用冒号 ...
- Win32下 Qt与Lua交互使用(四):在Lua脚本中自由执行Qt类中的函数
话接上篇.通过前几篇博客,我们实现在Lua脚本中执行Qt类中函数的方法,以及在Lua脚本中连接Qt对象的信号与槽. 但是,我们也能发现,如果希望在Lua脚本中执行Qt类的函数,就必须绑定一个真正实现功 ...
- Win32下 Qt与Lua交互使用(三):在Lua脚本中connect Qt 对象
话接上文.笔者为了方便使用Lua,自己编写了一个Lua的类.主要代码如下: QLua.h #ifndef QLUA_H #define QLUA_H // own #include "inc ...
随机推荐
- Redis源码研究--字典
计划每天花1小时学习Redis 源码.在博客上做个记录. --------6月18日----------- redis的字典dict主要涉及几个数据结构, dictEntry:具体的k-v链表结点 d ...
- input元素的padding border margin的区别
padding内(不包含padding)的部分才是可输入部分,也是width和height标明的区域.padding的部分加上width和height部分是background的部分.padding的 ...
- ViewPager中GridView问题
GridView 嵌套在ViewPager中问题. 1. GridView属性设置无法显示. 正常显示方式 <GridView android:padding="8dip" ...
- Laravel 5 基础(七)- Eloquent (laravel 的ORM)
我们来生成第一个模型 php artisan make:model Article #输出 Model created successfully. Created Migration: 2015_03 ...
- 【转】Delphi的消息对话框
Delphi的消息对话框 输入输出inputBox()函数MessageBox()ShowMessage 对话框是Windows操作系统中程序与用户沟通的一种常见的交互方式,对话框可以向用户提供当前程 ...
- android 模拟按键事件
模拟按键事件可以提高代码的复用性,比如在一个edittext的回车事件里做的一些处理 在该edittext的另一个输入要做相同的处理时,模拟按键事件就非常方便了. 代码很简单,直接上代码: new T ...
- Java4Android
变量 在计算机中存储信息需要声明变量的位置和所需的内存空间 boolean true false char ASCII字符集 计算机中所有数据都使用二进制表示 例如:a,b,c 适用七位二进制数进行表 ...
- 文件系统 第八次迭代 VFS相关说明
麻烦访问evernote链接 http://www.evernote.com/shard/s133/sh/53e5b5ac-1192-4910-8bd5-6886218562af/59516c32a5 ...
- object sender ,EventArs e
引用:http://blog.csdn.net/kongbai308416350/article/details/4233786 说的通俗一些,就是: 有一个叫做EventHandler 的家伙,他会 ...
- angularjs+nodejs+mongodb三件套
说实话,自己对于web前段的认识并不是太深入,但是因为项目的需要,所以有的时候肯定会需要接触到web前段的知识点.说到web前端想必大家肯定会想到css+js+html,的确web前端的工作,从某总角 ...