L02. 变量及作用域
一. 什么是变量
无
二. Lua变量的命令规则
1. 命名规则:数字字母下划线构成 但是不能数字开头
2. 注意 :变量命名必须要包含一定涵义 比如我们要用变量存储一个年龄数值 比如我们用 x=18 别人看我们的源码 看到这里 她不明白 X这个变量为18代表什么意思 如果我们用age=18 那么他一看就明白了 方便我们自己 也方便他人 这个是一个良好的习惯 值得培养
3. 注意: 变量名区分大小写
4. 注意:变量名有一些系统关键字 不要占用这些关键字 比如Lua本身的一些语句 if else end function
5. 注意:如果规范一点 我们可以针对 全局变量和局部变量 我们最好区分写法 比如全局变量 p_x=14 p就是public 的缩写 局部变量 l_y l就是local的缩写
三 . Lua变量的定义
1. Lua语言中的变量包含三种类型:全局变量、局部变量、表中的域。
2. Lua中的所有变量全部是全局变量,哪怕是在函数体中也是全局变量,除非用Local关键字显式声明为局部变量
--初始化全局变量,全局变量不需要定义直接可以拿来使用
g_a = 123; g_b = 456 print(a,b) --输出结果: 123 456 --定义并初始化局部变量,使用local声明 local l_a = 123; l_b = 456 print(a,b) --输出结果: 123 456 local k = 5 --局部变量 k = 6 --局部变量 do m = 6 --全局变量 local n = 5 --局部变量 end local function func() b = 8 --全局变量 local b --局部变量 end if true then local c = 5 --局部变量 d = 6 --全局变量 end
4. 初始化变量与定义变量是两个不同的概念
--只要在赋值之前变量为nil, 都为初始化变量
--这叫定义局部变量 local a --这叫初始化局部变量(a在赋值之前为nil,然后被赋予有效值叫初始化) a = 6 --这叫定义并初始化局部变量 local b = 8 --这叫初始化全局变量 c = 5
5. 全局变量都保存在_G表中
--初始化全局变量 k = 5 --输出全局变量k print(k) --输出结果: 5 --也可以这样输出全局变量 print(_G.k) --输出结果: 5
6. 注意: 变量先在最小的作用域下寻找定义,然后再扩大作用域寻找,之后在去找全局_G里面寻找定义(如果不明白作用域,下方有讲解)
local val1 = 5 --定义并初始化局部变量 val1 = 6 --局部变量赋值(此变量与上面的变量是一个) do val1 = 8 --局部变量赋值(此变量与上面的变量是一个) function fun() --定义全局函数 val1 = 8 --局部变量赋值(此变量与上面的变量是一个) end fun() --调用执行函数 end --[[ 讲解一下函数内变量是如何寻找自己属于哪个作用域的 1. 先在函数内寻找val1,如果没有找到 2. 然后在定义函数的上方的do end语句块内,开始寻找,如果没有找到 3. 然后再整个.lua(模块)文件中查找,如果没有找到(这里是找到了val1属于这个作用域) 4. 最后在_G里面寻找 --]]
四. Lua变量的赋值与删除
1. 变量的默认值为nil。
--变量的默认值为nil示例: --输出一个全局并没有赋值的变量 print(a) --输出结果: nil --输出一个局部并没有赋值的变量 local a print(a) --输出结果: nil
2. 赋值是将"="右边的内容计算完成后并保存起来然后再赋值给左边(Lua特性,利用此特性可以使用多变量赋值方式直接进行变量交换)
3. 多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语句右边的值会依次赋给左边的变量。
4. 多个变量同时赋值时,变量列表与值列表的元素个数不一致时,采取方式:当变量个数 > 值的个数,按变量个数补足nil 当变量个数 < 值的个数,多余的值会被忽略。
local a = 5 --将5赋值给a变量 local b = a --将a变量内的值赋值给b --多变量赋值 local a,b,c = {123},20,"在吗?" --赋值语句右边的值会依次赋给左边的变量。 print(a,b,b) --输出结果:表地址 20 在吗 --交换变量 local a,b = 10,20 a,b = b,a --交换变量 print(a,b) --输出结果: 20 10
--变量列表与值列表的元素个数不一致
--案例1 local a,b,c = 1,2 --变量列表多于值列表,则将变量列表中的c赋值为nil,因为赋值语句右边的值会依次赋给左边的变量。 print(a,b,c) --输出结果:1 2 nil --案例2 local x,y = 10,20,30 --变量列表少于值列表,则将值列表中30进行省略 print(x,y) --输出结果:10 20
5. 尽可能的使用局部变量: ①.避免了命名的冲突 ②访问速度更快 ③占用内存更小
6. 删除变量
①如果你想删除一个变量,只需要将变量赋值为nil
②当一个变量不等于nil时,这个变量才存在
四. Lua变量的作用域
1. 全局变量整个项目都有效或者说整个lua虚拟机都有效
2. 局部变量
①: 局部变量的作用域仅限于代码块中,可以是一个'控制结构的主体'、或是一个'函数的主体'、或是一个'代码段'-->'变量被声明时的.lua文件'
②: 局部变量会随着'作用域的结束而消失',从而使'垃圾回收器-->gc'能够将其'释放'
③: 访问局部变量的速度比全局变量更快,原因: local的变量是存放在lua的堆栈内,是Array操作,而全局变量是存放在_G的table中,效率不及堆栈
3. 变量的作用域从小到大排序:
1)'全局环境'变量-->(_ENV|'_G')列表
2)'文件'作用范围的local变量 --> "包"或"模块"
3)'函数内'定义的local变量
4)函数内部'程序块'或'复杂语句中'定义的local变量
a = 5 --全局变量a a = 6 --将全局变量a重新赋值 local b = 10 --对于本文件.lua的局部变量,作用域在本文件.lua(模块)中有效 b = 20 --对局部变量b重新赋值 --语句块 do a = 1 --全局变量 local b = 2 --局部变量,仅针对这个语句块有效 b = 3 --对局部变量重新赋值 end print(a,b) --输出结果: 1 20 --函数 function abc() x = 1 --全局变量 local y = 2 --局部变量,仅针对function这个语句块有效 y = 2 --对局部变量重新赋值 end abc() --调用abc函数 --如果不调用abc则输出: nil nil print(x,y) --输出结果: 1 nim --If判断 if true then k = 1 --全局变量 local v = 2 --局部变量,仅针对if这个语句块有效 v = 3 --对局部变量重新赋值 else --上面if中的局部变量在这里是无效的 end --while循环 local i = 100 --局部变量,针对本文件.lua(模块)有效 while i > 10 do --[[这个i是获取的外面i的值,因为: i这个变量首先在while语句块中往上查找,上面没有,则会道上一层作用域中查找 --]] print(i) --输出结果: 100 --这个为什么输出100与while表达式中i原理一样 local i = 5 --局部变量对外面无效 print(i) --输出结果: 5 end print(i) --输出结果: nil --repeat循环 local j = 1 repeat print(j) --输出结果: 1 local j = 100 --创建局部变量 print(j) --输出结果: 100 until j == 100 --[[里面的局部变量j对此表达式有效因为: j这个变量首先查找 repeat这个语句块中的定义如果没有查找到则查找上一层作用域 --]]
4. 将函数赋值给变量,那么这个变量就指向了这个函数的地址,那么就具有了函数的一切功能
--局部变量print就具有了全局函数print功能,可以将全部的全局变量函数修改成模块内的局部函数 --1. 这样写的好处是让脚本执行效率更快,因为局部变量的访问要比全局的快 --2. 并且还节省空间,因为当局部变量的语句块结束后,lua虚拟机会释放内存 local print = print
--下面的代码不能需要单独复制出来运行,测试全局函数与局部函数的执行速度 do local abs = math.abs local t1 = os.clock () for i = 1,100000000 do abs(1) end print("使用局部函数耗时: ",os.clock ()-t1) --耗时: 3.251 end do local t1 = os.clock () for i = 1,100000000 do math.abs(-123) end print("使用全局函数耗时: ",os.clock ()-t1) --耗时: 5.392 end
五. 变量的作用域习题
--变量的作用域实战习题1 local l_var = "第一个模块变量" local a = "第二个模块变量" do print(l_bl) --输出结果: nil local l_bl = "do end的局部变量" print(l_bl) --输出结果: do end的局部变量 function g_func(a) print(string.format("%s, %s",l_var, a) ) end local a = "do end的局部变量" g_func(a) --输出结果: 第一个模块变量, do end的局部变量 end local l_var = "重复定义的第一个模块变量" g_func(a) --输出结果: 第一个模块变量, 第二个模块变量

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了