本文共 13598 字,大约阅读时间需要 45 分钟。
笔记相关–lua语法
前记:很久之前看的了,发到博客里记录一下-------------------mx
print("----------字符串---------")
Str = “双引号字符串” Str2=‘单引号字符串’–获取字符串的长度
print("----------字符串长度---------") S=“ACSsdad” S2=“速度” print(“字符长度”…#S) print(“汉字长度”…#S2)–字符串拼接通过 … 或者string提供的方法
–[[ string.format()字符串拼接 string.lower()字符串全变成大写 string.upper()字符串全变成小写 string.reverse()字符串翻转 string.find()字符串反转 string.sub()截取字符串 string.repl()字符串复制 string.gsub()字符串修改 string.byte(“Lua”,1)字符转ascii码 string.char()ascii码转字符串 =]]–字符运算常见的都有,以下是特殊的
print(“123.4”-1) print(“123.4”*2) print(“123.4”/2) print(“123.4”%2)–条件运算符与其他相同,特殊的:不等于 ~=
–逻辑运算符 and or not
print(true and true or (not false))–不支持位运算符,不支持三目运算符,需要自己实现
------------条件分支语句-------------
print("-----------条件分支语句-----------") a=5 if a > 5 then print(“123”) endif a < 5 then
print(“123”) else print(“456”) endif a < 5 then
print(“123”) elseif a>5 then print(“456”) else print(“789”) end –lua中没有switch语法 需要自己实现------------循环语句-------------
print("-----------循环语句-----------") –while语句 print("–While语句–") num=0 while num<5 do print(num) num=num +1 endprint("–do While语句–")
num=0 repeat print(num) num=num+1 until num>5 --,满足结束条件跳出,结束条件–博主:mx
print("–for语句–") for i=2,5 do–默认递增。i=i+1 print(i) end print("\n") for i=2,5,2 do–自定义增量,为第三个参数 print(i) end------------函数-------------
print("-----------函数-----------") –[[ function 函数命() 内容 end或者
a=function()
内容 end]]
print("–无参数无返回值函数–")
function F1() print(“F1函数”) end F1()F2=function()
print(“F2函数”) end F2()print("–有参数无返回值函数–")
function f3(a) print(a) end f3(1) f3(“123”) f3(true) –如果传入的阐述和函数个数不匹配,不会报错。只会补空,或者丢弃 f3() f3(1,2,3)print("–有返回值函数(可多返回值)–")
function F4(a)
return a,“123”,true,123 end temp=F4(1)print(temp)
–博主:mx print("\n") –[[ 多返回值是在前面声明多个变量来接取即可 如果变量不够,不影响,直接去对应位置的返回值 如果变量多了,多出来的会直接赋值nil ]] temp1,temp2,temp3,temp4=F4(1) print(temp1) print(temp2) print(temp3) print(temp4)print("–函数的类型–")
print(type(F4))print("–函数的重载–")
–函数命相同,参数类型不同,或者参数个数不同 –lua中函数不支持重载 –默认调用最后一个声明的函数 function F6() print(“好耶!”) end function F6(Str) print(Str) end F6()print("–函数:变长参数–")
–变长参数使用,用一个表存起来,再用 function F7(…) arg={…} for i = 1, #arg do print(arg[i]) end end F7(1,“123”,true,4,5,6)print("–函数:函数嵌套-")
function F8()return function () print("嵌套测试")end
end
f9=F8() f9()–面试题考点:lua的闭包体现? 改变传入参数的生命周期,如下
function F9(x) –改变传入参数的生命周期 return function (y) return x+y end endf10=F9(10)
print(f10(5))------------复杂数据类型-------------
print("-----------复杂数据类型 table-----------") print("-----------数组-----------") a={1,2,3,4,“123”,nil,true} for i = 1,7 , 1 do print(a[i]) endfor i = 1,#a , 1 do
print(a[i]) endprint("#获取得到的a的长度: ")
– #是通用的获取长度的关键字 在打印长度的时候,空nil被忽略,并认为数组已经结束 print(#a)print("-----------数组的遍历-----------")
for i = 1,7 , 1 do
print(a[i]) endprint("-----------二维数组-----------")
b={ {1,2,3},{4,nil,“sub”}} print(b[1][2])print("-----------二维数组的遍历-----------")
for i = 1, 2, 1 do for j = 1, 3, 1 do print(b[i][j]) end endprint("-----------自定义索引-----------")
c={[0]=1,2,3,[-1]=4,“num”,nil}print(c[0])
print(c[1]) print(c[2]) print(c[3]) print(c[4]) print(c[-1]) –博主:mx –自定义索引:在计算长度时,如果索引连续性被断掉,就只计算断之前的连续长度 print(#c)------------迭代器遍历-------------
print("-----------迭代器遍历-----------") –[[ 迭代器遍历主要是用来遍历表的,无法遍历nil空值 #得到长度,其实并不尊却,一般不要用#来遍历表 ]]print("-----------ipairs迭代器遍历-----------")
–[[ ipairs遍历还是从1开始往后遍历的,小于等于0的值得不到,无法遍历nil空值 只能找到连续索引的键,如果中间断序了,就无法遍历出后面的内容 ]] d={[0]=1,2,3,[-1]=4,“num”,[7]=nil} for i,k in ipairs(d) do print("ipairs遍历键: ") print(i) print("值: ") print(k) endprint("-----------pairs迭代器遍历-----------")
–[[ –它能够把所有的键都找到,通过键可以得到值,无法遍历nil空值 优先遍历原生索引,再遍历自定义索引 ]] for i, k in pairs(d) do print("pairs遍历键: ") print(i) print("值: ") print(k) end------------复杂数据类型–表2-------------
print("-----------字典-----------") print("–字典的声明–") –[[ 字典有键值对构成 访问单个变量,用键来访问,可以用中括号填键访问,也可以类似。成员变量来得到值(但是该成员变量不能是数字) ]] e={[“name”]=“小明”,[“age”]=15,[“1”]=5} print(e[“name”]) print(e[“age”]) print(e[“1”]) print(e.name) print(e.age) –修改成员变量 e[“name”]=“小红” print(e[“name”]) print(e.name) –新增成员变量 e[“sex”]=false print(e[“sex”]) print(e.sex) –删除,不存在实际意义上的删除,只能将成员变量置空 e[“sex”]=nil print(e[“sex”])print("–字典的遍历–")
–如果要遍历字典必须要用pairs,不能用ipairs,注意遍历无法遍历nil空值 for k, i in pairs(e) do print(k,i,1,“好耶!”) end –不能直接访问值,必须通过键来访问 for k in pairs(e) do print(k) print(e[k]) end for ,v in pairs(e) do print(v) print(,v) end –博主:mxprint("--------类和结构体-----------")
–[[
Lua中默认没有面向对象的,需要我们自己来实现 成员变量、成员函数 ]] Student={ –年龄 age=1, –性别 sex=true, –函数 Up=function () –这样写,这个age 和表中的age没有任何关系,它是一个该函数的全局变量 –print(age)--想要在表内部函数中,调用表本身的属性或者方法 --一定要指定是谁的,所以要使用表名.属性或者表名.方法 print(Student.age) print("我好起来了")end,Learn=function(k) print(k.sex) print ("好好学习、天天向上")end
}
–声明表过后,在表外去新增内容 Student.Up()–Lua中 .和冒号的区别
Student.Learn(Student) –冒号调用方法会默认把调用者作为第一个参数传入方法中 Student:Learn()Student.name=“好耶”
Student.Speak=function () print(“你说哪鸭”) endfunction Student.Speak2()
print(“我哪也没说”) end–冒号可以用来声明函数
–格式只能是function + 名字形式 声明 –如果是冒号声明相当于有一个默认参数,self就是用来冒号声明是作为第一个参数的代表的 –self
3 ````````!= this !!! function Student:Speak3() –Lua中self关键字 表示默认传入的第一个参数 print(self.name) print(“我哪也没说啊啊啊啊啊”) end –c#要是使用类。需要实例化对象new,静态直接点.
–Lua中类的实现,更像是一个类中有很多 静态变量和函数 print(Student.age)Student.Speak()
Student.Speak2()Student:Speak3()
Student.Speak3(Student)print("----------表的公共操作---------")
–表中 table 提供的一些公共方法的讲解t1={
{age=1,name=“123”},{age=2,name=“345”}} t2={name=“好耶”,sex=true} –插入 print("-插入-") print(#t1) table.insert(t1,t2) print(#t1)for i, v in pairs(t1) do
print(v); print(v.name); end–删除指定元素
print("-删除1-") –remove方法传一个参数(表)进去会移除最后一个索引的内容 table.remove(t1); for i, v in pairs(t1) do print(v); print(v.name); end –remove方法传两个参数(表)进去,第一个参数是要移除的表,第二个参数是要移除内容的索引 print("-删除2-") table.remove(t1,1); for i, v in pairs(t1) do print(v); print(v.name); end –排序 print("-默认排序-") t2={1,5,8,1,2,4,3} –sort传入要排序的表,默认升序排列 table.sort(t2) for i, v in pairs(t2) do print(v); end print("-规则排序-") t2={1,5,8,1,2,4,3} –sort传入两个参数,第一个是要排序的表,第二个是排序的规则函数 table.sort(t2,function (a,b) if a>b then return true end return false end) for i, v in pairs(t2) do print(v); end print("-拼接-") tb={“123”,“456”,“789”,“741852”} –concat连接函数,用于拼接表的元素,返回值,返回一个字符串,第一个参数是要连接表,第二个参数是连接的字符 str=table.concat(tb,nil) print(str) str=table.concat(tb,",") print(str)–博主:mx
print("----------多脚本执行---------")
print("-全局变量和本地变量-") –全局变量 a=1 b=“123” for i = 1, 2 do c=“好耶” end print© –本地(局部)变量的关键字 local 加了关键字之后他只在对应语句块中有效 for i = 1, 2 do local eee=“好耶” end print(eee) fun= function () local tt=“123123” end fun() print(tt) local tt2=“123” print(tt2)print("-多脚本执行-")
–关键字 require(“脚本名”) require(‘脚本名’) –在同一文件夹下不需要加路径,如果是不同文件夹则要 require(“Test”) print(testa) print(testlocalA) print("-脚本卸载-") –如果是require加载执行的脚本,加载过一次之后就不会再被执行 require(“Test”) –package.loaded[“脚本名”],返回值是boolean意思是是否被执行 print(package.loaded[“Test”]) –卸载已经执行过的脚本 package.loaded[“Test”]=nil print(package.loaded[“Test”]) –require执行一个脚本时,可以在脚本最后返回一个外部希望获取的内容 local testlA= require(“Test”) print(testlA) print("-大_G表-") –_G表是一个总表(table)他将我们声明的所有的全局变量都存储其中 for k, v in pairs(_G) do print(v); end –本地变量,加了local的变量是不会存到大_G表中print("----------协同程序---------")
print("----------协程的创建---------")
–coroutine.create() fun=function () print(123)end
co=coroutine.create(fun)–返回是一个线程 –协程的本质是一个线程对象 print(co) print(type(co))–coroutine.wrap()
co2=coroutine.wrap(fun)–返回是一个函数 print(co) print(type(co2))print("----------协程的运行---------")
–第一种方式,对应的是通过create创建的协程 coroutine.resume(co) –第二种方式 co2()print("----------协程的挂起---------")
fun2=function () local i=0 while true do print(123) i=i+1 –协程的挂起函数 coroutine.yield(i); end end co3=coroutine.create(fun2) –默认第一个返回值是协程是否启动成功 –第二个返回值是yield里面的返回值 tmp1,num1=coroutine.resume(co3) print(num1)co4=coroutine.wrap(fun2)
co4() –第一个返回值就是yield里面的返回值 num2=co4() print(num2)print("----------协程的状态---------")
–coroutine.status(协程状态) –dead 结束 –suspended 暂停 –running 进行中 print(coroutine.status(co3)) print(coroutine.status(co))–这个函数可以得到当前正在运行的协程的线程号
print(coroutine.running())print("----------元表---------")
print("----------元表的概念---------") –任何表变量都可以作为另一个表变量的原表 –任何表变量都可以有自己的元表(父表) –当我们子表中进行一些特殊操作是,会执行元表中的内容 print("----------元表的设置---------") meta={} myTable={} –设置元表函数 –第一个参数 子表 –第二个参数 元表 setmetatable(myTable,meta)–博主:mx
print("----------元表特殊操作---------") print("----------元表特殊操作-—_tostring---------") meta2={ –当子表中被当作字符串使用时会默认调用这个元表中的tostring方法 __tostring=function (t) return t.name end } myTable2={ name=“好耶” } –设置元表函数 –第一个参数 子表 –第二个参数 元表 setmetatable(myTable2,meta2) print(myTable2)print("----------元表特殊操作-—_call---------")
meta3={ –当子表中被当作字符串使用时会默认调用这个元表中的tostring方法 __tostring=function (t) return t.name end, –当元表被当作一个函数使用时,会默认调用这个__call中的内容 –当我们希望传参数时,默认第一个参数是调用者本身(子表),第二个才是要传入的参数 __call=function (a,b) print(a) print(b) print(“好哦”) end } myTable3={ name=“好耶” } –设置元表函数 –第一个参数 子表 –第二个参数 元表 setmetatable(myTable3,meta3) print(myTable3) myTable3(1)print("----------元表特殊操作-运算符重载---------")
meta4={ –相当于运算发重载,当子表使用+运算符时,会调用该方法 –运算符+ __add=function (t1,t2) return t1.age+t2.ageend,--运算符-__sub=function (t1,t2) return t1.age-t2.ageend,--运算符*__mul=function (t1,t2) return t1.age*t2.ageend,--运算符/__div=function (t1,t2) return t1.age/t2.ageend,--运算符%__mod=function (t1,t2) return t1.age%t2.ageend,--运算符^__pow=function (t1,t2) return t1.age^t2.ageend,--运算符==__eq=function (t1,t2) return trueend,--运算符<__lt=function (t1,t2) return falseend,--运算符<=__le=function (t1,t2) return trueend,--运算符..__concat=function (t1,t2) return ""end,
}
–博主:mx myTable4={age=1} setmetatable(myTable4,meta4) myTable5={age=5} setmetatable(myTable5,meta4) print(myTable4+myTable5) print(myTable4-myTable5) print(myTable4*myTable5) print(myTable4/myTable5) print(myTable4%myTable5) print(myTable4^myTable5)–如果要使用条件运算符,来比较两个对象
–这两个对象的元表必须要一致,才能准确调用方法 print(myTable4==myTable5) print(myTable4<myTable5) print(myTable4<=myTable5)print(myTable4…myTable5)
print("----------元表特殊操作-_index和_newIndex---------")
meta5Father={ age=3}
meta5Father.__index=meta5Father meta5={}
meta5.__index=meta5 myTable6={} setmetatable(meta5,meta5Father) setmetatable(myTable6,meta5)–__index当子表中找不到某个属性时
–会到元表中__index指定的表去找索引 print(myTable6.age)–_newIndex当复制时,如果赋值一个不存在的索引
–那么会把这个值赋值到newIndex所指的表中,不会修改自己 meta7={} meta7.__newindex={} myTable7={} setmetatable(myTable7,meta7) myTable7.age=1 print(myTable7.age) print(meta7.__newindex.age)print("----------元表的其他操作---------")
–得到元表的方法 print(getmetatable(myTable7))–rawget 当我们使用它时,会去找自己身上有没有这个变量
print(rawget(myTable6,“age”))–rawset 该方法会忽略newIndex的设置 只会改自己变量
rawset(myTable7,“age”,2) print(myTable7.age)print("----------面向对象---------")
print("----------封装---------") –面向对象 类 其实都是基于table来实现 –重点相关 元表相关知识点 Object={} Object.id=1 Object.__index=Object –冒号 是会自动将调用这个函数的对象 作为第一个参数传入的写法 function Object:new() –self 代表的是我们默认传入的第一个参数 –对象就是变量,返回一个新的变量 –返回出去的内容本质上就是表对象 local obj={} –元表知识 __index当找自己的变量 找不到时就会去找元表当中—__index只想的内容 setmetatable(obj,self) return obj end function Object:Test() –body print(self.id) end local myobj=Object:new() print(myobj) print(myobj.id) myobj:Test() –相当于对空表中声明一个新的属性 叫做id myobj.id=2 myobj:Test()print("----------继承---------")
–重点相关大G表 function Object:subClass(className) –大G表的知识点 是总表 所有声明的全局变量,都以键值对的形式存在其中 _G[className]={} –写相关继承的规则 –用到元表 local obj=_G[className] obj.__index=obj obj.base=self setmetatable(obj,self) –博主:mx end Object:subClass(“Person”) local personObj= Person:new() print(personObj.id)Object:subClass(“Monster”)
local monsterObj= Monster:new() print(monsterObj.id)print("----------多态---------")
Object:subClass(“GameObject”) GameObject.posX=0; GameObject.posY=0; function GameObject:Move() self.posX=self.posX+1 self.posY=self.posY+1 print(self.posX) print(self.posY) endGameObject:subClass(“Player”)
function Player:Move() –base指得gameobject表(类) –base:Move这种方式调用相当于把积累表作为第一个参数传入了方法中 --目前这种写法有坑,不同对象使用的成员变量,居然是相同的成员变量,不是自己的 –因此要避免把基类表传入到方法中,这样相当于就是公用了一张表的属性了 –我们如果要执行父类逻辑,我们不要直接使用冒号调用 –要通过.调用,然后自己传入第一个参数 self.base.Move(self) end local p1=Player:new() p1:Move() local p2=Player:new() p2:Move() p1:Move()print("----------面向对象示例---------")
object={}
function object:new() local obj={} self.__index=self obj.base=self setmetatable(obj,self) return obj end function object:subClass(className) _G[className]={} local obj=_G[className] obj.base=self self.__index=self setmetatable(obj,self) endobject:subClass(“gameobject”)
gameobject.posX=0 gameobject.posY=0 function gameobject:Move() self.posX=self.posX+1 self.posY=self.posY+1 endlocal OBJ=gameobject:new()
print(OBJ.posX) OBJ:Move() print (OBJ.posX)gameobject:subClass(“player”)
function Player:Move() self.base.Move(self) endlocal p3=player:new()
print(p3.posX) p3:Move() print(p3.posX) –博主:mxprint("----------自带库---------")
–string –table print("----------时间---------") –系统时间 print(os.time()) –自己传入参数,得到时间 print(os.time({year = 2014,month = 8,day = 14})) –os.date("*t") local nowTime=os.date("*t") for k, v in pairs(nowTime) do print(k,v) end print("----------数学运算---------") –math –绝对值 print(math.abs(-11)) –弧度转角度 print(math.deg(math.pi)) –三角函数 传弧度 print(math.cos(math.pi)) –向上向下取整 print(math.floor(2.6)) print(math.ceil(5.2)) –最大最小值 print(math.max(1,2)) print(math.max(4,2)) –小数分离 分数整数部分和小数部分 print(math.modf(1.2)) –幂运算 print(math.pow(2,5)) –随机数 –先设置随机数种子 math.randomseed(os.time()) print(math.random(100)) print(math.random(100)) –开方 print(math.sqrt(4)) print("----------路径---------") –lua脚本加载路径 print(package.path) package.path=package.path…";C:\" print(package.path)print("----------lua垃圾回收---------")
test={id=1,name=“123123”} –垃圾回收关键字 –collectgarbage–获取当前lua占用的内存储 k字节数,用返回值*1024,就可以得到具体的内存占用字节数
print(collectgarbage(“count”)) –lua中机制和C#中垃圾回收机制,会把野指针野内存释放 test=nil–进行垃圾回收
collectgarbage(“collect”) print(collectgarbage(“count”)) –lua中有自动定时进行GC的方法 –unity中热更新开发,尽量不要用自动垃圾回收,在跳转场景或内存达到瓶颈时要垃圾回收–博主:mx
转载地址:https://blog.csdn.net/m0_56399931/article/details/118228413 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!