Lua基本语法与面向对象

目录

  • 一、Lua基本语法
    • 1、Lua中的数据类型
    • 2、Lua中的元表
    • 3、Lua中的闭包
    • 4、Lua中的协程
    • 5、其他知识
  • 二、Lua实现面向对象
    • 1、封装
    • 2、继承
    • 3、多态
  • 三、总结

一、Lua基本语法

1、Lua中的数据类型

类型 描述
nil 表示一个无效值(在条件表达式中相当于false)
boolean 包含两个值:false和true
number 表示双精度类型的实浮点数
string 字符串由一对双引号或单引号来表示
function 由 C 或 Lua 编写的函数
userdata 表示任意存储在变量中的C数据结构
thread 表示执行的独立线路,用于执行协同程序
table Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。

2、Lua中的元表

在Lua中,元表(metatable)是一种特殊的表,用于控制其他表的行为。每个表都可以关联一个元表,通过元表可以重定义表的操作。
设置元表:setmetatable(t1,t2),将t2设置为t1的元表
获得元表:getmetatable(t),获取t的元表

元表中的操作 描述
__tostring 当子表被当做字符串使用时,会调用元表中的tostring方法
__call 当子表被当做函数调用时,会调用该方法
__index 当子表找不到变量时,会去元表中查找
__newIndex 当子表赋值一个不存在的变量时,会赋值到 __newIndex指定的表中
__运算符重载 __add,__sub,__mul等,子表使用+,-,*等符号时会调用重载的方法

3、Lua中的闭包

闭包(Closure)是指在一个函数内部定义的函数,并且可以访问外部函数的变量。换句话说,闭包是一个函数加上其相关的引用环境组合而成的实体。
闭包的作用:可以获取外部函数的变量,并且改变局部变量的生命周期,例如本例:传入参数x的值11,一直保存到了执行f(6)时

print("------------闭包---------------")
function Fun1(x)
	--改变传入参数的生命周期
	Fun2=function(y)
		print("内部函数"..x+y)
	end
	return Fun2
end

f=Fun1(11)
f(6)

运行结果
Lua基本语法与面向对象_第1张图片

4、Lua中的协程

在Lua中,协程(coroutine)是一种轻量级的线程,可以在不同的执行流之间进行切换。协程可以用于实现协作式多任务处理,允许程序在需要的时候暂停和恢复执行。
注意:Lua中没有多线程,但是可以用协程实现类似多线程的效果,Lua中的协程与C#不同,不会自动连续执行,需要手动resume

Lua中的协程通过coroutine库来实现。coroutine库提供了一些函数来创建和控制协程,包括:

coroutine.create(function):创建一个新的协程,参数为一个函数,该函数为协程的主体。

coroutine.resume(coroutine, …):启动或恢复一个协程的执行。第一个参数为协程对象,后面的参数会传递给协程主体函数。

coroutine.yield(…):暂停当前协程的执行,并返回给调用者。可以通过yield函数将控制权交给其他协程。

coroutine.status(coroutine):获取协程的状态,返回字符串"running"、“suspended”、“normal”、“dead”。

除了上述基本函数外,coroutine库还提供了一些辅助函数,如:

coroutine.wrap(function):将一个函数包装成一个协程,返回一个可直接调用的函数。

coroutine.running():返回当前正在执行的协程对象。
示例代码:

local function foo()
    for i = 1, 5 do
        print("foo", i)
        coroutine.yield()
    end
end

local co = coroutine.create(foo)

for i = 1, 10 do
    print("main", i)
    coroutine.resume(co)
end

运行结果
Lua基本语法与面向对象_第2张图片

5、其他知识

lua中的下标从1开始,而不是0
pairs和ipairs区别
ipairs:不能找到0和0以下的自定义索引的内容,如果nil会退出
pairs:可以得到所有值,包括nil
语法:for i,k in pairs(table) do
end

项目 描述
self 默认传入的第一个参数
: 和 . 区别 “:” 会把调用者默认当成第一个参数传入,“.”不会
_G表 一个特殊的表,用于存储全局变量和全局函数。
local lua中不添加local关键字的变量都是全局变量,会存储在G表中,可以被require,添加local关键字成为局部变量

二、Lua实现面向对象

1、封装

封装是面向对象编程中的一个重要概念,它指的是将数据和方法包装在一个类中,并对外部隐藏内部实现的细节。通过封装,可以控制对类的访问,并确保数据的安全性和完整性。

Lua中的表其实就表现出了封装的特型,只不过不能使用访问修饰符,我们只需要添加new方法就可以了。原理:利用元表和__index关键字,实现了类似类和对象的效果

--封装
Object={}
Object.id=1

function Object:Test()
	print(self.id)
end

function Object:new()
	local obj={}
	--子表找不到变量时去元表指定的表中查找,这里指定为元表本身,就实现了类似类和对象的效果
	self.__index=self
	--设置元表
	setmetatable(obj,self)
	return obj
end

local myObj=Object:new()
print(myObj.id)
myObj.Test(myObj)

运行结果
在这里插入图片描述

2、继承

继承是面向对象编程中的一个重要概念,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。通过继承,子类可以拥有父类的特性,并且可以在此基础上添加自己的特性。

原理:在G表中添加要创建的子类,并用元表和__index实现父类效果

--继承
print("------------继承--------------")
function Object:subClass(className)
	_G[className]={}
	local obj=_G[className]
	self.__index=self
	--子类中的base属性代表父类
	obj.base=self
	setmetatable(obj,self)
end

Object:subClass("Person")
print(Person.id)

local p1=Person:new()
print(p1.id)

Person:subClass("Son")
local s1=Son:new()
print(s1.id)
s1.id=70
print(s1.id)

运行结果
Lua基本语法与面向对象_第3张图片

3、多态

多态的概念:多态指的是同一个方法或操作可以在不同的对象上产生不同的行为。简单来说,多态是指一个对象可以根据当前的实际类型来选择调用哪个方法。

原理:

print("------------多态--------------")
Object:subClass("GameObj")
GameObj.posX=0;
GameObj.posY=0;
function GameObj:Move()
	self.posX=self.posX+1
	self.posY=self.posY+1
	print(self.posX)
	print(self.posY)
end

GameObj:subClass("Player")
function Player:Move()
	--调用方法时传入自己,修改的就是自己的属性
	self.base.Move(self)
end

local p1=Player:new()
p1:Move()


local p2=Player:new()
p2.posY=3
p2:Move()

运行结果
Lua基本语法与面向对象_第4张图片

三、总结

lua中比较简单的知识就不列出了,本文列出了lua语法中比较重要的知识点

你可能感兴趣的:(lua,junit,开发语言)