lua metatable/metamethod学习

metatable

类似封装了lua类型的操作符;

作用
lua的类型定义的一组操作符, 即当要对对象进行操作的时候,则查看元表里有没有对应的操作符; 如table的+对应__add, 该字段就是所谓在元方法(函数);

lua 中每个值都有一个元表, 而只有table, userdata 有自己独立在元表,其它的类型都是共享一个元表;

table默认创建时元表为nil;
getmetatable(table)setmetatable(table, meta) 为元表操作函数;
lua中只能设置table的元表, 其它类型的值的元表只能通过C代码来设置;

元表示例

如下面的例子就是给table设置了一个+的算法来求集合:

local mt = {}
Set = {}
function Set.new(list)
    local re = {}
    setmetatable(re,mt)
    for _,v in ipairs(list) do re[v] = true     end
    return re
end
function Set.Union(a,b)
    local re = {}
    for k in pairs(a) do    re[k] = true    end
    for k in pairs(b) do    re[k] = true end
    return re
end
function Set.Print(lst)
    local l = {}
    for e in pairs(lst) do
    l[#l+1] = e
    end
    return "{"..table.concat(l,",").."}"
end
local lh = Set.new{"hbb",5,3,8}
local lb = Set.new{"nm",2,6}
mt.__add = Set.Union
local l = lh + lb
print(Set.Print(l))

metatable元表的禁止

想要用户即看不到元表又不能修改元表, 则可以将元表的__metatable属性赋值, 如上面的例子,如果mt.__metatable = "hehe" 则getmetable会返回这个值, 而setmetatable则直接报错;


元方法

就是当table查询或修改的字段不存在时, 会访问元方法;

当对table进行字段查找和修改的时候,如果当前table里面没有对应的字段, 则会想metatable中的metamethod:__index, __newindex进行查找;
注: 这里是metatable的 而不是table自己的__index和__newindex字段

local mt = {}
T = {}
T.__index = function (t,k)
    print("this is the meta index")
end
T.__newindex = function (t,k,v)
    print("this is the meta newidex")
end 
setmetatable(T,mt)
T.Id = 4      --会打印thsi is the meta newindex, 但这里没有创建字段,
-- 所以后面查询为空
print(T.Id)    -- this is the meta index, nil'

rawget(t,k), rawset(t,k,v)

rawget(t,k) 就是访问table t的k字段时, 不会访问到__index元方法;
同理,rawget(t,k.v)也是绕过__newindex元方法直接对table进行设置;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值