lua metatable/metamethod学习

来源:互联网 发布:高校大数据课程 编辑:程序博客网 时间:2024/06/10 04:29

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 reendfunction 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 reendfunction Set.Print(lst)    local l = {}    for e in pairs(lst) do    l[#l+1] = e    end    return "{"..table.concat(l,",").."}"endlocal lh = Set.new{"hbb",5,3,8}local lb = Set.new{"nm",2,6}mt.__add = Set.Unionlocal l = lh + lbprint(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")endT.__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进行设置;

0 0
原创粉丝点击