Lua 元表

有一篇博客对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 元表)