lua--迭代器、模块、元表

2022-06-21  本文已影响0人  aruba

接着lua的使用,迭代器、模块和元表,元表为重点需要关注的内容

一、迭代器

pairs就是一个迭代器,它的返回值是key和value,下面自定义一个迭代器

定义迭代器语法:
function 迭代器名(终止值参数,初始值参数)
end

使用迭代器语法:
for 第一个返回值,第二个返回值 in 迭代器名,终止值,初始值 do
end

-- 第一个参数:终止值 第二个参数:初始值
function double(max,init)
        if(init < max) then
                init = init + 1
                return init,init*2
        end
end

-- in后面,跟上迭代器名,终止值,初始值  
for i,d in double,10,0  do
        print(i,d)
end

运行结果:

二、模块

lua5.1开始支持模块,可以将函数封装进模块中,在别的脚本中引用模块

1. 新建模块

-- 定义模块
module = {}

-- 模块的常量
module.name = '我的模块'
module.time = '2022'

-- 对外公开的方法 使用module.方法名定义
function module.func1()
        print("func1")
end

-- 内部方法,不能加moudle.
local function func2()
        print("func2")
end

function module.func3()
        func2()
end

-- 返回模块
return module

2. 其他脚本引入模块

-- 引入模块
require("module")

print(module.name..module.time)

print(module.func1())
print(module.func3())

运行结果:

三、元表

元表允许改变table的行为,对table变相的进行扩展,甚至能达到模拟类的功能

1. 元表定义和使用

元表和table一样,使用{}定义,使用元表需要和普通表进行结合,调用setmetatable方法

a = {1,2,3} -- 普通表
b = {} -- 元表
c = setmetatable(a,b)

print("table:",a)
print("metatable:",b)
print("ret:",c)
print("getmetatable:",getmetatable(c))

运行结果:

可以发现setmetatable的返回值为普通表,getmetattable的返回值为元表

2. index元方法

index元方法定义方式为{__index = 值},有两种用途

2.1 结合两张普通表
-- 两张普通表
e = {'a','b'}
f = {c = 'c'}

-- 元表将index元方法赋值为f
g = {__index = f}

-- 为e表设置元表
setmetatable(e,g)

print(e['c'])

运行结果:

2.2 扩展没有对应key的取值方法
-- 普通表
e = {'a','b'}

-- 元表将index元方法赋值为一个函数
g = {
        __index = function(tab,key)
                if(key[tab] == nil) then
                        return 'null'
                end
        end     
}

-- 为e表设置元表
setmetatable(e,g)

print(e['c'])
print(e[1])

运行结果:

3. newindex元方法

newindex元方法定义方式为{__newindex = 值},也有两种用途

3.1 将新元素存入另一张普通表中
-- 两张普通表
e = {'a','b'}
f = {}

-- 元表将newindex元方法赋值为f
g = {__newindex = f}

-- 为e表设置元表
setmetatable(e,g)

-- 设置新元素
e[5] = 'f'
print(e[5])
print(f[5])

运行结果:

3.2 扩展插入新元素方法
-- 普通表
e = {'a','b'}

-- 元表将newindex元方法赋值为匿名函数
g = {
        __newindex = function(tab,key,val)
                print("新key:"..key,"新value:"..val)
                rawset(tab,key,val)
        end
}

-- 为e表设置元表
setmetatable(e,g)
e['a'] = 'hello'

print(e['a'])

运行结果:

4. 运算符重载

元表的运算符重载使用如下方式定义:

方式 对应运算符
__add +
__sub -
__mul *
__div /
__mod %
__concat ..
__eq ==
__lt <
__le <=
__gt >
__ge >=

测试,合并两个table:

-- 运算符重载
a = {'a','b'}
b = {'c','d'}

c = {
        __add = function(tab1,tab2)
                -- 获取第一个table的长度
                local t1_len = #tab1
                -- 遍历第二个table
                for k,v in pairs(tab2) do
                        t1_len = t1_len + 1
                        -- 将第二个tab的值赋值给第一个tab
                        tab1[t1_len] = v
                end
                return tab1
        end
}

setmetatable(a,c)
a = a + b

for k,v in pairs(a) do
        print(v)
end

运行结果:

5. call元方法

当表被当成函数调用时,会触发

-- call元方法
a = {1,2}

c = {
        __call = function(tab,...)
                for k,v in pairs({...}) do
                        print(k,v)
                end
        end
}

setmetatable(a,c)

a(1,2,3,5,6,7)

运行结果:

6. tostring元方法

重写打印的方法,和Java中类似


a = {'a','c','e'}


c = {
        __tostring = function(tab) 
                local ret = ''
                for k,v in pairs(tab) do
                        ret = ret..v..','
                end
                return ret
        end
}

setmetatable(a,c)

print(a)

运行结果:

上一篇下一篇

猜你喜欢

热点阅读