自从在公司和Lua第一次相遇之后,我的IT生涯从此也开启了另一个新篇。。。

起初并没有和Lua产生相遇时的那种电石火花般的怦然心动。。。但。。。

说实话虽然我的心没有因此触动但至少也不排斥。。。因为公司的需要,我就

必须去爱上她,所以大家都懂得。。。我们开始了正式的"交往"咯^_^ ^_^ ^_^

  在与Lua"交往"的这段时光里,你会发现自己已经渐渐的被Lua所吸引。。。

她虽然没有令你一见钟情的"容貌",但却有着你喜欢的那种日久生情的"气质"。。。

  废话就不多说了、、、咱直接进入主题吧。。。细说Metatable(元表)的那点事。。。

如果你想对lua中table的结构进行变化。。。那么就用lua的元表就来帮你实现。。。请看下面详解。。。

==>这次的博文新增了导航栏,,,方便博友们上下滚动网页来回切换视角、也别忽视了右侧的浮动目录。。。

一、 __index元方法

__index元方法:用于查看表中元素是否存在,如果不存在返回结果为nil;如果存在,则由__index返回结果

  存在__index元方法:

myTable = setmetatable({key1 = "lua", key3 = "java"}, {
__index = function(myTable, key)
if key == "key2" then
  return "key2 is nil"
  else
   return myTable[key]
  end
end
})

  程序运行输出:

---------- 新建程序 ----------
lua key2 is nil java 输出完成 (耗时 秒) - 正常终止

  不存在__index元方法:

myTable = {key1 = "lua", key3 = "java"}

print(myTable.key1, myTable.key2, myTable.key3)

  程序运行输出:

---------- 新建程序 ----------
lua nil java 输出完成 (耗时 秒) - 正常终止

二、__newindex元方法

__newindex元方法:用来对表进行更新。给一个表的缺少的索引赋值时,解释器就会查找是否存在__newindex元方法,

          如果存在则调用这个函数而不进行赋值操作;不存在则进行赋值操作。(只针对表中不存在的索引有效)

  存在__newindex元方法:

myTable = {key1 = "lua", key3 = "java"}

setmetatable(myTable, {
__newindex = function(myTable, key, value)
   print(key .. " is not exists in myTable " .. value)
end
}) myTable.key1 = "hello"
myTable.key2 = "world" --给key2赋值会执行__newindex函数 print(myTable.key1, myTable.key2)

  程序运行输出:

---------- 新建程序 ----------
key2 is not exists in myTable world
hello nil 输出完成 (耗时 秒) - 正常终止

  解释说明:  在给myTable表的key1索引赋值时,因为key1索引是myTable中已经存在的索引,

       所以只进行赋值而不调用__newindex元方法;

         在给myTable表的key2索引赋值时,因为key2索引在myTable表中不存在,解释器就会查找

       是否存在__newindex元方法,又由于存在__newindex元方法,所以调用了__newindex元方法

       而不对key2索引进行赋值;若不存在__newindex方法,则对新索引进行赋值操作。 

  不存在__newindex元方法:

myTable = {key1 = "lua", key3 = "java"}

myTable.key1 = "hello"
myTable.key2 = "world" print(myTable.key1, myTable.key2)

  程序运行输出:

---------- 新建程序 ----------
hello world 输出完成 (耗时 秒) - 正常终止

三、__add元方法

__add元方法:用于操作表与表之间的关联事件。当两张表之间用到字符'+'时,解释器就会去查找是否存在__add元方法,

        若存在__add元方法,则调用__add元方法,否则程序执行报错。(对应的运算符:'+')

  存在__add元方法:

myTable = {, , }
newTable = {, , } setmetatable(myTable, {
__add = function(myTable, newTable)
   print("add") --此处用来处理相关事件,可遍历两个对其中的元素进行累加求和并返回
  return "already add"
end
}) print(myTable + newTable)

  程序运行输出:

---------- 新建程序 ----------
add
already add 输出完成 (耗时 秒) - 正常终止

四、__sub元方法

__sub元方法:用法类似于__add元方法。(对应的运算符:'-')

myTable = {, , }
newTable = {, , } setmetatable(myTable, {  
__sub = function(myTable, newTable)  --__sub可替换__mul/__div/__mod/__unm/__concat/__eq/__lt/__le
  print("subtract") --处理相关事件
  return "already subtract"
end
}) print(myTable - newTable)  --此处要替换为相应的对应运算符

  程序运行输出:

---------- 新建程序 ----------
subtract
already subtract 输出完成 (耗时 秒) - 正常终止

类似于__add和__sub元方法的还有:

  __mul元方法:对应运算符'*'

  __div元方法:对应运算符'/'

  __mod元方法:对应运算符'%'

  __pow元方法:对应运算符'^'

  __unm元方法:对应运算符'-',此处的运算符不是减号,是代表负数

  __concat元方法:对应运算符'..'

  __eq元方法:对应运算符'=='

  __lt元方法:对应运算符'<'

  __le元方法:对应运算符'<='

最后再拿__unm元方法举例:

myTable = {, , }

setmetatable(myTable, {
__unm = function(myTable)
   print("nagative") --处理相关事件
  return "already nagative"
end
}) print(-myTable)

  程序运行输出:

---------- 新建程序 ----------
nagative
already nagative 输出完成 (耗时 秒) - 正常终止

五、__call元方法

__call元方法:用于表变量调用一个参数时调用__call元方法。

myTable = {, , }
num = setmetatable(myTable, {
__call = function(myTable, param) --此处的param可替换其他类型的变量
   print("call " .. param) --处理相关事件
   return "already call"
end
}) print(myTable(num))  --myTable调用num变量

  程序运行输出:

---------- 新建程序 ----------
call
already call 输出完成 (耗时 秒) - 正常终止

六、__tostring元方法

__tostring元方法:用于修改表的输出行为。【类似于JAVA中类中重写了toString()方法,用于修改对象的输出行为】

--写法一
myTable = {, , } setmetatable(myTable, {
__tostring = function(myTable) --注意__tostring是两个_开头
  local sum =
  for _,v in pairs(myTable) do  --注意此处的_字符也表示变量,可用字母k或其他字母替代
   sum = sum + v
   end
   return ("表元素之和=" .. sum)
end
}) print(myTable) --写法二
myTable = {, , } mt = {} mt.__tostring = function(myTable)
local sum =
for _,v in pairs(myTable) do
  sum = sum + v
end
return ("表元素之和=" .. sum)
end setmetatable(myTable, mt) print(myTable)

  循环遍历部分也可修改为:

for index = ,#myTable do
sum = sum + myTable[index]
end

  程序运行输出:

---------- 新建程序 ----------
表元素之和= 输出完成 (耗时 秒) - 正常终止

  

  明天就要去出差了、、、在这之前。。把我和Lua的相知篇赶出来和大家分享。。。

希望多少能够给大家带来一点帮助。。。

  如果博友们看出了我在认知Lua的过程中,,,对Lua有误解。。。说出来、、、

我们一起探讨探!!!  *^_^*

  如果觉得此博文写的还行、看着还不错的博友们。。。移动起你们的鼠标。。。轻轻一点推荐

把祝福传给我们。。。让知识传递下去。。。 *^_^* *^_^* *^_^*

  有想关注和阅读我最新博文的博友们。。。就关注走一波咯。。。

   

       喜欢和爱是有差别的。。。

     喜欢是让自己高兴,,,爱却是让对方幸福。。。

    喜欢是一种占有,,,爱更多的是一种付出,一种责任。。。

  想要看起来毫不费力,,,在这之前你就必须全力以赴。。。

Metatable让我从心认知了Lua(相知篇)的更多相关文章

  1. Mac下cocos2dx3.1用Cocos IDE写的Lua binding篇01

    本人Lua新手,写着玩玩. 新建一个模版project. 一.改动main.lua require "Cocos2d" require "Cocos2dConstants ...

  2. Lua的元表(metatable)

    metatable允许我们改变table的行为 > Lua中的每一个表都可以有metatable(后面我们将看到userdata也有Metatable) > Lua默认创建一个不带meta ...

  3. Lua中的metatable详解

    转自:http://www.jb51.net/article/56690.htm Lua 中 metatable 是一个普通的 table,但其主要有以下几个功能: 1.定义算术操作符和关系操作符的行 ...

  4. <转> lua: userdata的metatable使用

    1 如何封装c++的指针 对于c++对象的lua包装,我们可以使用 template<typename T> struct luaUserdataWrapper {  luaUserdat ...

  5. lua实现私有函数

    本文是原创文章,如需转载,请注明文章出处 要用lua实现私有函数,关键就是使用metatable的特性来实现. Test.lua: local v = {};v.x = 100;v.y = 200; ...

  6. Lua 与 Redis

    Lua 与 Redis 标签: Java与NoSQL 从 2.6版本 起, Redis 开始支持 Lua 脚本 让开发者自己扩展 Redis - 案例-实现访问频率限制: 实现访问者 $ip 在一定的 ...

  7. Metatable和Metamethod

    Metatable和Metamethod是用来干啥的?它们可以使得表a和b的表达式“a + b”变得有意义,其中metatable使两个不相关的表a和b之间可以进行操作,而操作的具体行为比如说&quo ...

  8. Metatable和Metamethod(转)

    Metatable和Metamethod是用来干啥的?它们可以使得表a和b的表达式“a + b”变得有意义,其中metatable使两个不相关的表a和b之间可以进行操作,而操作的具体行为比如说&quo ...

  9. Lua语言模型 与 Redis应用

    Lua语言模型 与 Redis应用 标签: Java与NoSQL 从 2.6版本 起, Redis 开始支持 Lua 脚本 让开发者自己扩展 Redis. 本篇博客主要介绍了 Lua 语言不一样的设计 ...

随机推荐

  1. Javascript之旅——第十一站:原型也不好理解?

    写到这篇,我的js系列也快接近尾声了,所以这个系列不会遗留js来实现面向对象的核心——原型,有些人说原型不好理解,其实嘛,要想系统 的理解原型,最便捷的方式就是看看经典的书,少看些博客,博客这东西只是 ...

  2. PHP代码规范

    PHP编码规范 1. 标识符命名规范 标识符的命名力求做到统一.达意和简洁. 1.1 统一 统一是指,对于同一个概念,在程序中用同一种表示方法,比如对于供应商,既可以用supplier,也可以用pro ...

  3. 好久没有写博客了,发现Live Writer也更新了

    最近由于工作变动,工作内容和心态也有所变化,所以很久没有写博客了,而且我的开源项目深蓝词库转换也很近没有更新了.今天打开LiveWriter发现居然有新版本,于是果断更新.现在新的LiveWriter ...

  4. 今天说一下 Group by 这个东西

    group by 这个关键字,这个语句太平凡了~基本上只要有报表的地方,就会有它的身影. 常规用法就是 INSERT INTO #TypeValue ( TypeID, Col2 ) , N , N ...

  5. Linux磁盘管理之设备文件详解04

    Linux一切接文件,除了普通文件和目录文件,还包括一些其它的特殊文件:块设备文件.字符设备文件.套接字文件.链接文件等.今天这里主要说一下常见的块设备文件和字符设备文件,这2类是最常见的设备文件类. ...

  6. MMORPG大型游戏设计与开发(客户端架构 part2 of vegine)

    一个好的接口是尽可能让更多实用的方法进行整理封装,要记住的是不常用的方法和类最好不好封装到接口中,因为那样会造成本身的困惑.基础模块中并没有太多封装,甚至连一个类的封装也没有,而是一些很常用的工具方法 ...

  7. 阻塞通信之Socket编程

    Socket通信,主要是基于TCP协议的通信.本文从Socket通信(代码实现).多线程并发.以及TCP协议相关原理方面 介绍 阻塞Socket通信一些知识. 本文从服务器端的视角,以“Echo Se ...

  8. HDU2191悼念512汶川大地震遇难同胞——珍惜现在,感恩生活[多重背包]

    悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  9. openjudge2989糖果[DP 01背包可行性]

    openjudge2989糖果 总时间限制:  1000ms 内存限制:  65536kB 描述 由于在维护世界和平的事务中做出巨大贡献,Dzx被赠予糖果公司2010年5月23日当天无限量糖果免费优惠 ...

  10. Java—FileOperator

    //基本用法 JFileChooser jfc = new JFileChooser(); int result = jfc.showOpenDialog(this); if(result != JF ...