当前位置: 首页 > backend >正文

Lua语言元表、协同程序

元表

元表的定义

允许我们改变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) thenreturn "index--5" endend}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] = valuerawset(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 = #tab1for k,v in pairs(tab2)dom = m+1tab1[m] = vendreturn tab1end}setmetatable(tab3,metatab3)v = tab3 + tab4 print(v)for k,v in pairs(v) doprint(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) doprint(v)endend}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) doprint(v)endend,__tostring = function(tab)local str = ""for k,v in pairs(tab) dostr = 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)wrapco = 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最终的 协程状态:       suspendedyield后 协程状态:      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) endco = 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 = 0while i<100doi = i+1print("生产了:",i)-- 通过协程实现coroutine.yield(i) endendfunction consumer() while truedo-- 从生产者获取产品local status,result = coroutine.resume(po) print("消费了:",result)if (result == 99) thenbreakendendend-- 程序开始po = coroutine.create(productor)consumer()

http://www.xdnf.cn/news/17405.html

相关文章:

  • JavaWeb(苍穹外卖)--学习笔记17(Apache Echarts)
  • LightGBM 与 GBDT 在机器学习中的性能与特点比较
  • Graph-R1:一种用于结构化多轮推理的智能图谱检索框架,并结合端到端强化学习
  • 【最后203篇系列】031 构建MCP尝试
  • Docker Compose 部署高可用 MongoDB 副本集集群(含 Keepalived + HAProxy 负载均衡)
  • 从零学习three.js官方文档(二)——图元
  • 去除Edge微软浏览器与Chrome谷歌浏览器顶部出现“此版本的Windows不再支持升级Windows 10”的烦人提示
  • JavaWeb(苍穹外卖)--学习笔记18(Apache POI)
  • 安全引导功能及ATF的启动过程(五)
  • 数据结构:栈和队列(Stack Queue)基本概念与应用
  • AI编程插件对比分析:CodeRider、GitHub Copilot及其他
  • 云服务器最新版MySQL 安装步骤
  • 第4章 程序段的反复执行1 for语句P115练习题(题及答案)
  • Matlab系列(004) 一 Matlab分析正态分布(高斯分布)
  • cuOpt_server错误分析
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘fastai’问题
  • 面试题-----Spring Cloud
  • LLM 的向量的方向表示语义,向量长度表示什么
  • 强化学习笔记:从Q学习到GRPO
  • 1.JavaScript 介绍
  • Linux系统编程Day10 -- 进程管理
  • 分治-快排-面试题 17.14.最小k个数-力扣(LeetCode)
  • 在 Vue 中动态引入SVG图标的实现方案
  • Horse3D引擎研发笔记(三):使用QtOpenGL的Shader编程绘制彩色三角形
  • 第十九天-输入捕获实验
  • Redis面试题及详细答案100道(01-15) --- 基础认知篇
  • synchronized和RentrantLock用哪个?
  • LangChain-Unstructured 基础使用:PDF 与 Markdown 处理解析
  • 深入解析进程创建与终止机制
  • RAG-大模型课程《李宏毅 2025》作业1笔记