Lua元表metatable理解


最近总是遇到如果通过脚本语言搭建一个OOP结构,于是针对Lua进行了解,发现需要用到其元表metatable来实现,则对Lua的metatable进行一个理解的整理

理解:
名称:元表,本身也是一个table
针对table进行一些定制设定,添加或改变table的一些行为
例如定义一些方法,例如定义一个table的相加行为

metatable设置方法:

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

以下实例演示了如何对指定的表设置元表:
-- An highlighted block
mytable = {}                          -- 普通表 
mymetatable = {}                      -- 元表
setmetatable(mytable,mymetatable)     -- 把 mymetatable 设为 mytable 的元表 

__index元方法

metabale最常用的键,访问table的时候,没有这个键值,如果这个键没有值,则查找该table中的metatable,若metatable存在的情况下,查找metatable中的__index键,如果__index包含表格,lua会在其中查找对应的键值,如果__index包含一个函数,则调用其函数,table和键作为参数。
__index元方法查看表中元素是否存在,如果不存在,返回结果为nil;如果存在则由__index返回结果。

总结

Lua查找一个表元素时的规则,其实就是如下3个步骤:
1.在表中查找,如果找到,返回该元素,找不到则继续
2.判断该表是否有元表,如果没有元表,返回nil,有元表则继续。
3.判断元表有没有__index方法,如果__index方法为nil,则返回nil;如果__index方法是一个表,则重复1、2、3;如果__index方法是一个函数,则返回该函数的返回值。

__newindex 元方法

__newindex 元方法用来对表更新,__index则用来对表访问 。
当你给表的一个缺少的索引赋值,解释器就会查找__newindex 元方法:如果存在则调用这个函数而不进行赋值操作。
以下实例演示了 __newindex 元方法的应用:

mytable = setmetatable({key1 = "value1"}, {
  __newindex = function(mytable, key, value)
        rawset(mytable, key, "\""..value.."\"")

  end
})

mytable.key1 = "new value"
mytable.key2 = 4

print(mytable.key1,mytable.key2)

__call 元方法

__call 元方法在 Lua 调用一个值时调用
– 计算表中最大值,table.maxn在Lua5.2以上版本中已无法使用
– 自定义计算表中最大键值函数 table_maxn,即计算表的元素个数

function table_maxn(t)
    local mn = 0
    for k, v in pairs(t) do
        if mn < k then
            mn = k
        end
    end
    return mn
end

定义元方法__call

mytable = setmetatable({10}, {
  __call = function(mytable, newtable)
    sum = 0
    for i = 1, table_maxn(mytable) do
        sum = sum + mytable[i]
    end
    for i = 1, table_maxn(newtable) do
        sum = sum + newtable[i]
    end
    return sum
  end
})
newtable = {10,20,30}
print(mytable(newtable))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值