Lua查找表元素过程(元表、__index方法是如何工作的)
近日开始研究Lua,在元表的使用上照猫画虎地搞了两下,实现了“面向对象”,但究其本质却略有不解,后咨询牛哥得解,特此记录。
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方法是一个函数,则返回该函数的返回值
转自:http://blog.csdn.net/xocoder/article/details/9028347
Lua查找表元素过程(元表、__index方法是如何工作的)的更多相关文章
- 【游戏开发】小白学Lua——从Lua查找表元素的过程看元表、元方法
引言 在上篇博客中,我们简单地学习了一下Lua的基本语法.其实在Lua中有一个还有一个叫元表的概念,不得不着重地探讨一下.元表在实际地开发中,也是会被极大程度地所使用到.本篇博客,就让我们从Lua查找 ...
- jquery 查找子元素的几种方法
<div class="tm-clear tb-hidden tm_brandAttr" id="J_BrandAttr" style="dis ...
- 算法与数据结构(九) 查找表的顺序查找、折半查找、插值查找以及Fibonacci查找
今天这篇博客就聊聊几种常见的查找算法,当然本篇博客只是涉及了部分查找算法,接下来的几篇博客中都将会介绍关于查找的相关内容.本篇博客主要介绍查找表的顺序查找.折半查找.插值查找以及Fibonacci查找 ...
- jquery查找父元素、子元素(个人经验总结)
使用js或者jquery查找父元素.子元素经常遇到.可是用起来总容易混淆,这里统一总结了一下,以后用起来相信会方便好多 这里jquery向上查找父元素 用到的方法:closest() parents( ...
- lua中查询表元素规则(__index)解析
阅读文章后用一个流程图来总结__index的规则用法 总结一下Lua查找一个表元素时的规则,其实就是如下3个步骤: 1.在表中查找,如果找到,返回该元素,找不到则继续 2.判断该表是否有元表,如果没有 ...
- 【quick-cocos2d-x】Lua 面向对象(OOP)编程与元表元方法
版权声明:本文为博主原创文章,转载请注明出处. 面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物. 早期的计算机编程是基于面向过程的方法,通过设计一个算法就可以解决当时 ...
- sap透明表、结构、簇介绍以及查找表方法
sap透明表.结构.簇介绍以及查找表方法 一些人在写开发功能说明书的时候不知道如何去找屏幕字段对应的透明表,下面我来介绍一个比较有效的方法:首先简单介绍一下概念:在SAP中的表的种类有以下三种:Tra ...
- JS数组常用函数以及查找数组中是否有重复元素的三种常用方法
阅读目录: DS01:常用的查找数组中是否有重复元素的三种方法 DS02:常用的JS函数集锦 DS01.常用的查找数组中是否有重复元素的三种方法 1. var ary = new Array(&qu ...
- 利用Xilinx中的ROM构造查找表来计算sin和cos的方法探讨
1.使用matlab制作.coe文件 查找表的构造 构造256点的正余弦表 exp(-j*2*pi*(0:255)/256),分别得到 cos和sin的查找表 matlab代码: 求sin fid = ...
随机推荐
- Dynamo分布式系统——「RWN」协议解决多备份数据如何读写来保证数据一致性,而「向量时钟」来保证当读取到多个备份数据的时候,如何判断哪些数据是最新的这种情况
转自:http://blog.jqian.net/post/dynamo.html Dynamo是Amazon开发的一款高可用的分布式KV系统,已经在Amazon商店的后端存储有很成熟的应用.它的特点 ...
- [转]MYSQL高可用方案探究(总结)
前言 http://blog.chinaunix.net/uid-20639775-id-3337432.htmlLvs+Keepalived+Mysql单点写入主主同步高可用方案 http://bl ...
- POJ2774 (后缀数组)
#include<cstdio> #include<cstring> using namespace std; ],b[]; ],x[],wv[],ws[],h[],rank[ ...
- string类实现(C++)
class CMyString { friend std::ostream& operator<<( std::ostream& os, const CMyString&a ...
- 输入任意一个字符串,如:“abDEe23dJfd343dPOddfe4CdD5ccv!23rr”。取出该字符串中所有的字母。顺序不能改变!并把大写字母变成小写,小写字母变成大写!
package lovo.Linyoujia; import java.util.Scanner; public class Java { @param args public static void ...
- CSS表达式
一直以来我们被教育说CSS Expression是个坏东西,很影响性能,应该禁止使用,但是如果仔细想想CSS表达式影响性能的原因,规避掉影响性能的写法,CSS表达式还是能给我们带来一些惊喜的.CSS表 ...
- CentOS 6.6编译安装Nginx1.6.2+MySQL5.6.21+PHP5.6.3
http://www.osyunwei.com/archives/8867.html 一.配置防火墙,开启80端口.3306端口 vi /etc/sysconfig/iptables #编辑防火墙配置 ...
- sqlserver 2008 孤立用户解决方法
从别一台服务器上得到一个数据库备份.还原到本地,数据库中的用户无法登录,也就是联机帮助中说的还原备份可能产生的孤立用户问题. 一.新建一个 MyDataBase 数据库 二.把备份文件放到 C 盘根目 ...
- Object类clone方法的自我理解
网上搜帖: clone()是java.lang.Object类的protected方法,实现clone方法: 1)类自身需要实现Cloneable接口 2)需重写clone()方法,最好设置修饰符mo ...
- Go语言http包Form解析之坑
最近正在用Go语言做一个项目,今天在用http包读取客户端发过来的POST数据时遇到了一点小麻烦,就下面这段代码,死活读不到数据: { var body []byte nRead, err := r. ...