4.1 赋值
Lua支持“多重赋值”,即可以一次性将多个值赋予多个变量。
a,b = 10, 2*x
在多重赋值中,Lua先对等号右边所有元素求值,然后才执行赋值,这样便可以进行交叉赋值
x,y = y,x
a[i], a[j] = a[j], a[i]
Lua总是会将等号右边值的个数调整到与左边变量数量相等。规则是:若值的个数少于变量个数,则多余的变量被赋予nil;若值的个数多于变量个数,则舍多余的值。
a,b,c = 0, 1 -->c为nil
a,b = 0, 1, 2 -->值2被舍弃
注意要初始化一组变量,应为每个变量都提供一个值
a,b,c = 0 -->只有a被赋值
a,b,c = 0, 0, 0
多重赋值语句并不比等价的多条赋值语句更快。其一般比较多用于交换两个变量的值,以及收集函数的多个返回值。
4.2 局部变量与块
通过local语句来创建局部变量。与全局变量不同的是,局部变量的作用域仅限于声明它的那个块。一个块是一个控制结构的执行体、或者是一个函数的控制体,再或者是一个程序块。另外,局部变量会屏蔽相同名称的全局变量。
x=10
local i = 1
while i <= x do
local x = i * 2
print(x) -->局部变量x
i = i + 1
end
print(x) -->全局变量x
尽可能的使用局部变量是一种良好的编程习惯,局部变量可以避免污染全局作用域,此外,访问局部变量比访问全局变量更快,最后,一个局部变量通常会随着其作用域的结束而消失,这样便使垃圾收集器可以及时释放其值。
在Lua中,有一种习惯的写法:
local foo = foo -->用全局变量foo来初始化局部变量foo
这种写法可以加速在当前作用域中对foo的访问。
4.3 控制结构
4.3.1 if then else
若要编写嵌套的if,则用elseif
结构:
if cond then ... end
if cond then ... else ... end
if cond then ... elseif ... then ... else ... end
4.3.2 while
结构:
while cond
...
end
4.3.3 repeat
结构:
repeat
...
until cond
4.3.4 数字型for
结构:
for var = exp1,exp2,exp3 do
...
end
var从exp2变化到exp2,每次变化步长递增exp3,exp3若不指定,则默认为1, 如果不想给循环设置上限,则可以使用math.huge:
for i = 1, math.huge do
...
end
另外还需要注意一些细节,首先,for的三个表达式是在循环开始前一次性求值的,其次,控制变量会自动声明为for语句的局部变量,并且只在循环体内部可见,因此,控制变量在循环结束后就不存在了。最后一点,不要在循环过程中改变控制变量的值,否则将导致不可预知的结果。
4.3.5 泛型for
泛型for通过迭代器来遍历所有值。泛型for通过不同的迭代器,几乎可以遍历所有东西,并且写出的代码极具可读性。标准库提供了几种迭代器,包括io.lines,pairs,ipairs,string.gmatch等。
泛型for和数字型for有两个2共同点:1.循环变量是循环体的局部变量;2.绝不应该对循环变量做任何赋值。
4.4 break与return
break语句用于结束一个内部循环,而不会影响外层的循环,return则用于结束一个函数的执行。
由于语法构造的原因,break或return只能是一个块的最后一条语句。换句话说, 它们是程序块的最后一条语句,或者是end、else、until前的最后一条语句
有时我们希望那些位于return后面的语句无法执行(比如调试时),那么可以通过手动添加do end来实现:
function foo()
do return end
...
end