算来lua脚本的使用也有一年了,记录一些在项目使用过程中碰到的雷点,没注意的话就容易踩坑。
1.迭代器 pairs ipairs
ipairs 有序遍历,适用于数组
local tab = {1,2,3,4,5,6}
for i,v in ipairs(tab) then
print(v)
end
输出:1 2 3 4 5 6
注意:遍历到nil就会停止遍历
local tab_2 = {1,2,3,nil,5,6}
for i,v in ipairs(tab_2) then
print(v)
end
输出:1 2 3
pairs 无序遍历,适用于键值对
local tab = {
[one] = 1,
[two] = 2,
[three] = 3
}
for k,v in (tab) then
print(v)
end
输出:不确定(因为遍历顺序不确定)
2.table.sort()
table.sort是排序函数,它要求排序的目标table必须是从1到n连续的数组,即中间不能有nil
table.sort默认按照升序排序;当额外写了比较函数时,相当于你重载了lua中自带的“<”操作符。这就有一个特别要注意的问题,当两个数相等的时候,比较函数一定要返回false!
a = 5;
b = 5;
c = 5;
d = {a, b, c};
table.sort(d,function(first,senond)
if first < second then
return true;
end
if first > second then
return false;
end
return true;
)
上面那段代码一执行就会报错了,原因就在于最后的一个true。比较函数执行时,a==b,返回true;b==c,返回true;c==a,返回true。但是,我们所写的比较函数实际上是重载了“小于号”操作符,所以程序执行后的结果就是a<b,b<c,c<a,此时就会出问题!
这里我犯过一个错误就是在重写比较函数的时候将“<”号重载为“>=”,返回为true。即,table.sort(d,function(first,second)
return first >= second
end)
这样即使程序执行不报错,当first == second得到的排序结果也不会如我们预期的想象。
3.值类型 / 引用类型
这个是脚本语言反复强调的重点,也是面试必考的知识点,但是当我在处理一个比较复杂的界面运算逻辑的时候还是不可避免的踩了坑。关于这块网上已经有很多定义上的解释,这里我们直接上例子。
值类型:
local a = 3
local b = a
a = a + 1 //这里强调下lua语言当中并没有c++等语言当中的自增自减符号
print(b)
输出:3
引用类型:
local tab_3 = {1,2,3}
local tab_4 = tab_3
local tab_5 = {}
for i,v in(tab_3) do
{
table.insert(tab_5,v)
}
tab_3[2] = 5 //lua数组的下标从1开始
for i,v in(tab_4) do
{
print(v)
}
for i,v in(tab_5) do
{
print(v)
}
输出:1 5 3
1 2 3
我们重点解释下为什么tab_5没有随着tab_3的改变而改变,因为tab_5是重新声明插入数值的表,在堆中开辟了一块新的地址空间,是独立于tab_3的新表。tab_4是在栈中对tab_3的引用,与tab_3拥有一样的寻址空间。