lua学习(二)

ops/2025/3/4 19:20:24/

lua_0">lua学习(二)

函数

定义格式

lua">optional_function_scope function function_name( argument1, argument2, argument3..., argumentn)function_bodyreturn result_params_comma_separated
end
  • optional_function_scope: 该参数是可选的指定函数是全局函数还是局部函数,未设置该参数默认为全局函数,如果你需要设置函数为局部函数需要使用关键字 local

  • function_name: 指定函数名称。

  • argument1, argument2, argument3…, argumentn: 函数参数,多个参数以逗号隔开,函数也可以不带参数。

  • function_body: 函数体,函数中需要执行的代码语句块。

  • result_params_comma_separated: 函数返回值,Lua语言函数可以返回多个值,每个值以逗号隔开。

可变参数

在函数参数列表中使用三点  表示函数有可变的参数。传入函数的个数可以变。

lua">function add(...)  
local s = 0  for i, v in ipairs{...} do   --> {...} 表示一个由所有变长参数构成的数组  s = s + v  end  return s  
end  
print(add(3,4,5,6,7))  --->25
获取可变参数个数
lua">function average(...)result = 0local arg={...}    --> arg 为一个表,局部变量for i,v in ipairs(arg) doresult = result + vendprint("总共传入 " .. #arg .. " 个数")print("总共传入 " .. select("#",...) .. " 个数")return result/#arg
endprint("平均值为",average(10,5,3,4,5,6))

注意事项:

  • 固定参数必须放在变长参数之前
select
  • select(‘#’, …) 返回可变参数的长度。

  • select(n, …) 用于返回从起点 n 开始到结束位置的所有参数列表。

lua">function f(...)a = select(3,...)  -->从第三个位置开始,变量 a 对应右边变量列表的第一个参数print (a)print (select(3,...)) -->打印所有列表参数
endf(0,1,2,3,4,5)

image.png

协同程序(协程)

yield:返回值并等待后续协程传入的参数

resume:启动协程,并传递参数到协程中

lua">function foo()print("协同程序 foo 开始执行")local value = coroutine.yield("暂停 foo 的执行")print("协同程序 foo 恢复执行,传入的值为: " .. tostring(value))print("协同程序 foo 结束执行")
end-- 创建协同程序
local co = coroutine.create(foo)-- 启动协同程序
local status, result = coroutine.resume(co)
print(result) -- 输出: 暂停 foo 的执行-- 恢复协同程序的执行,并传入一个值
status, result = coroutine.resume(co, 42)-- 此时将42赋值给value
print(result) -- 输出: 协同程序 foo 恢复执行,传入的值为: 42

复杂例子

lua">function foo (a)print("foo 函数输出", a)return coroutine.yield(2 * a) -- 返回  2*a 的值
endco = coroutine.create(function (a , b)print("第一次协同程序执行输出", a, b) -- co-body 1 10local r = foo(a + 1)print("第二次协同程序执行输出", r)local r, s = coroutine.yield(a + b, a - b)  -- a,b的值为第一次调用协同程序时传入,将a+b,a-b输出,等待协程传参,用r,s接收print("第三次协同程序执行输出", r, s)return b, "结束协同程序"                   -- b的值为第二次调用协同程序时传入
end)print("main", coroutine.resume(co, 1, 10)) -- true, 4
print("--分割线----")
print("main", coroutine.resume(co, "r")) -- true 11 -9
print("---分割线---")
print("main", coroutine.resume(co, "x", "y")) -- true 10 end
print("---分割线---")
print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine
print("---分割线---")

生产者消费者模型

lua">local newProductorfunction productor()local i = 0while true doi = i + 1send(i)     -- 将生产的物品发送给消费者end
endfunction consumer()while true dolocal i = receive()     -- 从生产者那里得到物品print(i)end
endfunction receive()local status, value = coroutine.resume(newProductor)return value
endfunction send(x)coroutine.yield(x)     -- x表示需要发送的值,值返回以后,就挂起该协同程序
end-- 启动程序
newProductor = coroutine.create(productor)
consumer()

面对对象

Lua 中的类可以通过 table + function 模拟出来。

关键是使用__index方法和元表来实现继承和多态

继承

lua">-- 定义矩形类
Rectangle = {area = 0, length = 0, breadth = 0}-- 创建矩形对象的构造函数
function Rectangle:new(o, length, breadth)o = o or {}  -- 如果未传入对象,创建一个新的空表setmetatable(o, self)  -- 设置元表,使其继承 Rectangle 的方法self.__index = self  -- 确保在访问时能找到方法和属性o.length = length or 0  -- 设置长度,默认为 0o.breadth = breadth or 0  -- 设置宽度,默认为 0o.area = o.length * o.breadth  -- 计算面积return o
end-- 打印矩形的面积
function Rectangle:printArea()print("矩形面积为 ", self.area)
end-- 定义正方形类,继承自矩形类
Square = Rectangle:new()  -- Square 继承 Rectangle 类-- 重写构造函数(正方形的边长相等)
function Square:new(o, side)o = o or {}  -- 如果未传入对象,创建一个新的空表setmetatable(o, self)  -- 设置元表,使其继承 Rectangle 的方法self.__index = self  -- 确保在访问时能找到方法和属性o.length = side or 0  -- 设置边长o.breadth = side or 0  -- 正方形的宽度和长度相等o.area = o.length * o.breadth  -- 计算面积return o
end-- 运行实例:
local rect = Rectangle:new(nil, 5, 10)  -- 创建一个长为 5,宽为 10 的矩形
rect:printArea()  -- 输出 "矩形面积为 50"local square = Square:new(nil, 4)  -- 创建一个边长为 4 的正方形
square:printArea()  -- 输出 "矩形面积为 16"

多态

lua">-- 定义一个"类"(实际上是一个表)
Person = {}-- 为"类"添加一个构造函数
function Person:new(name, age)local obj = {}  -- 创建一个新的表作为对象setmetatable(obj, self)  -- 设置元表,表示它是Person类的实例self.__index = self  -- 设置索引元方法,指向Personobj.name = nameobj.age = agereturn obj
end-- 添加方法
function Person:greet()print("Hello, my name is " .. self.name)
end-- 定义一个子类 Student 继承自 Person
Student = Person:new()-- 子类重写父类的方法
function Student:greet()print("Hi, I'm a student and my name is " .. self.name)
endlocal person2 = Person:new("Charlie", 25)
local student2 = Student:new("David", 18)-- 多态:不同类型的对象调用相同的方法
person2:greet()  -- 输出 "Hello, my name is Charlie"
student2:greet()  -- 输出 "Hi, I'm a student and my name is David"

http://www.ppmy.cn/ops/163102.html

相关文章

fastjson1.2.24 CVE-2017-18349 漏洞复现

fastjson1.2.24 CVE-2017-18349 漏洞复现 时间不等人啊/(ㄒoㄒ)/~~ 0. 前置知识 建议直接看参考链接 JNDI:Java命名和目录接口 RMI:远程方法调用注册表 LDAP:轻量级目录访问协议 CORBA:公共对象请求代理体系结构 1. jndi …

机器视觉3D焊接机器人视觉跟踪系统核心技术解析

焊接机器人集成视觉跟踪系统的核心技术要素涉及多学科的交叉融合,其核心在于实现精准、实时、自适应的焊接过程控制。以下是五大关键要素及其技术解析: 高精度视觉感知技术 传感器选型与布局 采用工业级高速相机(如CCD/CMOS)、激光扫描仪或结构光传感器,需根据焊接场景(弧…

Github 2025-03-01 开源项目月报 Top19

根据Github Trendings的统计,本月(2025-03-01统计)共有19个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目9TypeScript项目6Jupyter Notebook项目2JavaScript项目2非开发语言项目1Svelte项目1Rust项目1Go项目1C++项目1Ollama: 本地大型语言模…

JS宏案例:在wps编辑器中玩numpy

NumPy 是 Python 中用于科学计算的一个基础库,它提供了大量的数学函数工具,尤其是用于高效处理大型多维数组和矩阵。NumPy 是 Python 数据分析、机器学习、科学计算等领域中不可或缺的一部分。 然,在wps的js宏编辑器中,并没有这样一个模块或是全局对象,但是,问题不大,我…

05. Springboot admin集成Actuator(一)

目录 1、前言 2、Actuator监控端点 2.1、健康检查 2.2、信息端点 2.3、环境信息 2.4、度量指标 2.5、日志文件查看 2.6、追踪信息 2.7、Beans信息 2.8、Mappings信息 3、快速使用 2.1、添加依赖 2.2、添加配置文件 2.3、启动程序 4、自定义端点Endpoint 5、自定…

【星云 Orbit • STM32F4】04.一触即发:GPIO 外部中断

【星云 Orbit- • STM32F4】04. 一触即发:外部中断控制 摘要 本文详细介绍了如何使用STM32F407微控制器的HAL库实现外部中断功能。通过配置GPIO引脚作为外部中断源,并在中断回调函数中处理按键事件,实现了按键控制LED状态翻转的功能。本文旨…

C# Equals 和 ReferenceEquals 使用详解

总目录 前言 在C#中,Equals 方法和 ReferenceEquals 方法用于比较对象,但它们的用途和行为有着显著的区别。理解这两者的差异对于编写高效且无误的代码至关重要。 一、Equals 方法 1. 定义 Equals 是 System.Object 类中的一个虚方法,用于…

【练习】【贪心】力扣452. 用最少数量的箭引爆气球

题目 用最少数量的箭引爆气球 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着 x 轴从不同点 完全垂直…