元表还可以指定关系操作符的含义,元方法为__eq ,__lt(小于) ,__le(小于等于).

而其它3个关系操作符则没有单独的元方法,Lua会

把a ~= b 转化为not(a == b)

将a>b   转化为 b < a ;

将a>=b 转化为 b <= a ;

因此需要分别为__le和__lt提供实现:

mt.__le = function(a,b)  --set containment
for k in pairs(a) do
if not b[k] then return false end
end
return true
end mt.__lt = function(a,b)
return a<=b and not(b <= a)
end

最后,还可以定义集合的相等性判断:

mt.__eq = function(a,b)
  return a <= b and b<=a
end

有了这些定义,可以比较集合了:

s1 = Set.new{,}
s2 = Set.new{,,}
print(s1 <= s2 ) --> true
print(s1 < s2) --> true
print(s1 >= s1) --> true
print(s1 > s1) -->false
print(s1 == s2 * s1) -->true

等于比较有一点限制,如果两个对象拥有不同的方法,那么等于操作不会调用任何一个元方法,而是直接返回false。

只有当两个比较对象共享一个元方法时,Lua才调用这个等于比较的元方法。

与算术类的元方法不同的是,关系类的元方法不能应用于混合的类型。

如果试图将一个字符串与一个数字作顺序性比较,Lua会引发一个错误。

库定义的元方法

函数tostring,它能将各种类型的值表示为一种简单的文本格式:

print({})            -->table:0x8062ac0

print函数总是调用tostring来格式化其输出。当格式化任意值时,tostring会检查该值是否有一个__tostring的元方法。

如果有这个元方法,tostring就用该值作为参数来调用这个元方法。

这个元方法工作的结果就是tostring的结果。

在集合的实例中,已定义了一个将集合表示为字符串的函数。接下来要做的就是设置元表中的__tostring字段:

mt.__tostring = Set.tostring

此后只要调用print来打印集合,print就会调用tostring函数,进而调用到Set.tostring:

s1 = Set.new{,,}
print(s1) -->{4,5,10}

函数setmetatable和getmetatable也会用到元表中的一个字段,用于保护元表。

假设想要保护集合的元表,使用户既看不到也不能修改集合的元表。那么就需要用到字段__metable。

当设置了该字段,getmetatable就会返回这个字段的值,而setmetatable则会引发一个错误:

mt.__metatable = "not your business"

s1 =  Set.new{}
print(getmetatable(s1)) -->not your business
setmetatable(s1,{}) -->stdin:1:cannot change protected metatable

以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 》

chapter 13_2 关系类、库定义的元方法的更多相关文章

  1. php类的定义与实例化方法

    php类的定义 类是对某个对象的定义.它包含有关对象动作方式的信息,包括它的名称.方法.属性和事件.实际上它本身并不是对象,因为它不存在于内存中.当引用类的代码运行时,类的一个新的实例,即对象,就在内 ...

  2. OC学习--OC中的类--类的定义,成员变量,方法

    1. 类的定义 >用关键字@interface进行声名  @end 结束 >所有的类有一个基类NSobject >类名 也是标示符 第一个字母大写 如果多个字母组成 每个单词的首字母 ...

  3. Lua 学习笔记(十一)元表与元方法

    在Lua中的每个值都有一套预定义的操作集合.例如可以将数字相加,可以连接字符串,还可以在table中插入一对key-value等.但是我们无法将两个table相加,无法对函数作比较,也无法调用一个字符 ...

  4. lua元表与元方法

    lua中提供的元表(metatable)与元方法(metamethod)是一种非常重要的语法,metatable主要用于做一些类似于C++重载操作符式的功能. lua中提供的元表是用于帮助lua变量完 ...

  5. lua元表和元方法 《lua程序设计》 13章 读书笔记

    lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在创建table时不会创建元表. t = {} print(getmet ...

  6. lua metatable和metamethod元表和元方法

    Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加.假设a和b都是table,通过元表可以定义如何计算表达式a+b.当Lua试图将两个table相加时, ...

  7. lua编程之元表与元方法

    一. 前言 lua是一种非常轻量的动态类型语言,在1993年由由Roberto Ierusalimschy.Waldemar Celes 和 Luiz Henrique de Figueiredo等人 ...

  8. Step By Step(Lua元表与元方法)

    Step By Step(Lua元表与元方法) Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加.假设a和b都是table,通过元表可以定义如何计算表 ...

  9. chapter 13_3 table访问的元方法

    前两节的算术类.关系类运算符的元方法都为各种错误情况定义了行为,它们不会改变语言的常规行为. 但是Lua还提供了两种可以改变table行为的方法: 一种是查询table中不存在的字段.一种是修改tab ...

随机推荐

  1. Webkit浏览器点击控件时出现的边框消除

    -webkit-tap-highlight-color:rgba(0,0,0,0); 其实是将边框颜色透明,让其不可见了而已

  2. [河南省ACM省赛-第三届] 房间安排 (nyoj 168)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=168 分析:找到一天中需要最多的房间即可 #include<iostream> ...

  3. 无法定位程序输入点__gxx_personality_v0的一个解决方法

    windows系统,使用mingw32-g++编译一个简单的工程,编译链接过程都没有错误提示,但是运行的时候会弹出提示框提示"无法定位程序输入点__gxx_personality_v0&qu ...

  4. 域名注册商namesilo价格便宜,赠送whois保护,最新优惠码:geekradio

    注册域名,不懂事的中国人一般去国内奸商万网注册,价格贵,域名管理风险大,甚至注册.cn域名,花钱还吃亏.精明一点的中国人选godaddy,namecheap,gandi这类国外域名注册商,价格不贵,你 ...

  5. ios GCD的使用及封装

    实现代码: CGDHelper /* * Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法. * 系统要求:iOS4.0以上. */ #import & ...

  6. 10、 iOS 加载图片选择imageNamed 方法还是 imageWithContentsOfFile

    Apple官方的文档为生成一个UIImage对象提供了两种方法: 1. imageNamed,其参数为图片的名字: 2. imageWithContentsOfFile,其参数是图片文件的路径. 两种 ...

  7. js检测对象中是否存在某个属性

    1.使用in关键字.该方法可以判断对象的自有属性和继承来的属性是否存在. 2.使用对象的hasOwnProperty()方法.该方法只能判断自有属性是否存在,对于继承属性会返回false. 3.用un ...

  8. 小谈数据库Char、VarChar、NVarChar差异

    1. char      固定长度,最长n个字符.   2. varchar      最大长度为n的可变字符串. (n为某一整数,不同数据库,最大长度n不同)   char和varchar区别:   ...

  9. 小白学C++的小问题

    昨天开始学习C++,使用的visual studio 2012. 1命名要有意义,避免用a,b,c,尽量使用num,result等让人看见就能明白相关含义的名字 2要有一定的注释,注释和有意义的命名可 ...

  10. fopen()函数以"a+"方式打开一个不存在的文件后读写出现问题

    问题:在完成课后习题的时候,使用fopen()函数以"a+"方式打开一个不存在的文件时,写入.读取出现错误: //添加用户输入单词后,在单词头加入编号,确保编号跟着前面的开始排序 ...