lua元表与元方法
lua中提供的元表(metatable)与元方法(metamethod)是一种非常重要的语法,metatable主要用于做一些类似于C++重载操作符式的功能。
lua中提供的元表是用于帮助lua变量完成某些非预定义功能的个性化行为,如两个table的相加,通过让两者指向同一元表并修改该元表的元方法可以实现该功能。
任何table都可以成为任何值的元表,而一组相关的table也可以共享一个元表。
一些MetaMethod:
__add(a, b) 对应表达式 a + b
__sub(a, b) 对应表达式 a - b
__mul(a, b) 对应表达式 a * b
__div(a, b) 对应表达式 a / b
__mod(a, b) 对应表达式 a % b
__pow(a, b) 对应表达式 a ^ b
__unm(a) 对应表达式 -a
__concat(a, b) 对应表达式 a .. b
__len(a) 对应表达式 #a
__eq(a, b) 对应表达式 a == b
__lt(a, b) 对应表达式 a < b
__le(a, b) 对应表达式 a <= b
__index(a, b) 对应表达式 a.b
__newindex(a, b, c) 对应表达式 a.b = c
__call(a, ...) 对应表达式 a(...)
1、算术类and关系类元方法
先看一个简单的例子:
--我们想让两个分数相加,这是一种非预定义的行为 fraction_a = {numerator=, denominator=}
fraction_b = {numerator=, denominator=}
fraction_op={} --元表 -- __add这是metatable,这是lua内建约定的
function fraction_op.__add(a,b)
res={}
res.numerator=a.numerator*b.denominator+b.numerator*a.denominator
res.denominator=a.denominator*b.denominator
return res
end --将fraction_a,fraction_b的元表设置为fraction_op
--其中setmetatable是库函数
setmetatable(fraction_a,fraction_op)
setmetatable(fraction_b,fraction_op) --调用的是fraction_op.__add()函数
fraction_c=fraction_a+fraction_b
print(fraction_c.numerator.."/"..fraction_c.denominator)
--输出结果
--26/21
再来看一个深度一点的例子,例举了算数类的元方法,关系类的元方法,库定义的元方法。
Set={} local metatable={} --元表 --根据参数列表中的值创建一个新的集合
function Set.new(a)
local set={}
--将所有由该方法创建的集合的元表都指定到metatable
setmetatable(set,metatable)
for i,v in pairs(a) do
set[v]=true
end
return set
end --计算两个集合的并集
function Set.union(a,b)
local res=Set.new{}
for i in pairs(a) do
res[i]=true
end
for i in pairs(b) do
res[i]=true
end
return res
end --计算两个集合的交集
function Set.intersect(a,b)
local res=Set.new{}
for i in pairs(a) do
res[i]=b[i]
end
return res
end --print总是调用tostring来格式化输出
--这里我们稍作修改库定义的print
function Set.tostring(a)
local t={}
for i in pairs(a) do
t[#t+]=i
end
return "{"..table.concat(t,",").."}"
end --判断a集合是否是b集合的子集
function Set.lessorequal(a,b)
for i in pairs(a) do
if not b[i] then return false end
end
return true
end --最后将重定向的元方法加入到元表中
metatable.__add=Set.union
metatable.__mul=Set.intersect
metatable.__tostring=Set.tostring
metatable.__le=Set.lessorequal
metatable.__eq=function(a,b) return a<=b and b<=a end
metatable.__lt=function(a,b) return a<=b and not (b<=a) end s1=Set.new{,,,}
s2=Set.new{,,}
s3=s1+s2
s4=s1*s2
print(s3)
print(s4)
print(+,*) --新加的方法不改变表本身具有的方法,因为传入的参数不同,只会让元方法更完善
s5=Set.new{,}
s6=Set.new{,,}
print(s5<=s6)
print(s5<s6)
print(s5==s6)
--输出结果
--{2,8,4,9,7}
--{2,4}
--7 12
--true
--true
--false
2、table访问的元方法:
算数类和关系类的元方法都为各自错误情况定义了行为,他们不会改变语言的常规行为,但lua还是提供了一种可以改变table的行为。有两种可以改变table的行为:查询table以及修改table中不存在的字段。
1)、__index元方法
当访问table中不存在的字段时,得到的结果为nil。如果我们为table定义了元方法__index,那访问的结果将由该方法决定。
Window={}
Window.prototype={x=,y=,width=,height=}
Window.mt={} --Window的元表 function Window.new(o)
setmetatable(o,Window.mt)
return o
end Window.mt.__index=function(table,key) return Window.prototype[key] end w=Window.new{x=,y=}
print(w.width)
print(w.width1)
--输出结果
--
--nil
2)、__newindex元方法
和__index不同的是,该元方法用于不存在键的赋值,而前者用于访问。
Window={}
Window.prototype={x=,y=,width=,height=}
Window.mt={} --Window的元表 function Window.new(o)
setmetatable(o,Window.mt)
return o
end Window.mt.__index=function(table,key) return Window.prototype[key] end
Window.mt.__newindex=function(table,key,value) Window.prototype[key]=value end w=Window.new{x=,y=}
w.length=
print(w.width)
print(w.width1)
print(Window.prototype.length)
--输出结果
--
--nil
--
lua元表与元方法的更多相关文章
- Step By Step(Lua元表与元方法)
Step By Step(Lua元表与元方法) Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加.假设a和b都是table,通过元表可以定义如何计算表 ...
- lua——元表、元方法、继承
[元表] 元表中的键为事件(event),称值为元方法(metamethod). 通过函数getmetatable查询不论什么值的元表,通过函数setmetatable替换表的元表. setmetat ...
- lua元表和元方法 《lua程序设计》 13章 读书笔记
lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在创建table时不会创建元表. t = {} print(getmet ...
- lua 元表与元方法示例
-- 1.检查是否有元表local t = {1, 2}print(getmetatable(t)) -- nilprint("----------------------" ...
- Lua 学习笔记(十一)元表与元方法
在Lua中的每个值都有一套预定义的操作集合.例如可以将数字相加,可以连接字符串,还可以在table中插入一对key-value等.但是我们无法将两个table相加,无法对函数作比较,也无法调用一个字符 ...
- lua中 table 元表中元方法的重构实现
转载请标明出处http://www.cnblogs.com/zblade/ lua作为游戏的热更新首选的脚本,其优势不再过多的赘述.今天,我主要写一下如何重写lua中的元方法,通过自己的重写来实现对l ...
- 【游戏开发】小白学Lua——从Lua查找表元素的过程看元表、元方法
引言 在上篇博客中,我们简单地学习了一下Lua的基本语法.其实在Lua中有一个还有一个叫元表的概念,不得不着重地探讨一下.元表在实际地开发中,也是会被极大程度地所使用到.本篇博客,就让我们从Lua查找 ...
- lua编程之元表与元方法
一. 前言 lua是一种非常轻量的动态类型语言,在1993年由由Roberto Ierusalimschy.Waldemar Celes 和 Luiz Henrique de Figueiredo等人 ...
- Lua中的元表与元方法学习总结
前言 元表对应的英文是metatable,元方法是metamethod.我们都知道,在C++中,两个类是无法直接相加的,但是,如果你重载了"+"符号,就可以进行类的加法运算.在Lu ...
随机推荐
- PHP异常处理函数set_exception_handler()的用法
定义和用法 set_exception_handler() 函数设置用户自定义的异常处理函数. 该函数用于创建运行时期间的用户自己的异常处理方法. 该函数会返回旧的异常处理程序,若失败,则返回 nul ...
- PHP 获取中国时间,即上海时区时间
/** * 获取中国时间,即上海时区时间 * @param <type> $format * @return <type> */ function getChinaTime($ ...
- Mac Pro 实现 PHP-5.6 与 PHP-7.0 等多版本切换
先前参考 如何 实现PHP多版本的 共存 和 切换? 实现了Linux(Ubuntu/CentOS)系统下,PHP多版本的切换,但是在 Mac OS 下,由于用户权限控制的比较严格,文章里提到的脚本运 ...
- Javascript实现图片预加载【回调函数,多张图片】
使用JS实现一组图片动画效果或者使用HTML5 Canvas渲染一系列图片等案例中,需要图片全部加载完成方可运行动画效果.此时程序中就会涉及多张图片预加载代码.当接二连三的案例中都涉及图片预加载时,就 ...
- Spring MVC+FreeMarker简介
最近做项目,刚接触到SpringMVC与FreeMarker框架,就简单介绍一下自己的理解,不正确的地方请大家指教!! 1.Spring MVC工作原理: 用户发送请求--->前端服务器去找相对 ...
- C# mongodb 驱动操作(Z)
Query.All("name", "a", "b");//通过多个元素来匹配数组 Query.And(Query.EQ("nam ...
- System Error Codes
很明显,以下的文字来自微软MSDN 链接http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx M ...
- Python学习笔记(一)——环境搭建
一.安装包下载: 国内镜像:32位:http://pan.baidu.com/s/1jI4q4lS 64位:http://pan.baidu.com/s/1eRPhpRW 版本更迭速度很 ...
- JavaScript(一)
JavaScript 是脚本语言 JavaScript 是一种可插入 HTML 页面的轻量级的编程语言,它跟Java没有什么蛋关系. JavaScript使用: <script language ...
- BZOJ 2460 [BeiJing2011]元素 ——线性基
[题目分析] 线性基,由于最多有63个,只需要排序之后,动态的去维护线性基即可. [代码] #include <cstdio> #include <cstring> #incl ...