lua学习笔记day11-----metatable 和 metamathods 的关系运算

lua中有明确metamathods的关系运算符只有以下三种:
__eq(等于 =),__lt(小于 <),__le(小于等于 <=).
剩下的三种
a~=b , 用not(a == b)
a > b, 用b <= a
a >= b, 用b < a
代替。
这就相当于,当发现 b <= a的结果是false的时候,就认为结果是b > a。然而,这种考虑是有漏洞的。
当两张表进行比较的时候,将 a<=b,定义为a是b的子集。
a = {1,2,3,4}
b = {2,3,4,5}
a <= b 是不成立,如果根据lua中的讲法,结果就是 b < a 。显然在这个例子里,b < a也是不正确的。
上述内容,是让读者注意,不能断章取义的取使用这仅有的三个符号。
以下代码是对 __eq,__lt,__le的实现:

Set = {}
Set.mt = {}
function Set.New(t)
        local set = {}
        setmetatable(set,Set.mt)
        for _,i in ipairs(t) do set[i] = true end
        return set
end
function Set.eq(a,b)
        for k in pairs(a) do
                if not (b[k]) then return false end
        end
        return true
end
function Set.le(a,b)
        for k in pairs(a) do
                if not(b[k]) then return false end
        end
        return true
end
function Set.lt(a,b)
        return a <= b and not(b <= a)
end
do
        Set.mt.__eq = Set.eq
        Set.mt.__le = Set.le
        Set.mt.__lt = Set.lt
        s1 = Set.New{10,20,30,40}
        s2 = Set.New{1,2,10,20}
        print(s1 <= s2)
        print("\n")
        print(s2 < s1)
end

上述代码中,将lt的实现通过le来实现,当调用 < 的时候,会触发metatable中的 __lt ,这个函数调用__le,如果返回真,说明 a <= b,再证明 b中含有a中不具备的元素,那么就能得到a < b的结论。所以当 a<= b 的时候再调用 not(b <=a ).

仅当两个有共同metamathods的对象,lua才会进行关系运算,其他的情况,lua会抛出错误!

你可能感兴趣的:(lua)