chapter 13_1 算术类的元方法
假设用table来表示集合,用function去计算集合的交集、并集。
为了保持名称空间的整齐,将这些函数存入一个名为Set的table中。
现在,假设用“+”来计算两个集合的并集,那么就要让所有用于表示集合的table共享一个元表。
并且在该元表中定义如何执行一个加法操作。
- local mt = {} --集合的元表
- function Set.new(l)
- local set = {}
- setmetatable(set,mt)
- for _,v in ipairs(l) do set[v] = true end
- return set
- end
在此后,用Set.new创建的集合都具有一个相同的元表:
- s1 = Set.new{,,,}
- s2 = Set.new{,}
- print(getmetatable(s1)) -->table:00672B60
- print(getmetatable(s2)) -->table:00672B60
最后将元方法加入到元表中:
- mt.__add = Set.union
元方法就是一个函数:
- Set = {}
- function Set.union(a,b) --并集
- local res = Set.new{}
- for k in pairs(a) do res[k] = true end
- for k in pairs(b) do res[k] = true end
- return res
- end
- function Set.intersection(a,b) --交集
- local res = Set.new{}
- for k in pairs(a) do
- res[k] = b[k]
- end
- return res
- end
为了帮助检查此示例,还定义了一个用于打印集合的函数:
- function Set.tostring(set)
- local l = {} --用于存放集合中所有元素的列表
- for e in pairs(set) do
- l[#l + ] = e
- end
- return "{" .. table.concat(l,", ") .. "}"
- end
- function Set.print(s)
- print(Set.tostring(s))
- end
此后,只要Lua试图将两个集合相加,就会调用Set.union函数,并将两个操作数作为参数传入。可以使用加号来求集合的并集:
- s3 = s1 + s2
- Set.print(s3) --> {1, 10, 20 ,30 ,50}
类似还可以用乘号来求集合的交集:
- mt.__mul = Set.intersection
- Set.print((s1+s2) * s1) -->{10, 20, 30 ,50}
在元表中,每种算术操作符都有对应的字段名。除了上面的__add和 __mul外,还有__sub,__div、__unm(相反数)、__mod(取模)和__pow(乘幂)。
此外,还可以定义__concat字段,用于描述连接操作符的行为。
然而,当一个表达式中混合了具有不同元表的值时,例如:
- s = Set.new{,,}
- s = s +
Lua会按照下面步奏去找元表:
如果第一个值有元表,并且元表中有__add字段,那么Lua就以这个字段为元方法,而与第二个值无关;
反之,如果第二个值有元表并包含__add字段,Lua就以它为元方法;
如果两个都没有元方法,Lua就引发一个错误。
Lua可以包含这些混合类型,但实际需要注意如果执行了s = s + 8,那么在Set.union内部就会发生错误。
- bad argument # to "pairs" (table expected , got number)
如果想要得到更清晰的错误消息,则必须在实际操作前显式地检查操作数的类型:
- function Set.union(a,b)
- if getmetatable(a) ~= mt or getmetatable(b) ~= mt then
- error("attempt to 'add' a set with a non-set value",)
- end
- <as before>
注意,error的第二个参数用于指示哪个函数调用造成了该错误消息。
以上内容来自:《Lua程序设计第二版》和《Programming in Lua third edition 》
chapter 13_1 算术类的元方法的更多相关文章
- chapter 13_3 table访问的元方法
前两节的算术类.关系类运算符的元方法都为各种错误情况定义了行为,它们不会改变语言的常规行为. 但是Lua还提供了两种可以改变table行为的方法: 一种是查询table中不存在的字段.一种是修改tab ...
- chapter 13_2 关系类、库定义的元方法
元表还可以指定关系操作符的含义,元方法为__eq ,__lt(小于) ,__le(小于等于). 而其它3个关系操作符则没有单独的元方法,Lua会 把a ~= b 转化为not(a == b) 将a&g ...
- Lua 学习笔记(十一)元表与元方法
在Lua中的每个值都有一套预定义的操作集合.例如可以将数字相加,可以连接字符串,还可以在table中插入一对key-value等.但是我们无法将两个table相加,无法对函数作比较,也无法调用一个字符 ...
- lua元表和元方法 《lua程序设计》 13章 读书笔记
lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在创建table时不会创建元表. t = {} print(getmet ...
- lua metatable和metamethod元表和元方法
Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加.假设a和b都是table,通过元表可以定义如何计算表达式a+b.当Lua试图将两个table相加时, ...
- Lua中的元表与元方法
[前言] 元表对应的英文是metatable,元方法是metamethod.我们都知道,在C++中,两个类是无法直接相加的,但是,如果你重载了“+”符号,就可以进行类的加法运算.在Lua中也有这个道理 ...
- Lua中的元表与元方法学习总结
前言 元表对应的英文是metatable,元方法是metamethod.我们都知道,在C++中,两个类是无法直接相加的,但是,如果你重载了"+"符号,就可以进行类的加法运算.在Lu ...
- Step By Step(Lua元表与元方法)
Step By Step(Lua元表与元方法) Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加.假设a和b都是table,通过元表可以定义如何计算表 ...
- lua元表与元方法
lua中提供的元表(metatable)与元方法(metamethod)是一种非常重要的语法,metatable主要用于做一些类似于C++重载操作符式的功能. lua中提供的元表是用于帮助lua变量完 ...
随机推荐
- find用法积累
查找目录下的所有文件中是否含有某个字符串 find .|xargs grep -ri "IBM" 查找目录下的所有文件中是否含有某个字符串,并且只打印出文件名 find .|xar ...
- cookie会话技术
会话技术 B/S请求是无状态无记忆的,脚本与脚本之间是没有联系的,导致不能进行连续的业务逻辑 Cookie技术:将会话数据保存在浏览器端 原理:服务器向浏览器发送指令,用来管理存储在浏览器端的cook ...
- POJ 1118 Lining Up
枚举,排序. 先将所有点按双关键字排序,然后枚举线的顶点$P$,剩余的点以$P$为中心进行极角排序,可以取个$gcd$,这样一样的点就排在一起了,然后统计一下更新答案. #pragma comment ...
- KMP 算法 学习 整理
我自己整理的KMP算法的PDF文件:http://pan.baidu.com/s/1o8yKIi2提取密码:8291 别的就不多说啥了,感谢来自海子 博客园的 资料--
- umount: /home: device is busy
转自:umount: /home: device is busy 取消挂载/home时出现umount: /home: device is busy,原因是因为有程序在使用/home目录,我们可以使用 ...
- jquery+ajax 实现text框模糊搜索并可利用listbox实时显示模糊搜索列表结果
功能描述: text框中输入,text框下面的listbox中实时显示依据输入的内容进行模糊搜索的结果 js代码 $j(function() { $j("input[id='txtCos'] ...
- JS中的Replace只会替换第一处解决办法
解决这个问题只需将replace的第一个参数使用正则的方式即可,代码如下: var reg = new RegExp(",","g"); var str = & ...
- javascript实现验证身份证号的有效性并提示
javascript实现验证身份证号的有效性并提示 function nunber(allowancePersonValue){ if(allowancePersonValue=="身份证号 ...
- 我的JAvA第三天
- kali rolling 安装typecho
#1 apt-get install nginx php7.0 php7.0-mysql php7.0-gd php7.0-cgi php7.0-cli php7.0-curl php7.0-fpm ...