LUA元表、元操作

  


1.元表、元操作

1.1算术元操作

Metatables允许我们改变table的行为,例如,使用Metatables我们可以定义Lua如何计算两个table的相加操作a+b。当Lua试图对两个表进行相加时,他会检查两个表是否有一个表有Metatable,并且检查Metatable是否有__add域。如果找到则调用这个__add函数(所谓的Metamethod)去计算结果。


Lua中的每一个表都有其Metatable。(后面我们将看到userdata也有Metatable),Lua默认创建一个不带metatable的新表

t = {}

print(getmetatable(t))      --> nil


任何一个表都可以是其他一个表的 metatable ,一组相关的表可以共享一个 metatable (描述他们共同的行为)。一个表也可以是自身的 metatable (描述其私有行为)。

Set.mt = {}       -- metatable for sets

function Set.new (t)     -- 2nd version --创建

    local set = {}

    setmetatable(set, Set.mt)

    for _, l in ipairs(t) do set[l] = true end

    return set

end

function Set.union (a,b) --并集

    local res = Set.new{}

    for k in pairs(a) do res[k] = true end

    for k in pairs(b) do res[k] = true end

    return res

end

 

function Set.intersection (a,b) --交集

    local res = Set.new{}

    for k in pairs(a) do

       res[k] = b[k]

    end

    return res

end

function Set.tostring (set) --转换

    local s = "{"

    local sep = ""

    for e in pairs(set) do

       s = s .. sep .. e

       sep = ", "

    end

    return s .. "}"

end

 

function Set.print (s) --打印

    print(Set.tostring(s))

end


第一步,我们定义一个普通的表,用来作为metatable。为避免污染命名空间,我们将其放在set内部。

Set.mt = {}       -- metatable for sets

第二步,给metatable增加__add函数。

   Set.mt.__add = Set.union

当Lua试图对两个集合相加时,将调用这个函数,以两个相加的表作为参数。

通过metamethod,我们可以对两个集合进行相加:

s3 = s1 + s2

Set.print(s3)     --> {1, 10, 20, 30, 50}

同样的我们可以使用相乘运算符来定义集合的交集操作

Set.mt.__mul = Set.intersection

 

Set.print((s1 + s2)*s1)     --> {10, 20, 30, 50}

除了 __add __mul 外,还有 __sub( ) __div( ) __unm( ) __pow( ) ,我们也可以定义 __concat 定义连接行为。

Lua选择metamethod的原则:如果第一个参数存在带有__add域的metatable,Lua使用它作为metamethod,和第二个参数无关;

否则第二个参数存在带有__add域的metatable,Lua使用它作为metamethod 否则报错。

1.2关系元操作

Metatables也允许我们使用metamethods__eq(等于),__lt(小于),和__le(小于等于)给关系运算符赋予特殊的含义

对剩下的三个关系运算符没有专门的metamethod,因为Luaa ~= b转换为not (a == b)a > b转换为b < aa >= b转换为 b <= a

Set.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

 

Set.mt.__lt = function (a,b) --  <=

    return a <= b and not (b <= a)

end


Set.mt.__eq = function (a,b) -- ==

    return a <= b and b <= a

end

与算术运算的 metamethods 不同,关系元算的 metamethods 不支持混合类型运算。对于混合类型比较运算的处理方法和 Lua 的公共行为类似。

1.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值