Lua语言元表、协同程序

发布于:2025-08-13 ⋅ 阅读:(16) ⋅ 点赞:(0)

元表

元表的定义

允许我们改变table的行为。

setmetatable(普通表,元表)

-- 元表

a = {"a","b","c"} -- 普通表 b = {} --元表

c = setmetatable(a,b)

print("------------------------")

f = {}

print("f:",f)

d = setmetatable({"c","d"},f)

print(d[1])

e = getmetatable(d)

print("e:",e)

index元方法

__index (两个下划线)

定义普通表 p。

给普通表p,设置元表y,而元表y中有__index,__index=一个表 i,i中有 我们访问的那个不存在的 key。

__index=表

print("-------------测试__index---------------") -- 普通表

tab1 = {"a","b","c"}

print(tab1[5])

-- 普通表,有一个元素 5="e" newTab = {}

newTab[5] = "e"

metaTab1 = {__index=newTab}

setmetatable(tab1, metaTab1)

print(tab1[5])

--index=函数(表,key)

-- 普通表

tab1 = {"a","b","c"} print(tab1[5])

print("原始的tab1:",tab1)

metaTab1 = {

__index=function(tab, key )

print("参数当中的tab:",tab)

print("参数当中的key:",key)

if(key == 5) then

return "index--5" end

end

}

setmetatable(tab1, metaTab1)

print(tab1[5])

请求表中key的值:

先在普通表中找,有返回,没有,看元表。

如果元表有__index, 且 __index中有对应的key。 如果没有,继续找__index的function。

newindex元方法

对表进行更新时调用。

函数用法

print("-----------newindex--------------") mytab2 = {"a","b"}

metatab2 = {

__newindex = function(tab, key ,value)

print("被调用")

-- tab[key] = value

rawset(tab,key,value)

end

}

setmetatable(mytab2,metatab2)

mytab2[3]="c"

print(mytab2[3])



表



mytab2 = {"a","b"}

mytab21 = {} metatab2 = {

__newindex = mytab21

}

setmetatable(mytab2,metatab2)

mytab2[3]="c"

print(mytab2[3])

print(mytab2[3])

为表添加操作符

加法操作

print("-------------操作符------------") tab3 = {"1","2"}

tab4 = {"a","b","c"}

metatab3 = {

__add = function(tab1,tab2) local m = #tab1

for k,v in pairs(tab2)

do

m = m+1

tab1[m] = v

end

return tab1

end

}

setmetatable(tab3,metatab3)

v = tab3 + tab4 print(v)

for k,v in pairs(v) do

print(k,v) end

__add:+ __sub: - _mul:*   __div: /

__mod: %

__concat: ..

__eq:== __lt: <

_le: <=

call元方法

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

print("-----------call-------------") tab_a1 = {"a","b"}

print("tab_a1原始值:",tab_a1) tab_a2 = {"1","2"}

metatab_a = {

__call = function(tab, ...)

local a = {...}

for k,v in pairs(a) do

print(v)

end

end

}

setmetatable(tab_a1,metatab_a)

result = tab_a1(6,7,8)

tostring

用于修改表的输出行为。类似于java中的toString()。

print("-----------call-------------") tab_a1 = {"a","b","c","d"}

print("tab_a1原始值:",tab_a1) tab_a2 = {"1","2"}

metatab_a = {

__call = function(tab, ...)

local a = {...}

for k,v in pairs(a) do

print(v)

end

end,

__tostring = function(tab)

local str = ""

for k,v in pairs(tab) do

str = str..v..","

return str end

}

setmetatable(tab_a1,metatab_a) -- result = tab_a1(6,7,8)

print(tab_a1)

ps:每个元方法之间 用 ,

协同程序

类似于 多线程的概念。

协程和线程的区别:

一个多线程的程序,可以同时运行多个线程。而协程呢,在某个时刻,只有一个协程在运行。 线程由cpu调度,协程由代码调度。

创建协程,并运行:

# 定义协程

testAdd = coroutine.create( function(a,b)

print(a+b)

end

)

# 启动协程

# 原来暂停-》执行,原来执行-》暂停 coroutine.resume(testAdd, 1,2)

wrap

co = coroutine.wrap(

function(a)

print("参数值是:"..a)

end

)

co(2)

启动、停止

testAdd = coroutine.create(

function(a,b)

print("执行--子方法",a+b)

coroutine.yield();

print("执行--子方法",a-b)

end

)

coroutine.resume(testAdd, 1,7)



print("执行主方法")

coroutine.resume(testAdd)

返回值

testAdd = coroutine.create(

function(a,b)



print("协程执行",a+b)

coroutine.yield()

return a+b,a-b end

)

r1,r2,r3 = coroutine.resume(testAdd, 1,7)

print("返回值:",r1,r2,r3)

r1,r2,r3 = coroutine.resume(testAdd, 1,7)

print("重新执行,返回值:",r1,r2,r3)

协程状态

testAdd = coroutine.create(

function(a,b)

print("运行中 协程状态:",coroutine.status(testAdd)) coroutine.yield()

return a+b,a-b end

)



print("刚定义好的协程状态:",coroutine.status(testAdd))

r1 = coroutine.resume(testAdd,1,4)

print("启动协程结果:",r1)



print("最终的 协程状态:",coroutine.status(testAdd))



print("yield后 协程状态:",coroutine.status(testAdd))

r1 = coroutine.resume(testAdd,1,4)

print("二启动协程结果:",r1)



print("二最终的 协程状态:",coroutine.status(testAdd))



r1 = coroutine.resume(testAdd,1,4)

print("三启动协程结果:",r1)



结果:



刚定义好的协程状态:    suspended

运行中 协程状态:       running

启动协程结果:  true

最终的 协程状态:       suspended

yield后 协程状态:      suspended

二启动协程结果:        true

二最终的 协程状态:     dead

三启动协程结果:        false

协程协作

协程唯一标识



testAdd = coroutine.create(

function(a,b)

print(coroutine.running)

print("1") end

)

coroutine.resume(testAdd,1,1)



协程内部和外部协作的例子:



-- 协程内外部协作的例子 function foo(a)

print("foo 参数:",a)

return coroutine.yield(a*2) end

co = coroutine.create(

function(a,b)

print("第一次启动协程,参数:",a,b) local r = foo(a+1)

print("第二次启动协程,参数",r)



local x,y = coroutine.yield(a+b,a-b)

print("第三次启动协程,参数",x,y)



return b,"协程结束啦"

end

)

print("主程序:",coroutine.resume(co,1,5))

print("----分隔符---")

print("主程序:",coroutine.resume(co,"r"))

print("----分隔符---")

print("主程序:",coroutine.resume(co,"x","y"))

print("----分隔符---")

print("主程序:",coroutine.resume(co))



第一次resume,传入的参数是 function的参数。

第一次yield的参数,是第一次resume的返回值。

第二次resume的参数,是第一次yield的 返回值。

生产者消费者问题

思路:

1。生产者生产完 产品,(自己停下来),等待消费者消费。

2。消费者消费完产品,(自己停下来),等待生产者生产。



-- 生产者和消费者

function productor()

-- 定义生产的商品,用数字来替代 local i = 0

while i<100

do

i = i+1

print("生产了:",i)

-- 通过协程实现

coroutine.yield(i) end

end



function consumer() while true

do

-- 从生产者获取产品

local status,result = coroutine.resume(po) print("消费了:",result)

if (result == 99) then

break

end

end



end

-- 程序开始

po = coroutine.create(productor)

consumer()


网站公告

今日签到

点亮在社区的每一天
去签到