一. 什么是变量
无
二. Lua变量的命令规则
1. 命名规则:数字字母下划线构成 但是不能数字开头
2. 注意 :变量命名必须要包含一定涵义 比如我们要用变量存储一个年龄数值 比如我们用 x=18 别人看我们的源码 看到这里 她不明白 X这个变量为18代表什么意思 如果我们用age=18 那么他一看就明白了 方便我们自己 也方便他人 这个是一个良好的习惯 值得培养
变量名区分大小写
4. 注意:变量名有一些系统关键字 不要占用这些关键字 比如Lua本身的一些语句 if else end function
最好区分写法 比如全局变量 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
变量先在最小的作用域下寻找定义,然后再扩大作用域寻找,之后在去找全局_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
并保存起来然后再赋值给左边(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) --输出结果: 第一个模块变量, 第二个模块变量
这张图可以清晰明了的看清lua代码中语句应该获取哪个作用域的值(重要)