chapter 13_2 关系类、库定义的元方法

本文深入探讨Lua中的元表和元方法,包括如何使用元方法定义集合的比较、相等性和字符串表示。通过具体示例展示了元方法在集合操作中的应用,如集合的包含、相等和字符串表示。

  元表还可以指定关系操作符的含义,元方法为__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{2,4}
s2 = Set.new{4,10,2}
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{10,4,5}
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 》

转载于:https://www.cnblogs.com/daiker/p/5848349.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值