类型 | 描述 |
---|---|
nil | 表示一个无效值(在条件表达式中相当于false) |
boolean | 包含两个值:false和true |
number | 表示双精度类型的实浮点数 |
string | 字符串由一对双引号或单引号来表示 |
function | 由 C 或 Lua 编写的函数 |
userdata | 表示任意存储在变量中的C数据结构 |
thread | 表示执行的独立线路,用于执行协同程序 |
table | Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。 |
在Lua中,元表(metatable)是一种特殊的表,用于控制其他表的行为。每个表都可以关联一个元表,通过元表可以重定义表的操作。
设置元表:setmetatable(t1,t2),将t2设置为t1的元表
获得元表:getmetatable(t),获取t的元表
元表中的操作 | 描述 |
---|---|
__tostring | 当子表被当做字符串使用时,会调用元表中的tostring方法 |
__call | 当子表被当做函数调用时,会调用该方法 |
__index | 当子表找不到变量时,会去元表中查找 |
__newIndex | 当子表赋值一个不存在的变量时,会赋值到 __newIndex指定的表中 |
__运算符重载 | __add,__sub,__mul等,子表使用+,-,*等符号时会调用重载的方法 |
闭包(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中,协程(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中的下标从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中的表其实就表现出了封装的特型,只不过不能使用访问修饰符,我们只需要添加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)
继承是面向对象编程中的一个重要概念,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。通过继承,子类可以拥有父类的特性,并且可以在此基础上添加自己的特性。
原理:在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)
多态的概念:多态指的是同一个方法或操作可以在不同的对象上产生不同的行为。简单来说,多态是指一个对象可以根据当前的实际类型来选择调用哪个方法。
原理:
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中比较简单的知识就不列出了,本文列出了lua语法中比较重要的知识点