美文网首页
Lua元表Metatable

Lua元表Metatable

作者: 凉拌姨妈好吃 | 来源:发表于2018-06-27 16:23 被阅读0次

    1. 元表的含义

    元表是带有索引集合的表,它可以改变被附加的表的行为

    2. 算术类的元方法

    下面是我们为我们table赋值,这个table是一个普通表,它的value是一个有参函数


    1

    我们定义一个元表mt

    local mt={}
    

    然后重新修改一下上面的table集合的初始化函数,将元表加入集合中:setmetatable


    集合的初始化

    我们为元表设置元方法,此时下面的Set.union就是元方法,它用于描述如何完成加法的__add字段
    当我们在进行表a+b的时候:

    1. 检查第一个值是否有元表,并且表中有add字段,有就以这个字段的值为元方法,反之第二个值有元表就用它为元方法,如果都没有,就抛出错误
    2. 如果有__add,就取得它的值,此时这个值就是我们的元方法,里面编写了add函数的实现
    mt.__add = Set.union
    

    在元表中,每种算术操作符都有对应的字段名。

    3. __index元方法

    3.1 它的作用

    当我们访问table的一个不存在的字段时,如果没有__index这个元方法,那么就会返回nil,如果有这个元方法,就会由这个元方法来提供最终的结果。
    上面这段是什么意思呢?我们下面通过对象多态性的实现来理解这个概念

    如果想让__index的重写失效,我们可以使用rawget

    print(rawget(s2.gio()))-----返回nil,因为绕过__index,在s2中找不到gio,所以返回nil
    

    3. __newindex元方法

    当对一个table中不存在的索引赋值时,解释器就会去查找__newindex元方法,如果有这个元方法,解释器就调用它,而不是进行赋值nil。如果这个元方法是一个table,解释器就在这个table里进行赋值,而不是对原来的table

        local smartMan = {
            name = "none",
        }
       
        local other = {
            name = "大家好,我是很无辜的table"
        }
       
        local t1 = {};
       
        local mt = {
            __index = smartMan,
            __newindex = other
        }
       
        setmetatable(t1, mt);
         
        print("other的名字,赋值前:" .. other.name);
        t1.name = "小偷";
        print("other的名字,赋值后:" .. other.name);
        print("t1的名字:" .. t1.name);
    
    [LUA-print] other的名字,赋值前:大家好,我是很无辜的table
    [LUA-print] other的名字,赋值后:小偷
    [LUA-print] t1的名字:none
    

    因为我们给元表设置了:__newindex这个元方法,所以我们在给t1.name赋值的时候,因为t1没有这个属性,所以我们就去__newindex对应的other这个table下进行赋值,所以此时other就被赋值为小偷

    4. 跟踪table的访问

    使用了上面的__index 和__newindex,我们可以发现,这些都是在table里没有所需访问的index时才发挥作用的,所以只有当一个table为空的时候,才能捕获到所有对它的访问。所以当我们需要监视一个table的时候,可以创一个table代理,用来跟踪table的所有访问。

    跟踪访问

    相关文章

      网友评论

          本文标题:Lua元表Metatable

          本文链接:https://www.haomeiwen.com/subject/rxpbyftx.html