
☺lua和javaScript差不多的,就是一些语法的细节不同,学过js,再注意一下下面的细节,就能上手了~快速入门,可以直接看一下菜鸟教程的lua:ht
博客园 2023-04-04 22:34:11
Lua 和 Js 的不同Lua 概述Lua概述Lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。Lua特性☺ lua 和 javaScript 差不多的,就是一些语法的细节不同,学过js,再注意一下下面的细节,就能上手了~
(资料图片仅供参考)
快速入门,可以直接看一下菜鸟教程的lua:https://www.runoob.com/lua/lua-tutorial.html
1.轻量级
使用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。2.可扩展
Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。3.其它特性
支持面向过程(procedure-oriented)编程和函数式编程(functional programming)
自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象、字典,并且table是变长变量
语言内置模式匹配;闭包(closure);函数也可以看做一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持
通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等
1、注释(1) 单行注释:--
(2) 多行注释:--[[ 多行注释 多行注释 --]]
2、变量全局变量:默认情况下,没有被local 修饰的变量都是全局变量,不管它的位置在哪里访问一个没有初始化的全局变量也不会出错,只不过得到的结果是:nil如果你想删除一个全局变量,只需要将变量赋值为nil。局部变量[私有
]local 修饰nil (空)字符串字符串由一对双引号或单引号来表示
也可以用 2 个方括号 "[[]]" 来表示"一块"字符串
string1 = "this is string1"string2 = "this is string2"html = [[ 菜鸟教程]]print(html)
☺ 字符串拼接,使用的是 ..-- 举例子:> print("a" .. "b")ab> print(157 .. 428)157428
加号 + ,这和java有区别,会把字符串转成数学的加分运算
-- 举例子:> print("2" + 6)8.0> print("2" + "6")8.0
计算字符串长度,使用#> len = "www.runoob.com"> print(#len)
3、循环语句、判断语句循环语句(1) whilewhile(condition)do statementsend
(2) forvar 从 exp1 变化到 exp2,每次变化以 exp3 为步长递增 var,并执行一次 "执行体"。exp3 是可选的,如果不指定,默认为1。
for var=exp1,exp2,exp3 do <执行体> end -- 举例子:tab1 = { key1 = "val1", key2 = "val2", "val3" }for k, v in pairs(tab1) do print(k .. " - " .. v)end
(3) repeaterepeat statementsuntil( condition )
判断语句--[ 0 为 true ]if(0)then print("0 为 true")end
4、函数获取可变参数的长度,也是使用#变量,或者使用select方法-- 举例子:function average(...) result = 0 local arg={...} --> arg 为一个表,局部变量 for i,v in ipairs(arg) do result = result + v end print("总共传入 " .. #arg .. " 个数") return result/#argendprint("平均值为",average(10,5,3,4,5,6))-----------------------------------function average(...) result = 0 local arg={...} for i,v in ipairs(arg) do result = result + v end print("总共传入 " .. select("#",...) .. " 个数") return result/select("#",...)endprint("平均值为",average(10,5,3,4,5,6))
5、select 方法select("#", …)返回可变参数的长度。select(n, …)用于返回从起点 n开始到结束位置的所有参数列表如果这时候使用一个变量指向方法 select(n, …),它只会得到第 n 位置的参数值function f(...) a = select(3,...) -->从第三个位置开始,变量 a 对应右边变量列表的第一个参数 print (a) print (select(3,...)) -->打印所有列表参数endf(0,1,2,3,4,5)-- 结果:22 3 4 5
6、lua 的运算符通用的加减乘除外,还有整除 // , 比如:5//2输出结果 2
不等于 ~=
逻辑运算符:and、or、not
其他运算符:
7、转义字符.. 连接两个字符串
# 一元运算符,返回字符串或表的长度
所有的转义字符和所对应的意义:
转义字符 | 意义 | ASCII码值(十进制) |
---|---|---|
\a | 响铃(BEL) | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\v | 垂直制表(VT) | 011 |
\ | 代表一个反斜线字符""" | 092 |
" | 代表一个单引号(撇号)字符 | 039 |
" | 代表一个双引号字符 | 034 |
\0 | 空字符(NULL) | 000 |
\ddd | 1到3位八进制数所代表的任意字符 | 三位八进制 |
\xhh | 1到2位十六进制所代表的任意字符 | 二位十六进制 |
Lua 提供了很多的方法来支持字符串的操作:
序号 | 方法 & 用途 |
---|---|
1 | string.upper(argument):字符串全部转为大写字母。 |
2 | string.lower(argument):字符串全部转为小写字母。 |
3 | string.gsub(mainString,findString,replaceString,num)在字符串中替换。mainString 为要操作的字符串, findString 为被替换的字符,replaceString 要替换的字符,num 替换次数(可以忽略,则全部替换),如:> string.gsub("aaaa","a","z",3); zzza 3 |
4 | string.find (str, substr, [init, [plain]])在一个指定的目标字符串 str 中搜索指定的内容 substr,如果找到了一个匹配的子串,就会返回这个子串的起始索引和结束索引,不存在则返回 nil。init指定了搜索的起始位置,默认为 1,可以一个负数,表示从后往前数的字符个数。plain表示是否使用简单模式,默认为 false,true 只做简单的查找子串的操作,false 表示使用使用正则模式匹配。以下实例查找字符串 "Lua" 的起始索引和结束索引位置:> string.find("Hello Lua user", "Lua", 1) 7 9 |
5 | string.reverse(arg)字符串反转> string.reverse("Lua") auL |
6 | string.format(...)返回一个类似printf的格式化字符串> string.format("the value is:%d",4) the value is:4 |
7 | string.char(arg) 和 string.byte(arg[,int])char 将整型数字转成字符并连接, byte 转换字符为整数值(可以指定某个字符,默认第一个字符)。> string.char(97,98,99,100) abcd > string.byte("ABCD",4) 68 > string.byte("ABCD") 65 > |
8 | string.len(arg)计算字符串长度。string.len("abc") 3 |
9 | string.rep(string, n)返回字符串string的n个拷贝> string.rep("abcd",2) abcdabcd |
10 | ..链接两个字符串> print("www.runoob.".."com") www.runoob.com |
11 | string.gmatch(str, pattern)返回一个迭代器函数,每一次调用这个函数,返回一个在字符串 str 找到的下一个符合 pattern 描述的子串。如果参数 pattern 描述的字符串没有找到,迭代函数返回nil。> for word in string.gmatch("Hello Lua user", "%a+") do print(word) end Hello Lua user |
12 | string.match(str, pattern, init)string.match()只寻找源字串str中的第一个配对. 参数init可选, 指定搜寻过程的起点, 默认为1。 在成功配对时, 函数将返回配对表达式中的所有捕获结果; 如果没有设置捕获标记, 则返回整个配对字符串. 当没有成功的配对时, 返回nil。> = string.match("I have 2 questions for you.", "%d+ %a+") 2 questions > = string.format("%d, %q", string.match("I have 2 questions for you.", "(%d+) (%a+)")) 2, "questions" |
string.gsub(mainString,findString,replaceString,num)在字符串中替换。
mainString 为要操作的字符串, findString 为被替换的字符,replaceString 要替换的字符,num 替换次数(可以忽略,则全部替换)string.gsub("aaaa","a","z",3)
结果:zzza3字符串反转string.reverse(arg)字符串反转
string.reverse("Lua") > auL
字符串长度string.len(arg)
字符串拷贝string.rep(string, n)返回字符串string的n个拷贝
> string.rep("abcd",2)abcdabcd
字符串拼接,使用的是 ..> print("www.runoob.".."com")www.runoob.com
字符串截取string.sub(s, i [, j])用于截取字符串,原型为:
参数说明:
s:要截取的字符串。i:截取开始位置。j:截取结束位置,默认为 -1,最后一个字符。print(string.sub("abcdef", 1, 3))> abc
字符串查找(1) string.find (str, substr, [init, [plain]])在一个指定的目标字符串 str 中搜索指定的内容 substr,如果找到了一个匹配的子串,就会返回这个子串的起始索引和结束索引,不存在则返回 nil。
init指定了搜索的起始位置,默认为 1,可以一个负数,表示从后往前数的字符个数。
plain表示是否使用简单模式,默认为 false,true 只做简单的查找子串的操作,false 表示使用使用正则模式匹配。
以下实例查找字符串 "Lua" 的起始索引和结束索引位置:
> string.find("Hello Lua user", "Lua", 1) 7 9
(2) string.gmatch(str, pattern)返回一个迭代器函数,每一次调用这个函数,返回一个在字符串 str 找到的下一个符合 pattern 描述的子串。如果参数 pattern 描述的字符串没有找到,迭代函数返回nil。
> for word in string.gmatch("Hello Lua user", "%a+") do print(word) endHelloLuauser
(3) string.match(str, pattern, init)string.match()只寻找源字串str中的第一个配对. 参数init可选, 指定搜寻过程的起点, 默认为1。在成功配对时, 函数将返回配对表达式中的所有捕获结果; 如果没有设置捕获标记, 则返回整个配对字符串. 当没有成功的配对时, 返回nil。
> = string.match("I have 2 questions for you.", "%d+ %a+")2 questions
区别:使用format 格式化一下
> = string.format("%d, %q", string.match("I have 2 questions for you.", "(%d+) (%a+)"))2, "questions"
9、正则匹配规则和java 不一样,可以到时候,使用lua 正则在线规则,检查是否正确
字符含义%a字母a-z,A-Z%b%bxy,以x和y进行成对匹配%c控制字符ASCII码 十进制转义表示为\0 - \31%d数字 0 - 9%f%f[char-set],边界匹配,前一个不在范围内,后一个在%g除了空格以外的可打印字符 十进制转义表示为\33 - \126%l小写字母 a - z%u大写字母 A - Z%s空格 十进制转义表示为\32%p标点符号,即!@#$%^&*()`~-_=+{}:"<>?[];",./| 32个字符%w字母数字 a - z, A - Z, 0 - 9%x十六进制符号 0 - 9, a - f, A - F
10、字符串格式化模糊匹配的其他匹配情况[单个字符(除 ^$()%.[]*+-?外): 与该字符自身配对]:https://www.runoob.com/lua/lua-strings.html
Lua 提供了 string.format()函数,以下是它的一些转义码:
%c - 接受一个数字, 并将其转化为ASCII码表中对应的字符%d, %i - 接受一个数字并将其转化为有符号的整数格式%o - 接受一个数字并将其转化为八进制数格式%u - 接受一个数字并将其转化为无符号整数格式%x - 接受一个数字并将其转化为十六进制数格式, 使用小写字母%X - 接受一个数字并将其转化为十六进制数格式, 使用大写字母%e - 接受一个数字并将其转化为科学记数法格式, 使用小写字母e%E - 接受一个数字并将其转化为科学记数法格式, 使用大写字母E%f - 接受一个数字并将其转化为浮点数格式%g(%G) - 接受一个数字并将其转化为%e(%E, 对应%G)及%f中较短的一种格式%q - 接受一个字符串并将其转化为可安全被Lua编译器读入的格式%s - 接受一个字符串并按照给定的参数格式化该字符串
11、字符与整数相互转换string.byte(字符串)转换第一个字符
string.char(数字)转换为字符
12、Lua特性:自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象、字典,并且table是变长变量table 变量注意事项:
table 的索引不可以是数字,也不可以是字符串,会报错,只能是普通变量
。
> tbl ={100 = "100"}stdin:1: "}" expected near "="> tbl ={"100" = "100"}stdin:1: "}" expected near "="-- 正确写法:> tbl = {a = "aa"}> print(tbl["a"])aa> print(tbl.a)aa
(1) 数组array = {}for i= -2, 2 do array[i] = i *2endfor i = -2,2 do print(array[i])end
结果:
-4-2024
(2) Lua 迭代器☺ 泛型迭代pairs 和 ipairs异同同:都能进行for 循环遍历
异:ipairs 仅仅遍历值,按照索引升序遍历,索引中断停止遍历。即不能返回 nil,只能返回数字 0,如果遇到 nil 则退出。所以table 变量中的变量是键值对形式的,它会直接忽略,即ipairs迭代时会略过非数值的索引。
pairs 能遍历集合的所有元素。即 pairs 可以遍历集合中所有的 key,并且除了迭代器本身以及遍历表本身还可以返回 nil。
注意:下面两个例子的结果的顺序、特点
tab = {"Hello","World",a=1,b=2,z=3,x=10,y=20,"Good","Bye"}for k,v in pairs(tab) do print(k.." "..v)end
结果:1 Hello2 World3 Good4 Byea 1x 10b 2y 20z 3
tab = {"Hello","World",a=1,b=2,z=3,x=10,y=20,"Good","Bye"}for k,v in ipairs(tab) do print(k.." "..v)end
结果:1 Hello2 World3 Good4 Bye
☺ 泛型迭代的例子2:如上代码输出结果存在一定规律,"Hello"、"World"、"Good"、"Bye"是表中的值,在存储时是按照顺序存储的,并且不同于其他脚本语言,Lua是从1开始排序的,因此,使用pairs遍历打印输出时,会先按照顺序输出表的值,然后再按照键值对的键的哈希值打印。
for k, v in pairs(t) do print(k, v)end-------------------------------------------array = {"Google", "Runoob"}for key,value in ipairs(array)do print(key, value)end
结果:1 Google2 Runoob
☺ 泛型 for 在迭代的时候每次调用的是闭包函数,迭代函数只是开始的时候调用一次function eleiter(t) local index = 0 print("in eleiter function") --> 每次调用迭代函数都说一句:in eleiter function return function() print("I am here.") --> 每次调用闭包函数都说一句:I am here index = index + 1 return t[index] endendt = {"one","two","three","four","five"}for ele in eleiter(t) do print(ele)end
结果:(2) 表、字典、对象....in eleiter function --> 【
for 迭代函数内部包含闭包函数的情况,对于函数非闭包内容,只执行一次
】-->
泛型 for 在迭代的时候每次调用的是闭包函数
I am here.oneI am here.twoI am here.threeI am here.fourI am here.fiveI am here.
在lua使用 table 表示了数组、表、字典、对象
table 特点:
Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil。
Lua table 是不固定大小的,你可以根据自己需要进行扩容。
Lua 的table 变量是引用型变量,即地址指向。
tab = {"Hello","World",a=1,b=2,z=3,x=10,y=20,"Good","Bye"}tab[1] = "W两个世界"for k,v in ipairs(tab) do print(k.." "..v)end
结果:1 W两个世界2 World3 Good4 Bye
Lua 的table 变量是引用型变量,即地址指向。
-- 简单的 tablemytable = {}print("mytable 的类型是 ",type(mytable))mytable[1]= "Lua"mytable["wow"] = "修改前"print("mytable 索引为 1 的元素是 ", mytable[1])print("mytable 索引为 wow 的元素是 ", mytable["wow"])-- alternatetable和mytable的是指同一个 tablealternatetable = mytableprint("alternatetable 索引为 1 的元素是 ", alternatetable[1])print("mytable 索引为 wow 的元素是 ", alternatetable["wow"])alternatetable["wow"] = "修改后"print("mytable 索引为 wow 的元素是 ", mytable["wow"])-- 释放变量alternatetable = nilprint("alternatetable 是 ", alternatetable)-- mytable 仍然可以访问print("mytable 索引为 wow 的元素是 ", mytable["wow"])mytable = nilprint("mytable 是 ", mytable)
结果:mytable 的类型是 tablemytable 索引为 1 的元素是 Luamytable 索引为 wow 的元素是 修改前alternatetable 索引为 1 的元素是 Luamytable 索引为 wow 的元素是 修改前mytable 索引为 wow 的元素是 修改后alternatetable 是 nilmytable 索引为 wow 的元素是 修改后mytable 是 nil
(3) table 的增删改查操作序号 | 方法 & 用途 |
---|---|
1 | table.concat (table [, sep [, start [, end]]]):concat是concatenate(连锁, 连接)的缩写. table.concat()函数列出参数中指定table的数组部分从start位置到end位置的所有元素, 元素间以指定的分隔符(sep)隔开。 |
2 | table.insert (table, [pos,] value):在table的数组部分指定位置(pos)插入值为value的一个元素. pos参数可选, 默认为数组部分末尾. |
3 | table.maxn (table)指定table中所有正数key值中最大的key值. 如果不存在key值为正数的元素, 则返回0。(Lua5.2之后该方法已经不存在了,本文使用了自定义函数实现) |
4 | table.remove (table [, pos])返回table数组部分位于pos位置的元素. 其后的元素会被前移. pos参数可选, 默认为table长度, 即从最后一个元素删起。 |
5 | table.sort (table [, comp])对给定的table进行升序排序。 |
方法 | 描述 |
---|---|
coroutine.create() | 创建 coroutine,返回 coroutine, 参数是一个函数,当和 resume 配合使用的时候就唤醒函数调用 |
coroutine.resume() | 重启 coroutine,和 create 配合使用 |
coroutine.yield() | 挂起 coroutine,将 coroutine 设置为挂起状态,这个和 resume 配合使用能有很多有用的效果 |
coroutine.status() | 查看 coroutine 的状态 注:coroutine 的状态有三种:dead,suspended,running,具体什么时候有这样的状态请参考下面的程序 |
coroutine.wrap() | 创建 coroutine,返回一个函数,一旦你调用这个函数,就进入 coroutine,和 create 功能重复 |
coroutine.running() | 返回正在跑的 coroutine,一个 coroutine 就是一个线程,当使用running的时候,就是返回一个 coroutine 的线程号 |
当create一个coroutine的时候就是在新线程中注册了一个事件。
当使用resume触发事件的时候,create的coroutine函数就被执行了,当遇到yield的时候就代表挂起当前线程,等候再次resume触发事件。
可以把 yield 当成暂时,点击resume 当成开始,并且具有“断点续传” 作用
-- 注册一个事件co = coroutine.create( function(i)print(coroutine.status(co)) -- 挂起/暂停coroutine.yield() print(i); end) -- 执行事件coroutine.resume(co, 1) print(coroutine.status(co)) coroutine.resume(co, 3) -- 重新开始,相当于“断点续传”,因为这时候传递参数已经是3,但在原先情况上继续执行,会执行coroutine.resume(co, 1) 的参数1
结果:runningsuspended
1
(2) coroutine.creat方法和coroutine.wrap 的区别返回值不同:coroutine.creat返回的是一个协同程序,类型为thread,需要使用coroutine.resume进行调用;而coroutine.wrap返回的是一个普通的方法(函数),类型为function,和普通function有同样的使用方法,并且不能使用coroutine.resume进行调用。co_creat = coroutine.create( function() print("co_creat类型是"..type(co_creat)) end)co_wrap = coroutine.wrap( function() print("co_wrap类型是"..type(co_wrap)) end)coroutine.resume(co_creat)co_wrap()
结果:co_creat类型是threadco_wrap类型是function
14、创建对象Lua 中使用":"实现面向对象方式的调用。":"只是语法糖,它同时在方法的声明与实现中增加了一个名为 self 的隐藏参数,这个参数就是对象本身。
- --实例:Account = {balance = 0};--生成对象function Account:new(o) o = o or {}; --如果用户没有提供对象,则创建一个。 setmetatable(o, self); --将 Account 作为新创建的对象元表 self.__index = self; --将新对象元表的 __index 指向为 Account(这样新对象就可以通过索引来访问 Account 的值了) return o; --将新对象返回end--存款function Account:deposit(v) self.balance = self.balance + v;end--取款function Account:withdraw(v) self.balance = self.balance - v;end--查询function Account:demand() print(self.balance);end--创建对象myAccount = Account:new();--通过索引访问print(myAccount.balance);--调用函数myAccount:deposit(100);myAccount:withdraw(50);myAccount:demand();
结果:
050
如果本文对你有帮助的话记得给一乐点个赞哦,感谢!
☺lua和javaScript差不多的,就是一些语法的细节不同,学过js,再注意一下下面的细节,就能上手了~快速入门,可以直接看一下菜鸟教程的lua:ht
是公园也是“净水器”,成都面积最大垂直流人工湿地公园5月对外开放
1、怀孕后白带真的会增多。2、这是因为孕妇的阴部、阴道、宫颈都充满了血液,组织水分增多,所以分泌物也增多。3、怀孕的月份
西门子深圳磁共振公司召回医用血管造影x射线机---中国经济网北京4月4日讯广东省药品监督管理局网站近日公示的一则召回信息显示,西门子磁共振
1、吊丝一词最初是源于芳草吧屌丝网(有解释说源于百度李毅吧是不对的),是一种带有谐谑语气的称呼,可用于称呼别人,亦可自谓
祥生控股集团(02599)公告,2023年3月,归属集团总合约销售额约为人民币21亿元;归属集团合约建筑面积约为153,458平方米;及归属集团平均合约售价约为
2023年4月2日,安徽省黄山市歙县新安江水域,游船航行在江面上。春日里,新安江两岸的青山与徽州古村落相映成趣,山水画廊风光吸引众多游客前
冥币在我们扫墓、祭祀时需要用到的东西,是民间传统拜祭天地鬼神或祖先时火化的祭祀品之一,据悉5岁娃上坟藏冥币带回家,称要送朋友,具体情况
市场监管总局4月3日通报了车辆相关产品质量国家监督抽查情况。本次抽查检验510家企业生产的510批次车辆相关产品,涉及汽车用制动器衬片、汽车
4月3日,继安踏之后,一汽丰田官方微博同样已删除关于张继科的全部动态,并且下架了与其有关的全部宣传物料。而张继科个人微博
1、以下是专业热度排名,可以参考下。2、排名专业类型1金融学经济学2国际经济与贸易经济学3土木工程工学4机械设计制造及其自动化
软科和校友会是国内权威的大学排行榜,近日,软科和校友会2023中国大学排行榜公布,本期文章老师将为大家整理全国大学排行榜
福蓉科技(603327)04月03日在投资者关系平台上答复了投资者关心的问题。投资者:请问,截至2023年3月31日,公
大家好,小城来为大家解答以上问题。英雄联盟打字出现unknownharderror,c000021aunknownharderror很多人还不知道,现在让我们一
一个交易者,如果能够维持较长一段时间的成功交易,那么,一般说明他对于市场有了某种程度的理解和认知;形成了适合自己的一整套的交易理念、