Metatable让我从心认知了Lua(相知篇)
自从在公司和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(相知篇)的更多相关文章
- Mac下cocos2dx3.1用Cocos IDE写的Lua binding篇01
本人Lua新手,写着玩玩. 新建一个模版project. 一.改动main.lua require "Cocos2d" require "Cocos2dConstants ...
- Lua的元表(metatable)
metatable允许我们改变table的行为 > Lua中的每一个表都可以有metatable(后面我们将看到userdata也有Metatable) > Lua默认创建一个不带meta ...
- Lua中的metatable详解
转自:http://www.jb51.net/article/56690.htm Lua 中 metatable 是一个普通的 table,但其主要有以下几个功能: 1.定义算术操作符和关系操作符的行 ...
- <转> lua: userdata的metatable使用
1 如何封装c++的指针 对于c++对象的lua包装,我们可以使用 template<typename T> struct luaUserdataWrapper { luaUserdat ...
- lua实现私有函数
本文是原创文章,如需转载,请注明文章出处 要用lua实现私有函数,关键就是使用metatable的特性来实现. Test.lua: local v = {};v.x = 100;v.y = 200; ...
- Lua 与 Redis
Lua 与 Redis 标签: Java与NoSQL 从 2.6版本 起, Redis 开始支持 Lua 脚本 让开发者自己扩展 Redis - 案例-实现访问频率限制: 实现访问者 $ip 在一定的 ...
- Metatable和Metamethod
Metatable和Metamethod是用来干啥的?它们可以使得表a和b的表达式“a + b”变得有意义,其中metatable使两个不相关的表a和b之间可以进行操作,而操作的具体行为比如说&quo ...
- Metatable和Metamethod(转)
Metatable和Metamethod是用来干啥的?它们可以使得表a和b的表达式“a + b”变得有意义,其中metatable使两个不相关的表a和b之间可以进行操作,而操作的具体行为比如说&quo ...
- Lua语言模型 与 Redis应用
Lua语言模型 与 Redis应用 标签: Java与NoSQL 从 2.6版本 起, Redis 开始支持 Lua 脚本 让开发者自己扩展 Redis. 本篇博客主要介绍了 Lua 语言不一样的设计 ...
随机推荐
- ADO.Net(五)——实战:对战游戏
对战游戏 要求: 自建数据表(例如:数据表包含:代号,姓名,性别,血量,攻击力,防御力,命中,闪避,等级等字段) 需要通过程序向数据表添加人员 添加的时候,根据用户输入的名字,自动计算生成相应的血量. ...
- php5.3新特性 之 mysql native driver(mysqlnd)
概述 本文主要写给sa看的.码农就不用看了. mysql native driver(mysqlnd) 自从php5.3.0开始成为官方源代码的一部分, 用来取代传统的mysql client lib ...
- 深入理解Nginx之调试优化技巧
在开发过程中,我们经常会碰到段错误等异常,这时我们需要有相应的机制来进行调试,特别是服务提供在线上时,面对大量的日志信息,合理的调试处理机制对于开发来说是一件非常重要的事情,幸好Nginx本身提供了很 ...
- 【mysql】高可用集群之MMM
一.复制的常用拓扑结构 复制的体系结构有以下一些基本原则: (1) 每个slave只能有一个master: (2) 每个slave只能有一个唯一的服务器ID: (3) 每个maste ...
- 烂泥:CentOS6.5挂载windows共享文件夹
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 由于工作需要,需要把本机的文件夹共享出去,然后让CentOS服务器临时使用下. 服务器使用的是CentOS系统,而本机使用的win7系统.考虑到是临时使 ...
- UDT中的epoll
epoll 是为处理大量句柄而改进的poll,在UDT中也有支持.UDT使用了内核提供的epoll,主要是epoll_create,epoll_wait,epoll_ctl,UDT定义了CEPollD ...
- ctargs使用
ctargs为源码的变量/对象.结构体/类.函数/接口.宏等产生索引文件,以便快速定位.目前支持41种语言,这里仅以C/C++为例:ctags可以产生c/c++语言所有类型的索引文件,具体如下: -& ...
- CentOS 6.3下rsync服务器的安装与配置
一.rsync 简介 Rsync(remote synchronize)是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件,也可以使用 Rsync 同步本地硬盘中的不同目录. Rsy ...
- OpenXml入门
一. OpenXml简介: Open XML标准的简单介绍:Ecma Office Open XML(“Open XML”)是针对字处理文档.演示文稿和电子表格的国际化开放标准,可免费供多个应用程序在 ...
- SQL主外键和子查询
主键 数据库主键是指表中一个列或列的组合,其值能唯一地标识表中的每一行.这样的一列或多列称为表的主键,通过它可强制表的实体完整性.当创建或更改表时可通过定义 PRIMARY KEY约束来创建主键.一个 ...