Lua脚本学习
创始人
2025-06-01 02:38:36
0

1、介绍

Lua 是一个小巧的脚本语言。其设计目的是为了通过灵活嵌入应用程序中从而为应用程序提供灵活的扩展和定制功能。Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。Lua并没有提供强大的库,这是由它的定位决定的。所以Lua不适合作为开发独立应用程序的语言。
Lua脚本可以很容易的被C/C++ 代码调用,也可以反过来调用C/C++的函数,这使得Lua在应用程序中可以被广泛应用。 在所有脚本引擎中,Lua的速度是最快的。这一切都决定了Lua是作为嵌入式脚本的最佳选择。

2、运行环境安装(linux版)

下载lua源码包

wget http://www.lua.org/ftp/lua-5.4.0.tar.gz

解压文件

tar zxf lua-5.4.0.tar.gz

进入解压后的文件中,编译文件

make linux test

编译成功后,会在src目录里面看到lua.c和luac.c文件

安装lua

make install

刷新动态库链接

ldconfig

验证是否安装成功

lua -v

3、lua的使用

基础语法

命名规则

lua中变量的命名规则和Java类似,可以由大小写字母、数字、下划线组成,但不能以数字开头,并且lua的内置关键字不能命名为变量

ab
ab12
_ab
ab_12
aA
AB

内置关键字

and

break

if

then

elseif

else

end

while

do

false

true

function

local

return

repeat

until

in

or

not

nil

goto

for

分号使用

lua语句的结尾,分号的使用是可选的

a = 1;
b = 2;c = 3
d = 4

注释规则

单行注释:两个连续的减号为单行注释

多行注释:两个连续减号,再加上两对方括号(注意:多行注释两个连续的--后面不能跟空格,否则会被认为是单行注释)

-- 此行为注释内容

a = 1

--[[

多行注释内容

]]

b = 2

全局变量和局部变量

在lua中使用local修饰的变量为局部变量,其它的变量都为全局变量

-- 全局变量i
i = 10;
do-- 局部变量xlocal x = i - 1;i = i - 1;-- 局部代码块打印xprint(x);
end
-- 打印i
print(i);
-- 局部代码块之外打印x
print(x);

可以看到x第一次正常打印出来了,x第二次打印的却是nil,这是因为x是局部变量,到外界被释放了

判断语句

--语法
if 表达式1 then
语句块1
elseif 表达式2 then
语句块2
else
语句块3
end
function panduan(a)if(a>100 or a<0) thenprint("输入不合法,请重新输入");elseif(a>=80) thenprint("优秀");elseif(a>=60) thenprint("及格");elseprint("不及格");end
end
print("please enter a number:");
n=io.read("*n");
panduan(n);

循环语句

--语法一
while 循环条件(符合该循环条件则继续循环) do
循环体
end
--语法二
repeat
循环体
until 循环条件(符合该循环条件,则退出循环)
--语法三
for 变量=初始值,终止值,步长 do
循环体
end
function whiletest(n,sum)local i = 0;while i<=n dosum=sum+i;i=i+1;endreturn sum;
end
function fortest(n,sum)for i=0,n,1 dosum=sum+i;endreturn sum;
end
function repeattest(n,sum)local i = 0;repeat sum=sum+i;i=i+1;until i>nreturn sum;
end
print("Please enter a number:");
n=io.read("*n");
print("while:add from 1 to "..n.." and the result is: "..whiletest(n,0));
print("for:add from 1 to "..n.." and the result is: "..fortest(n,0));
print("repeat:add from 1 to "..n.." and the result is: "..repeattest(n,0));

数据类型

lua有8种数据类型

分别为:nil(空),boolean(布尔),number(数值),string(字符串),userdata(用户数据),function(函数),thread(协程),table(表)

使用type()函数可以获取到值的类型名称

nil

nil是一种只有nil值的空类型,lua使用nil来表示无效值的情况,表示未被定义

boolean

boolean类型只有两个值:true和false

逻辑运算符

nil默认为false
and: 前面的操作数如果为false,就返回前面的操作数;否者返回后面的操作数
or: 前面的操作数为true,则返回前面的操作数,否者返回后面的
not: 取反

number

lua支持整型以及双精度的浮点型,整型被称为integer,浮点型被称为float,可以使用math.type()查看当前数值是类型

lua支持:加(+)、减(-)、乘(*)、除(/)、取负(-)、取模(%)、取整除(//)、幂运算(^)

注意:进行运行的时候,只有运算符号前后两个操作数都是整型并且不是除法时,结果才是整型,否则就是浮点型

lua对运算还提供了math数学库,与Java中的Math类似,可以对数据进行各种运算

例子:红包分配算法
t={}
function initAmount(m,n)local a = math.random(1,2*(math.floor(m/n)));if n>1 and m

string

lua中使用双引号或单引号来定义字符串变量,比如 a = "abc"或b = 'def'

并且b='def"abc"',单引号中包含双引号也可以正常输出,双引号不需要转义

但双引号中包含双引号,无法正常输出,这时候的双引号需要转义

字符串的相关操作

  • #后面跟上字符串,会返回当前字符串的长度

  • 字符串使用..进行拼接,如果拼接的是数值,会自动将其转为字符串

  • 多行字符串使用两对中括号包裹,a=[[字符串]],注意,使用该方式,如果字符串中有转义字符,无法转义

  • lua提供了数值和字符串的自动转换,在运算时,如果运算式中包含字符串,会自动尝试将其转为数值类型,转换不了,会报错(注意:比较运算符不会强制类型转换,因此当比较符前后同时包含数值和字符串时,会报错)

  • 显式类型转换,lua提供了主动的类型转换,tonumber(字符串)将字符串转为数值,tostring(数值)将数值转为字符串

  • lua提供了一个字符串库string,提供了很多功能处理字符串,调用示例:string.len(字符串)或字符串:len()

function

function类型定义的代码块,为函数区,可以通过函数名进行调用

--语法
function 函数名(入参1,入参2,...)具体代码
end
--调用方式
函数名(参数1,参数2,...)

table

表是lua中常用的一直数据结构,可以用来表示数组、集合等等

  • 使用a = {}构造表a,直接输出a会返回表的地址,a只是表的引用

  • 表添加元素采用的是a[key] = value,key-value的方式

  • 当多个表名引用同一张表时,任何一个引用改变了表数据,其它引用的表数据也会改变

  • 当表的所有引用都被释放时,垃圾回收器才会删除这张表

  • 将nil给表元素,可以将表元素删除

  • 当key是字符串时,可以通过表名.key名=value的方式插入数据,可以使用表名.key名的方式调用表元素等价于表名[key名]

  • a[0]和a["0"]是两个不一样的表元素,因为key一个是数值类型一个是字符串类型;但a[1]和a[1.0]指代的是同一个元素,因为整型和浮点型之间会进行类型转换,a[1.0]会转化成a[1]

  • 表的构建方法有:空构建,列表式构建,记录式构建,列表和记录混合构建

-- 表构建,相当于list={[1]="a",[2]="b",[3]="c",[4]="d",[5]="e",[6]="f"}
list={"a","b","c","d","e","f"}
-- 记录构建,相当于entity={["id"]=1,["name"]="zhangsan",["age"]=23}
entity={id=1,name="zhangsan",age=23}
-- 混合构建,相当于mix={["id"]=2,[1]="a",[2]="b",["name"]="lisi",["age"]=23,[3]="c"}
mix={id=2,"a","b",name="lisi",age=23,"c"}
print("list:first element is "..list[1]);
print("entity:name is "..entity.name);
print("mix:first element is "..mix[1].." name is "..mix.name);
  • pairs迭代器和ipairs迭代器

table={1,2,3,id="10021","a","b",name="ls"}
print("pairs result is:");
-- pairs可以遍历出所有的元素,但是遍历的元素不是按顺序的
for k,v in pairs(table) doprint(k,v);
end
print("ipairs result is:")
--[[ipairs只能遍历序列(key从1开始,直到key不连续为止),
输出顺序会按定义的顺序输出]]
for k,v in ipairs(table) doprint(k,v)
end
  • table表标准库

t={1,2,3,4}
-- 在表t开头插入9,其它元素依次后移一位
table.insert(t,1,9);
print("insert(t,1,9)");
for k,v in pairs(t) doprint(k,v)
end
-- 在表t末尾插入10
table.insert(t,10);
print("insert(t,10)");
for k,v in pairs(t) doprint(k,v)
end
-- 移除表t第一个元素,其它元素依次前移一位
table.remove(t,1);
print("remove(t,1)");
for k,v in pairs(t) doprint(k,v)
end
-- 移除表t最后一位元素
table.remove(t);
print("remove(t)")
for k,v in pairs(t) doprint(k,v)
end

userdata

userdata叫做用户数据也叫用户自定义数据,其作用是为了与其它编程语言(例如C语言、C++、C#)进行交互。

thread

lua中的thread叫做协同程序,与线程比较类似,拥有独立的堆栈,独立的局部变量,独立的指令指针。

线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行。在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只有在明确的被要求挂起的时候才会被挂起。线程是操作系统进行调度的最小单位,而协程则是在应用程序内部进行调度的最小单位。在多线程并发编程中,线程之间的切换涉及到内核态和用户态之间的切换,会带来一定的开销。而在协程并发编程中,由于很多协程都运行在同一个线程内,因此协程之间的切换只涉及到用户态之间的切换,避免了内核态和用户态之间的频繁切换,从而提高了性能

  • coroutine.create创建一个协程,返回的是corontine,参数是一个函数

  • coroutine.resume重新启动协程,配合create使用

  • coroutine.yield挂起协程

  • coroutine.status返回当前协程状态,suspended(挂起)、running(运行)、dead(死亡)

  • coroutine.wrap创建一个协程,返回一个函数,一旦调用这个函数,就会进入coroutine,和create类似。

  • coroutine.running返回正在运行的coroutine,返回的是coroutine的线程号

function run(data)-- 当前协程状态print("1:"..coroutine.status(co));data = data+1;print("co", 1, data);-- 当前协程的线程号print(coroutine.running());-- 当前协程挂起coroutine.yield()print("2:"..coroutine.status(co));print(coroutine.running())data = data+1;print("co", 2, data)
end
function test(data)-- 当前协程的线程号print(coroutine.running())data = data+1;print("co2",3,data)-- 协程挂起coroutine.yield()print(coroutine.running())data = data+1;print("co2",4,data)
end
print("coroutine.create():");
-- create方式创建协程
co = coroutine.create(run);
print("create status is:"..coroutine.status(co));
print("coroutine.wrap():");
-- wrap方式创建协程
co2 = coroutine.wrap(test);
--print("wrap status is:"..coroutine.status(co2));
data = 1
-- 启动co协程
coroutine.resume(co, data)
-- 启动co2协程
co2(data);
print("co first resume end status:"..coroutine.status(co));
print("main", data);
-- 重新启动co协程
coroutine.resume(co, data)
print("co second resume end status:"..coroutine.status(co));
-- 启动死亡协程,会报出cannot resume dead coroutine
print("co third resume:",coroutine.resume(co,data));
-- 重新启动co2协程
co2(data);

本章内容到此结束,下一章Redis运行Lua脚本和Redis配合Lua完成秒杀系统

相关内容

热门资讯

电视安卓系统哪个品牌好,哪家品... 你有没有想过,家里的电视是不是该升级换代了呢?现在市面上电视品牌琳琅满目,各种操作系统也是让人眼花缭...
安卓会员管理系统怎么用,提升服... 你有没有想过,手机里那些你爱不释手的APP,背后其实有个强大的会员管理系统在默默支持呢?没错,就是那...
安卓系统软件使用技巧,解锁软件... 你有没有发现,用安卓手机的时候,总有一些小技巧能让你玩得更溜?别小看了这些小细节,它们可是能让你的手...
安卓系统提示音替换 你知道吗?手机里那个时不时响起的提示音,有时候真的能让人心情大好,有时候又让人抓狂不已。今天,就让我...
安卓开机不了系统更新 手机突然开不了机,系统更新还卡在那里,这可真是让人头疼的问题啊!你是不是也遇到了这种情况?别急,今天...
安卓系统中微信视频,安卓系统下... 你有没有发现,现在用手机聊天,视频通话简直成了标配!尤其是咱们安卓系统的小伙伴们,微信视频功能更是用...
安卓系统是服务器,服务器端的智... 你知道吗?在科技的世界里,安卓系统可是个超级明星呢!它不仅仅是个手机操作系统,竟然还能成为服务器的得...
pc电脑安卓系统下载软件,轻松... 你有没有想过,你的PC电脑上安装了安卓系统,是不是瞬间觉得世界都大不一样了呢?没错,就是那种“一机在...
电影院购票系统安卓,便捷观影新... 你有没有想过,在繁忙的生活中,一部好电影就像是一剂强心针,能瞬间让你放松心情?而我今天要和你分享的,...
安卓系统可以写程序? 你有没有想过,安卓系统竟然也能写程序呢?没错,你没听错!这个我们日常使用的智能手机操作系统,竟然有着...
安卓系统架构书籍推荐,权威书籍... 你有没有想过,想要深入了解安卓系统架构,却不知道从何下手?别急,今天我就要给你推荐几本超级实用的书籍...
安卓系统看到的炸弹,技术解析与... 安卓系统看到的炸弹——揭秘手机中的隐形威胁在数字化时代,智能手机已经成为我们生活中不可或缺的一部分。...
鸿蒙系统有安卓文件,畅享多平台... 你知道吗?最近在科技圈里,有个大新闻可是闹得沸沸扬扬的,那就是鸿蒙系统竟然有了安卓文件!是不是觉得有...
宝马安卓车机系统切换,驾驭未来... 你有没有发现,现在的汽车越来越智能了?尤其是那些豪华品牌,比如宝马,它们的内饰里那个大屏幕,简直就像...
p30退回安卓系统 你有没有听说最近P30的用户们都在忙活一件大事?没错,就是他们的手机要退回安卓系统啦!这可不是一个简...
oppoa57安卓原生系统,原... 你有没有发现,最近OPPO A57这款手机在安卓原生系统上的表现真是让人眼前一亮呢?今天,就让我带你...
安卓系统输入法联想,安卓系统输... 你有没有发现,手机上的输入法真的是个神奇的小助手呢?尤其是安卓系统的输入法,简直就是智能生活的点睛之...
怎么进入安卓刷机系统,安卓刷机... 亲爱的手机控们,你是否曾对安卓手机的刷机系统充满好奇?想要解锁手机潜能,体验全新的系统魅力?别急,今...
安卓系统程序有病毒 你知道吗?在这个数字化时代,手机已经成了我们生活中不可或缺的好伙伴。但是,你知道吗?即使是安卓系统,...
奥迪中控安卓系统下载,畅享智能... 你有没有发现,现在汽车的中控系统越来越智能了?尤其是奥迪这种豪华品牌,他们的中控系统简直就是科技与艺...