关系运算相关的元方法

简介: 关系运算相关的元方法

元表还允许我们指定关系运算符的含义,其中的元方法包括等于( __eq )、小于__lt )、和小于等于__le )。其他三个关系运算符没有单独的元方法, Lua 语言会将 a ~= b 转换为 not (a == b)a > b 转换为 b < aa >= b 转换为 b <= a


Lua 语言的老版本中, Lua 语言会通过将 a <= b 转换为 not (b < a) 来把所有的关系运算符转化为一个关系运算符。不过,这种转换在遇到部分有序时就会不正确。所谓部分有序是指,并非所有类型的元素都能够被正确的排序。例如,由于 Not a NumberNaN )的存在,大多数计算机中的浮点数就不是完全可以排序的。根据 IEEE754 标准, NaN 代表未定义的值,例如 0/0 的结果就是 NaN 。标准规定任何涉及 NaN 的比较都应返回,这就意味着 NaN <= x 永远为假, x <= NaN 也为假。因此,在这种情况下, a <= bnot (b < a) 的转化也就不合法了。


在集合的实例中,我们也面临类似的问题。 <= 显而易见且有用的含义是集合包含a <= b 通常意味着 ab 的一个子集。然而,根据部分有序的定义, a <= bb < a 可能同时为假。因此,我们就必须实现 __le (小于等于,子集关系)和 __lt (小于,真子集关系):

mt.__le = function (a, b)
  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 。因此,不过元方法如何,集合永远不等于数字。

目录
相关文章
|
4月前
递归实现指数型枚举
递归实现指数型枚举
15 0
|
10月前
|
存储
操作符详解(1)(下)
操作符详解(1)(下)
|
10月前
|
C语言 索引
操作符详解(2)(上)
操作符详解(2)(上)
|
7月前
|
存储
华为机试HJ15:求int型正整数在内存中存储时1的个数
华为机试HJ15:求int型正整数在内存中存储时1的个数
|
10月前
|
存储
操作符详解(1)(上)
操作符详解(1)(上)
|
10月前
|
编译器 C语言
操作符详解(2)(下)
操作符详解(2)(下)
|
11月前
超大字符串型整数加减
超大字符串型整数加减
31 0
|
11月前
|
算法
不使用+或-运算符,计算两数之和
不使用+或-运算符,计算两数之和
47 0
|
12月前
枚举的三种类型--指数型&排列型&组合型
枚举的三种类型--指数型&排列型&组合型