在上期《Lua 优化:破解全局变量的使用困局》中,我们以UWA 本地资源检测内相关的规则为依托,针对全局变量为大家介绍了在 Lua 中多种需要关注的使用场景,并结合简单的代码示例进行了直观说明。
本期我们将从 “局部变量” 入手,来分析 Lua 使用时可能发生的各种不合理情况。我们依然会以简单的例子来帮助大家读懂这些规则,力图以浅显易懂的表达,让职场新手或优化萌新能够深入理解。
在 Lua 中,我们会频繁使用到局部变量,但编写时代码的不规范或者逻辑上的疏忽,往往会导致变量未被正确应用:比如相关的变量或者值没有被正确使用和参与运算;又或者某些变量或者值被覆盖。这些不正确、不规范的代码使用就很有可能导致无法预知的错误和资源上的浪费。接下来我们进行具体分析。
1.1 未被使用的局部变量
例如,声明了一个局部变量 bar:
local bar=5
但之后再没有使用过局部变量 bar。
1.2 未被使用的参数变量
在如下代码中:
function fun(x,y)
print(x)
end
函数 fun 有两个参数 x,y。但参数 y 从未被使用过。
1.3 未被使用的循环变量
在如下代码中:
for i=1,100 do
print("huh")
end
局部变量 i 从未被使用过。
上述三条规则,都表示代码中有从未被使用的局部变量。
1.4 访问了一个未被设置的局部变量
在如下代码中:
local num
print(num.string)
局部变量 num 还未被赋值就被访问了,num 还是一个 nil,这样会造成错误。
1.5 设置了一个局部变量,但从未被访问
在如下代码中:
local num=5
num=6
局部变量 num 有被赋值的操作,但从未被使用过。
1.6 设置了一个参数变量,但从未被访问
在如下代码中:
function fun(num)
num=6
end
参数 num 有被赋值的操作,但从未被使用过。
1.7 设置了一个循环变量,但从未被访问
在如下代码中:
for i=1,100 do
i=2
end
循环变量 i 有被赋值的操作,但从未被使用过。
上述三条规则,都表示代码中有局部变量被赋值的操作,但从未被使用过。
1.8 更改了一个局部变量,但从未被访问
在如下代码中:
local bar={"aaa"}
bar.dd='ff'
局部变量 bar 的域 “dd” 被赋值为 “ff”,但局部变量 bar 从未被使用过。表示代码中有局部变量的域发生改变的操作,但该局部变量从未被使用过。
2.1 未被使用的一个局部变量的值
在如下代码中:
local o = 5
print(o)
o=6
局部变量 o 的值被修改为 6 之后,再未被使用过。
2.2 未被使用的一个参数变量的值
在如下代码中:
function fun(x)
x=3
print(x)
end
参数 x 被赋值为 3,然后被使用(输出)。但参数 x 初始值从未被使用。
2.3 未被使用的一个循环变量的值
在如下代码中:
for index=1,100 do
index=2
print(index)
end
循环变量 index 被赋值为 2,然后被使用(输出)。但循环变量 index 的初始值从未被使用。
2.4 未被使用的一个表文字域的值
在如下代码中:
local bar = {b = 1, b = 2}
表 bar 中的 Key 为 “b” 的值被覆盖。
2.5 访问未被初始化的局部变量
在如下代码中:
local bar
if condition()
bar={}
else
print(bar)
else 分支语句中,访问了 bar 这个未初始化的局部变量。
2.6 更改了一个局部变量的值,但从未被访问
在如下代码中:
local function fun(st)
if not st then
st = {}
end
st.aa=2
end
local num
fun(num)
print(num)
>nil
程序原本试图当参数 st 为 nil 的时候初始化 st 为一个 table,然后赋值。但实际上类似于值传递,参数 st 依然是 nil,即局部变量 num 依然是 nil。所以第三行的参数 st 初始化的值,从未被访问过。
2.7 更改了一个未被初始化的局部变量
在如下代码中:
local bar
bar.a=2
bar={}
局部变量 b 在第三行进行初始化操作,而第二行还未初始化的局部变量 b 进行了修改。
3.1 重定义了一个局部变量
在如下代码中:
local bar={}
local bar={"huh"}
局部变量 bar 被重定义。
3.2 重定义了一个参数变量
在如下代码中:
function fun(bar)
local bar={}
end
局部变量 “bar” 和参数 “bar” 同名。
3.3 重定义了一个循环变量
在如下代码中:
for i=1,100 do
local i={}
end
循环变量 “i” 和局部变量 “i” 同名。
3.4 覆盖了一个局部变量
在如下代码中:
local bar
for i=1,100 do
local bar={}
end
在循环语句这段作用域内定义了一个局部变量 “bar”,覆盖了作用域外的同名局部变量 “bar”。
3.5 覆盖了一个参数变量
在如下代码中:
function fun(x)
if condition() then
local x={}
print(x)
else
print(x)
end
end
在 if 分支的作用域中,局部变量 x 覆盖了同名参数 x。
3.6 覆盖了一个循环变量
在如下代码中:
for i=1,100 do
if condition() then
local i={"huh"}
print(i)
else
print(i)
end
在 if 分支的作用域中,局部变量 x 覆盖了同名循环变量 x。
3.7 覆盖了一个上值
在如下代码中:
local bar
function fun()
local bar={}
end
在函数 fun 的作用域中,局部变量 “bar” 覆盖了同名上值 “bar”。
3.8 覆盖了一个上值参数
在如下代码中:
function fun(bar)
local function fun2()
local bar={}
end
return fun2
end
在 fun2 函数作用域中,局部变量 “bar” 覆盖了同名上值参数 “bar”。
3.9 覆盖了一个上值循环变量
在如下代码中:
for index=1,100 do
local function fun()
local index={}
end
end
在函数 fun 作用域中,局部变量 “index” 覆盖了同名上值循环参数 “index”。
希望以上这些简单的示例能在实际的开发过程中为大家带来帮助,从而最大程度上避开这些在使用 Lua 时会遇到的问题。同时,也欢迎大家来使用 UWA 推出的本地资源检测服务,可帮助大家尽早对项目建立科学的检测规范。
万行代码屹立不倒,全靠基础掌握得好!
《场景检测:面片、光影和物理属性》
《场景检测:Audio Listener、RigidBody 和 Prefab 连接》
《场景检测:雾效、Canvas 和碰撞体》
《特效优化 2:效果与性能的博弈》
《特效优化:发现绚丽背后的质朴》
《Prefab 优化:预制体中的各种细节选择》
性能黑榜相关阅读
《那些年给性能埋过的坑,你跳了吗?》
《那些年给性能埋过的坑,你跳了吗?(第二弹)》
《掌握了这些规则,你已经战胜了 80% 的对手!》