Lua 学习之元表(metatable) 一

在 Lua table 中我们可以访问对应的 key 来得到 value 值,但是却无法对两个 table 进行操作(比如相加)。

因此 Lua 提供了元表(Metatable),允许我们改变 table 的行为,每个行为关联了对应的元方法。类似于C++中的运算符重载。

一、两个很重要的函数来处理元表:

  • setmetatable(table,metatable): 对指定 table 设置元表(metatable),如果元表(metatable)中存在 __metatable 键值,setmetatable 会失败。

  • getmetatable(table): 返回对象的元表(metatable)。

mytable = {}                          -- 普通表
mymetatable = {}                      -- 元表
setmetatable(mytable, mymetatable)     -- 把 mymetatable 设为 mytable 的元表 

-- 也可直接写成如下形式
mytable = setmetatable({}, {})

getmetatable(mytable)                 -- 这会返回 mymetatable

二、通过添加操作符的方式来定义表之间的运算规则,类似于C++中的运算符重载:

详见官方文档:http://www.lua.org/manual/5.4/manual.html#2.4

使用方法,以__add为例:

T1 = {1, 2, 3, nil, 4}
T2 = {1, 2, 3, 4, 5, 6}
metaT3 = {}

metaT3["__add"] = function(t1, t2)
        local len
        if #T1 >= #T2 then
                len = #T1
        else
                len = #T2
        end

        local res = {}
        for i = 1, len do
                local a = t1[i] or 0
                local b = t2[i] or 0
                res[i] = a + b
        end

        return res
end

setmetatable(T1, metaT3)
setmetatable(T2, metaT3)

print("T1 + T2 :")
for k, v in pairs(T1 + T2) do
        print(k, v)
end

--执行结果
T1 + T2 :
1       2
2       4
3       6
4       4
5       9
6       6

对于__eq遇到的特殊情况

t1 = {1, 2, 3)
t2 = {1, 2, 3)
metaT3 = {}
metaT3["__eq"] = function(t1,t2)
        print("length of t1 = ", #t1)
        print("length of t2 = ", #t2)

        if #t1 ~= #t2 then
                return false
        end

        for i = 1, #t1 do
                if t1[i] ~= t2[i] then
                        return false
                end
        end

        return true

end

setmetatable(t1, metaT3)
setmetatable(t2, metaT3)

print(t1 == t2)

--执行结果
true

--但是当出现如下情况
t1 = {1, 2, 3}
t2 = {1, 2, 3, nil}

--执行结果
true

--解释:在Lua中table末尾的nil不会被当作有效值进行运算,因此t2末尾有若干个nil,t1 == t2 仍为true.
--但是,非末尾的nil不会被忽视

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值