关系运算的元方法(Metamethods)

x33g5p2x  于2022-08-17 转载在 其他  
字(1.0k)|赞(0)|评价(0)|浏览(534)
  • EQ 就是 EQUAL等于
  • NE就是 NOT EQUAL不等于
  • GT 就是 GREATER THAN大于 
  • LT 就是 LESS THAN小于
  • GE 就是 GREATER THAN OR EQUAL 大于等于
  • LE 就是 LESS THAN OR EQUAL 小于等于

Metatables 也允许我们使用 metamethods__eq(等于)__lt(小于),和__le(小于等于)给关系运算符赋予特殊的含义。对剩下的三个关系运算符没有专门的 metamethod,因为 Lua 将 a ~= b 转换为 not (a == b); a > b 转换为 b < a; a >= b 转换为 b <= a。

(直到 Lua 4.0 为止,所有的比较运算符被转换成一个, a <= b 转为 not (b < a)。然而这种转换并不一致正确。当我们遇到偏序(partial order)情况,也就是说,并不是所有的元素都可以正确的被排序情况。例如,在大多数机器上浮点数不能被排序,因为他的值不是一个数字(Not a Number 即 NaN)。根据 IEEE 754 的标准, NaN 表示一个未定义的值,比如 0/0 的结果。该标准指出任何涉及到 NaN 比较的结果都应为 false。也就是说, NaN <= x 总是 false, x < NaN 也总是 false。这样一来,在这种情况下 a <= b 转换为 not (b < a)就不再正确了。)

在我们关于基和操作的例子中,有类似的问题存在。 <=代表集合的包含: a <= b 表示集合 a 是集合 b 的子集。这种意义下,可能 a <= b 和 b < a 都是 false;因此,我们需要将__le 和__lt 的实现分开:最后,我们通过集合的包含来定义集合相等:

有了上面的定义之后,现在我们就可以来比较集合了:

结果如下:

与算术运算的 metamethods 不同,关系元算的 metamethods 不支持混合类型运算。对于混合类型比较运算的处理方法和 Lua 的公共行为类似。如果你试图比较一个字符串和一个数字, Lua 将抛出错误。相似的,如果你试图比较两个带有不同 metamethods 的对象, Lua 也将抛出错误。

但相等比较从来不会抛出错误,如果两个对象有不同的 metamethod,比较的结果为false,甚至可能不会调用 metamethod。这也是模仿了 Lua 的公共的行为,因为 Lua 总是认为字符串和数字是不等的,而不去判断它们的值。仅当两个有共同的 metamethod 的对象进行相等比较的时候, Lua 才会调用对应的 metamethod。

相关文章