lua的元表、模块和面向对象

元表

lua的元表是表的一个扩展,可以简化表的一些操作。setmetatable关键字是设置元表的核心操作。

__index相当于建立索引,为查找表元素提供了方便。
Lua 查找一个表元素时的规则,其实就是如下 3 个步骤: (参考自https://blog.csdn.net/xocoder/article/details/9028347)

  1. 在表中查找,如果找到,返回该元素,找不到则继续
  2. 判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。
  3. 判断元表有没有 __index 方法,如果 __index 方法为 nil,则返回 nil;如果 __index 方法是一个表,则重复 1、2、3;
  4. 如果 __index 方法是一个函数,则返回该函数的返回值,table和键会作为参数传递给函数。

给出代码实例:

other = {foo = 3}
t = setmetatable({}, {__index = other})
print(t.foo)

mytable = setmetatable({key1 = "key2"}, {
    __index = function(mytable, key)
        if key == "key2" then
            return "metatablevalue"
        else 
            return nil
        end
    end
})

print(mytable.key1)
print(mytable.key2)

函数的输出是:

3
key2
metatablevalue

可以给表添加操作符号,以__add为例子:

function table_maxn(t)
    local mn = 0
    for k, v in pairs(t) do
        if mn < k then
            mn = k
        end
    end
    return mn
end

mytable = setmetatable({1, 2, 3}, {
    __add = function(mytable, newtable)
        for i = 1, table_maxn(newtable) do
            table.insert( mytable, table_maxn(mytable) + 1, newtable[i])
        end
        return mytable
    end
})

secondtable = {4, 5, 6}
mytable = mytable + secondtable

for k, v in ipairs(mytable) do
    print(k, v)
end

同样的,函数以mytable和`操作符后面的表作为输入。还有其他的操作符号,可以查找对应的表数据。

__call方法在lua调用一个值时进行调用,给出代码实例:

function table_maxn(tb) 
    local mn = 0
    for k, v in pairs(tb) do
        if k > mn then
            mn = k
        end
    end
    return mn
end
mytable = setmetatable({1, 2, 3}, {
    __call = function(mytable, newtable)
        local sum = 0
        
        for i = 1, table_maxn(mytable) do
            sum = sum + mytable[i]
        end

        for i = 1, table_maxn(newtable) do 
            sum = sum + newtable[i]
        end
        return sum
    end
})

newtable = {4, 5, 6}
print(mytable(newtable))  -- 输出21

相当于一个元表本身就是一个函数了。

__tostring用于改变元素的输出方式,代码实例:

mytable = setmetatable({10, 20, 30}, {
    __tostring = function(mytable)
        local sum = 0
        for k, v in pairs(mytable) do
            sum = sum + v
        end
        return sum
    end
})

print(mytable)  -- 输出60

模块

新建一个module1的模块,命名为model1.lua

module1 = {}
module1.constant = "This is constant"

function module1.func1()
    print("public function")
end

local function func2()
    print("This is a private function")
end

function module1.func3()
    func2()
end

return module1

新建main.lua文件,内容如下:

local m = require("./module1")

print(module1.constant)  -- 报名调用
m.func1()  -- 变量调用
module1.func3()

如果是加载C语言的动态链接库,可以直接写成:

local path = "/usr/local/lua/lib/mylua.so"
local f = loadlib(path, "luaopen_socket")

Lua 面向对象

Lua中,一个类使用table表示的,同时还需要借助元表的技术,给出代码实例:

Rectangle = {width = 0, height = 0}

function Rectangle:new (o, width, height)
    o = o or {}
    setmetatable(o, self)  -- 通过元表的方式,来确定新对象,也可以进行引用操作
    self.__index = self
    self.width = width or 0
    self.height = height or 0
    return o
end

function Rectangle: area ()
    return self.width * self.height
end

rect = Rectangle:new(nil, 10, 20)  -- 新建对象
print(rect:area())  -- 200

rect1 = Rectangle:new(rect1, 20, 30)  -- 传递对象的引用,同时改变对应的值
print(rect:area())  -- 600
print(rect1:area())  -- 600
print(rect.width)  -- 20
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值