lua学习(二)

发布于:2025-03-06 ⋅ 阅读:(105) ⋅ 点赞:(0)

lua学习(二)

函数

定义格式

optional_function_scope function function_name( argument1, argument2, argument3..., argumentn)
    function_body
    return result_params_comma_separated
end

  • optional_function_scope: 该参数是可选的指定函数是全局函数还是局部函数,未设置该参数默认为全局函数,如果你需要设置函数为局部函数需要使用关键字 local

  • function_name: 指定函数名称。

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

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

  • result_params_comma_separated: 函数返回值,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
获取可变参数个数
function average(...)
   result = 0
   local arg={...}    --> arg 为一个表,局部变量
   for i,v in ipairs(arg) do
      result = result + v
   end
   print("总共传入 " .. #arg .. " 个数")
   print("总共传入 " .. select("#",...) .. " 个数")
   return result/#arg
end

print("平均值为",average(10,5,3,4,5,6))

注意事项:

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

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

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

f(0,1,2,3,4,5)

image.png

协同程序(协程)

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

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

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

复杂例子

function foo (a)
    print("foo 函数输出", a)
    return coroutine.yield(2 * a) -- 返回  2*a 的值
end
 
co = coroutine.create(function (a , b)
    print("第一次协同程序执行输出", a, b) -- co-body 1 10
    local 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("---分割线---")

生产者消费者模型

local newProductor

function productor()
     local i = 0
     while true do
          i = i + 1
          send(i)     -- 将生产的物品发送给消费者
     end
end

function consumer()
     while true do
          local i = receive()     -- 从生产者那里得到物品
          print(i)
     end
end

function receive()
     local status, value = coroutine.resume(newProductor)
     return value
end

function send(x)
     coroutine.yield(x)     -- x表示需要发送的值,值返回以后,就挂起该协同程序
end

-- 启动程序
newProductor = coroutine.create(productor)
consumer()

面对对象

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

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

继承

-- 定义矩形类
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  -- 设置长度,默认为 0
  o.breadth = breadth or 0  -- 设置宽度,默认为 0
  o.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"

多态

-- 定义一个"类"(实际上是一个表)
Person = {}

-- 为"类"添加一个构造函数
function Person:new(name, age)
    local obj = {}  -- 创建一个新的表作为对象
    setmetatable(obj, self)  -- 设置元表,表示它是Person类的实例
    self.__index = self  -- 设置索引元方法,指向Person
    obj.name = name
    obj.age = age
    return 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)
end

local 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"

网站公告

今日签到

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