美文网首页
Lua 元表

Lua 元表

作者: CodeVin | 来源:发表于2019-03-19 14:18 被阅读0次

    有一篇博客对Lua元表的介绍非常易懂,推荐阅读原博主的文章 点我前往

    以下内容仅仅是个人为了加深记忆将原博主内容消化并复述一遍。

    lua元表就是用于查找的备用表。如果访问table中不存在的字段,不会立即返回nil,而是先触发一套查找机制,查找它的元表。

    举例:

    local fathermayun = {
        money = 13000000000
    }
    --设置fathermayun的__index元方法
    fathermayun.__index = fathermayun
    local me = {}
    --将fathermayun设为me的元表
    setmetatable(me, fathermayun)
    print(me.money)
    
    --输出:13000000000
    

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

    利用元表的上述特性实现面向对象的继承特性
    local function class( super )
        local cls
        if super then
            cls = {}
            cls.super = super
            setmetatable(cls, {__index = super})
        else
            -- ctor是构造函数的命名
            cls = {ctor = function () end}
        end
    
        cls.__index = cls
        function cls.new( ... )
            local instance = setmetatable({}, cls)
            instance:ctor()
            return instance
        end
    
        return cls
    end
    

    测试继承

    local Test = class()
    function Test:doSomething()
        print("test doSomething")
    end
    local Test2 = class(Test)
    local test = Test2.new()
    test:doSomething()
    

    也可以成功打印出"test doSomething"
    原理说明:

    在new的时候,创建一个table并返回,即创建一个实例,实例可以有自己的字段,比如Test类的doSomething,该字段是个函数,可以调用执行。实例的元表是cls,如果调用实例没有的字段,会去cls里找
    cls设置了元方法__index = cls
    如果没有super,则只有一个构造函数方法
    如果有super,cls的元表是super,元表的元方法也正确的设置了
    所以,在Test2是继承自Test的,它的实例test调用doSomething,找不到,去元表里找,元表发现自己有父类,去父类里找,成功找到。

    相关文章

      网友评论

          本文标题:Lua 元表

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