Lua | 一篇文章讲清Lua语法及热更新

本文深入介绍了Lua编程语言的语法,包括输出、变量、运算符、条件分支、循环、函数、表、元表、面向对象等核心概念。此外,还详细讲解了在Unity中使用Lua进行热更新的流程,包括插件安装、创建和调用Lua脚本,以及项目升级的步骤。通过本文,读者将掌握Lua的基础知识和在游戏开发中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、环境搭建

二、Lua语法

1.输出print、单行注释、多行注释

2.变量

(1)nil

(2)number

(3)string

(3.1)字符串长度

(3.2)字符串拼接

(3.3)多行打印

(3.4)类型转换

(3.5)字符串操作(大小写、反转、查找、截取、重复)

(3.6)字符串与ASCII互转

(4)boolean

(5)function

(5.1)无参无返回值

(5.2)有参无返回值

(5.3)有一个返回值

(5.4)有多个返回值

(5.5)匿名函数

(5.6)可变形参函数

(5.7)获取函数类型

(5.8)函数嵌套

(5.9)函数嵌套-闭包

(6)table

(6.1)一维数组

 (6.2)unpack函数

(6.3)二维数组

 (6.4)自定义索引

(6.5)迭代器遍历

(6.5.1)ipairs

 (6.5.2)pairs

(6.6)字典

(6.7)类

(6.7.1)类函数声明

 (6.8)表操作

(6.8.1)插入

(6.8.2)删除

(6.8.3)排序

(6.8.4)拼接 

(7)thread

(7.1)协程创建

(7.2)协程运行

(7.3)协程挂起

(7.4)协程状态

 3.运算符

(1)算术运算符(+  -  *  /  %  ^)

(2)条件运算符(<  >  <=  >=  ==  ~=)

(3)逻辑运算符(and  or  not,支持短路规则)

4.条件分支语句

(1)单分支

(2)双分支

(3)多分支

5.循环语句

(1)for循环

(1.1)数值for循环

 (1.2)泛型for循环

(2)while...do...end循环

(3)repeat...until...循环

6.多脚本执行

(1)本地变量和全局变量

(2)require("脚本名")

(3)package.loaded["脚本名"]

(4)大G表

(5)dofile

7.特殊用法

(1)多变量赋值

(2)多返回值

(3)逻辑与、逻辑或

(4)实现三目运算符

8.元表

(1)设置元表

(2)特定操作

(2.1)__tostring

(2.2)__call

(2.3)运算符重载

(2.4)__index

(2.4.1)__index是表

(2.4.2)__index是方法

(2.5)__newindex

(2.5.1)__newindex是函数

(2.5.1)__newindex是表

(2.6)获取元表

9.面向对象

(1)封装

(2)继承

(3)多态

(4)总结

10.Lua其他库

(1)数学计算

(2)操作系统库-时间

(3)文件操作

(3.1)写文件

(3.2)读文件

(4)其他-路径

11.垃圾回收

三、热更新

1.插件安装

2.创建Lua脚本

3.unity中调用Lua脚本

4.项目升级

(4.1)Lua脚本更改

(4.2)unity中调用Lua 

(4.3)效果展示 


一、环境搭建

sublime_text快捷方式:

  • Ctrl+B:运行
  • Ctrl+L:选中当前行
  • Ctrl+/:快速注释
  • Ctrl+Shift+/:快速块注释

二、Lua语法

1.输出print、单行注释、多行注释

print("hello world")
--单行注释

--[[
多行注释
多行注释
]]

--[[
多行注释
多行注释
--]]

--[[
多行注释
多行注释
]]--

2.变量

  • lua中四种简单的变量类型:nil、string、boolean、number。除此之外还有:function、table、userdata、thread。
  • 不需要声明变量类型;可通过type函数获取变量类型,type函数返回值是string。
  • 变量可随便赋值。Lua 中的变量是动态类型的,这意味着变量没有预定义的类型,类型会在运行时根据赋给变量的值来决定。
  • lua中没有赋值过的变量,默认类型是nil。

(1)nil

a=nil
print(a)

(2)number

        所有的数值都是number类型。

a=10
print(a)

a=10.5
print(a)

(3)string

        在 Lua 中,字符串可以用双引号"、单引号'或者长括号[[ ]]来表示。

a="hello"
print(a)
(3.1)字符串长度

        使用#运算符可以获取字符串长度。

a="hello world"
print(#a)
a="一"    
print(#a)  --3
(3.2)字符串拼接

        可以使用..运算符来拼接字符串。也可以使用string.format来进行拼接。

a="一"    
print("一个汉字长度:"..#a)  --一个汉字长度是3
print(string.format("今年 %s 岁",'18'))
(3.3)多行打印

        在Lua中,可以使用多行字符串来打印多行文本。多行字符串可以通过在字符串的开始和结束使用双方括号[[]]来创建。也可以通过行末尾添加"\n"来进行多行打印。

a=[[1.hello
2.world]]
print(a)
(3.4)类型转换

        在Lua中,可以使用 tostring 函数将一个值转换为字符串。这个函数可以接受任何基本类型的值作为参数,并返回该值的字符串表示形式。

a=false
print(tostring(a))
(3.5)字符串操作(大小写、反转、查找、截取、重复)

        字符串相关操作,不会改变原字符串。Lua中索引从1开始。

str="YsL"
str1=string.upper(str)
print("原字符串:"..str..",全部大写为:"..str1)
str1=string.lower(str)
print("原字符串:"..str..",全部小写为:"..str1)
str1=string.reverse(str)
print("原字符串:"..str..",反转字符串为:"..str1)

--原字符串:YsL,全部大写为:YSL
--原字符串:YsL,全部小写为:ysl
--原字符串:YsL,反转字符串为:LsY
str="YsL"
print("---------字符串查找")
print(string.find(str,"sL")) --2  3

print("---------字符串截取")
print(string.sub(str,2))     --sL
print(string.sub(str,2,2))   --s

print("---------字符串重复:"..string.rep(str,3)) --字符串重复:YsLYsLYsL
print("---------字符串修改")
print(string.gsub("Session",'s','*'))    

--Se**ion	2

        string.gsub()返回两个结果,第二个值表示修改了几个字符。

(3.6)字符串与ASCII互转
a=string.byte("Lua",1)
print(a) --76

a=string.char(a)
print(a) --L

(4)boolean

a=false
print(a)
print(type(a)) --boolean
print(type(type(a))) --string

(5)function

        在Lua中,函数是一种可以封装代码以便重复使用的基本结构。函数可以接受参数,并且可以返回一个或多个值。Lua不支持重载,但重载后并不报错,默认调用最后声明的函数。

(5.1)无参无返回值
--先声明
function fun1()
	print("my fun1")
end

--再调用
fun1()
(5.2)有参无返回值
function fun3(a)
	print(a)
end

fun3(1)
fun3("hello world")
fun3(true)
fun3(nil) --nil
fun3()    --nil
fun3(1,2) --1     实参和形参个数不匹配,会补空或丢弃
(5.3)有一个返回值
function fun4(a)   --直接return即可
	return a
end

temp=fun4(1)
print(temp)
(5.4)有多个返回值
function fun5(a)   --支持返回多个值
	return a,-1
end

temp1,temp2,temp3=fun5(10) --支持多个变量来接取返回值
print(temp1)
print(temp2)
print(temp3)    --nil
(5.5)匿名函数
fun2=function()
	print("my fun2")
end

fun2()
(5.6)可变形参函数
function fun7(...)
	arg={...}        --arg表存储参数
	for i=1,#arg do
		print(arg[i])
	end
end
fun7(1,2,3,4,"hello",false)
(5.7)获取函数类型
fun6=function()
	print("my fun6")
end
print(type(fun6))   --function
(5.8)函数嵌套
function fun8()
	return function()
		print("函数嵌套")
	end
end

--调用方式1
fun9=fun8()
fun9()
--调用方式2
fun8()()
(5.9)函数嵌套-闭包

        在Lua中,函数可以嵌套在其他函数内部,这时候内部的函数可以访问外部函数的局部变量,这种结构称为闭包(closure)。闭包的强大之处在于,即使外部函数的执行已经结束,闭包仍然可以记住外部函数中的变量。

function fun10(x)
	return function(y)
		print(x+y)    --临时变量x的生命周期变长
	end
end

close=fun10(1)
close(2)

         即使 fun10执行完毕,close依然可以访问x这个变量。

(6)table

        表是 Lua 中唯一的数据结构,可以用来表示数组、字典等复杂数据结构。表在 Lua 中是非常强大的,因为它们可以包含所有类型的值。

(6.1)一维数组
a={1,2,3,4,nil,true,"hello",nil} --8个元素     如果数组的最后一个元素是 nil,Lua 通常会将其视为数组的结束,导致长度计算时忽略该 nil 元素。
print("数组a的长度:"..#a)  --7      lua5.1.5版本中,nil如果是数组最后一个元素,计算数组长度时则会忽略该元素。用#获计算长度不准确
print(a[0]) --nil  lua索引从1开始
print("第一个元素:"..a[1]) --1

print("---------------一维数组遍历")
for i=1,#a do
	print(a[i])
end
 (6.2)unpack函数

        在Lua中,unpack函数是一个非常有用的内置函数,它可以从表中取出一个连续的序列,并返回这些值。这个函数在Lua 5.1中是全局的,但从Lua 5.2开始,它被移到了table库中,即table.unpack

a = {1,2,3,4,nil,true,"hello",nil} 
print(unpack(a))  --1	2	3	4	nil	true	hello

        使用unpack可以很方便地将表中的值作为多个参数传递给函数。

        unpack或table.unpack接受三个参数:表、起始索引和结束索引。如果不指定起始索引和结束索引,默认情况下它会从第一个元素开始,到表的长度结束。

print(unpack(a,2,4))  --2	3	4
(6.3)二维数组
a={
  {1,2,3},{4,nil,"hello"}}
print(a[1][3]) --3
print(a[2][3]) --hello

print("---------------二维数组遍历")
for i=1,#a do
	b=a[i]
	for j=1,#b do
		print(b[j])
	end
end
 (6.4)自定义索引

        Lua的表不仅可以使用整数索引(不建议自定义整数索引),还可以使用字符串或其他Lua值(除了nil)作为键(后续会讲)。

a={[0]=1,2,3,[-1]=4,[4]=5}
print(#a)   --2   会去除索引不正常的元素
print(a[0]) --1

for i=1,#a do
	print(a[i])  --2 3
end

a={[1]=1,[2]=1,[4]=1,[6]=1}
print(#a)   --6
print(unpack(a)) --1	1	nil	1	nil	1
(6.5)迭代器遍历

         使用#计算长度并不准确,建议使用迭代器遍历:

  • 如果想要处理的是严格意义上的数组(索引连续的列表),使用ipairs更合适,因为它的性能可能会更好一些。
  • 如果需要处理的是一个混合了数组和字典风格的表,或者你不确定表的索引是否连续,那么使用pairs会更安全,它能确保遍历到表中的所有元素(nil除外)。
(6.5.1)ipairs

        从索引1开始遍历,索引小于0或者断序后无法遍历。

a={[0]=0,1,2,3,nil,4,5,[10]=6,c=7,nil}

for i,k in ipairs(a) do
	print("i:"..i.."-k:"..k)
end
-- i:1-k:1
-- i:2-k:2
-- i:3-k:3
 (6.5.2)pairs
a={[0]=0,1,2,3,nil,4,5,[10]=6,c=7,nil}

for i,k in pairs(a) do
	print("i:"..i.."-k:"..k)
end

--i:1-k:1
--i:2-k:2
--i:3-k:3
--i:5-k:4
--i:6-k:5
--i:0-k:0
--i:10-k:6
--i:c-k:7
(6.6)字典

         在Lua中,并没有专门的“字典”类型,但是表(table)结构在Lua中是非常灵活的,通常用来实现类似字典的功能。表可以存储键值对,其中键和值可以是任意类型的数据(除了nil)。当使用字符串作为键时,表就类似于其他语言中的字典或哈希表。

a={["name"]="Lisa",["age"]=22,["sex"]="girl",["1"]=true,c=56}

print("-------------访问")
print(a["name"])
print(a.c)
print(a.name)--虽然可以通过这种方法得到值,但键不能是数字,如a.1不对

print("-------------修改")
a["age"]=20
print(a["age"])

print("-------------新增")
a["Country"]="TaiLand"
print(a.Country)

print("-------------删除")
a["Country"]=nil
print(a.Country)

print("-------------字典的遍历,使用pairs")
for i,k in pairs(a) do
	print(i,k)
end
(6.7)类

        Lua中默认没有面向对象,所以不能new。

Student={
	age=12,
	name="Lisa",
	fun0=function(t) --在函数中需要调用表本身的属性和方法时,可以把自己当参数传进来
		print("fun0:"..t.name..":"..t.age) 
	end,
	fun1=function()
		--print("fun1:"..name..":"..age) --错误
		print("fun1:"..Student.name..":"..Student.age) --在函数中调用表本身的属性和方法,需要指明表名称
	end
}
--新增变量
Student.sex="girl"

print(Student.age)
print(Student.sex)

Student.fun0(Student)
Student:fun0() --语法糖:冒号调用方法时,会默认把调用者作为第一个参数传入方法中
Student.fun1()
(6.7.1)类函数声明

        和普通函数申明的两种方式(普通函数、匿名函数)相同,除此之外,也可以使用:来申明。

  • 当声明一个方法时,使用 : 语法允许定义一个需要隐式 self 参数的函数。self 实际上指的是调用方法的对象实例,而不是类名。
  • 当调用一个方法时,如果使用 : 语法,Lua会自动将调用该方法的表(对象)作为第一个参数传递给该方法。
Student.fun2=function()
    print("fun2")
end

function Student.fun3()
	print("fun3")
end

function Student:fun4() --语法糖:冒号声明方法时,会默认把调用者作为第一个参数传入方法中。self表示默认传入的第一个参数,self不是this。(self 实际上指的是调用方法的对象实例,而不是类名)
	print("fun4:"..self.name)
end

Student.fun2()
Student.fun3()

Student:fun4()
Student.fun4(Student)
 (6.8)表操作
(6.8.1)插入
t1={
  {name=1,age=10},{name=2,age=11}}
t2={name=3,age=12}

print(#t1)  --2
table.insert(t1,t2)

print(#t1)  --3
print(t1[3]["age"])  --12
(6.8.2)删除
table.remove(t1) --默认删除最后一个元素

table.remove(t1,1) --第二个参数,指定移除的元素索引
(6.8.3)排序

        在Lua中,table.sort 函数用于对表中的元素进行排序。这个函数可以对表中的元素进行原地(in-place)排序,也就是说,排序操作会直接改变原始表,而不是创建一个已排序的新表。

t3={12,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烫青菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值