第3章表达式
3.1 算术操作符
Lua支持的常规算术操作符有:二元的 +(加)、-(减)、*(乘)、/(除)、^(指数)、%(取模),一元的 -(负号)。其中取模操作符的定义:a % b = a - floor(a/b) * b。
3.2 关系操作符
Lua提供的关系操作符有: < > <= >= == ~=
这些操作符的运算结果都是 true 或 false 。
对于table、userdata和函数,Lua是做引用比较的,也就是说,只有当它们引用同一个对象时,才认为它们相等。例如:
a= {}; a.x = 1; a.y = 0;
b= {}; b.x = 1; b.y = 0;
c = a;
其中a == c ,但a ~= b。
3.3 逻辑操作符
Lua的逻辑操作符有and、or和not。与条件控制语句一样,所有的逻辑操作符将 false 和 nil 视为假,除此之外都视为真。对于 and 操作符来说,如果它的第一个操作数为假,就返回第一个操作数,否则返回第二个操作数;对于 or 操作符来说,如果它的第一个操作数为真,就返回第一个操作数,不然就返回第二个操作数。
print(4 and 5) -- 5
print(nil and 13) -- nil
print(false and 5) -- false
print(4 or 5) -- 4
print(false or 5) -- 5
操作符 not 永远只返回true或false:
print(not nil) -- true
print(not false) -- true
print(not 0) -- false
print(not not nil) -- false
3.4 字符串连接
在Lua中用“..”(两个点)连接两个字符串。若其中有一个或都是数字的话,Lua会将数字转化为字符串。
因为Lua的字符串是不可变值,连接操作符只会创建一个新的字符串,而不会修改原字符串。
3.5 优先级
Lua操作符的优先级如表3-1所示(从高到低):
3.6 table构造式
构造式用于创建和初始化table的表达式。最简单的构造式就是一个空构造式{},用于创建一个空table。构造式还可以用于初始化数组,例如:
Days = {“Sunday”,“Monday”,“Tuesday”,“Wednesdat”,“Thursday”,“Friday”,”Saturday”};
Lua会将Days[1]初始化为字符串“Sunday”,Days[2]为”Monday”,以此类推。
构造式的第一个元素的索引值为1,不是0。
可以在最后一个元素后面写一个逗号,这个特性是合法的:
A = {[1] = “red”, [2] = “green”,[3] = “blue”,};
在一个构造式中还可以用分号代替逗号,通常用于分隔构造式中不同的成分,例如:
A = {x=10, y=45; “one”, “two”};
第4章 语句
4.1 赋值
赋值(assignment)的基本含义是修改一个变量或一个table中字段的值。
Lua允许“多重赋值”,也就是给多个变量赋值,例如:
a, b = 10, 2*x ; -- a = 10, b = 2*x
【注意】若要初始化一组变量,应为每个变量提供一个值:
a, b, c = 0, 0, 0; -- a = 0, b = 0, c = 0
a, b, c = 0; -- a = 0, b = nil, c = nil
若一个函数f可以返回多个值,则 a, b = f() 中a接受第一个值,b接受第二个值。
4.2 局部变量与块(block)
Lua通过local语句来创建局部变量:
j = 10; -- 全局变量
local k = 9; -- 局部变量
局部变量的作用域仅限于它所在的块。一个块(block)是一个控制结构的执行体、或者是一个函数的执行体、或者是一个程序块(chunk)。
“尽可能地使用局部变量”是一种良好的编程风格。局部变量可以避免将一些无用的名称引入全局环境从而搞乱全局环境。此外,局部变量的访问速度比全局变量快。一个局部变量通常会随作用域的结束而消失。
4.3 控制结构
4.3.1 if then else
if 语句先测试其条件,然后根据测试结果执行 then 部分或 else 部分,else部分可无。
使用 elseif 编写嵌套的 if。 Lua不支持switch语句。
4.3.2 while
Lua先测while的条件,如条件为假,循环结束;否则继续执行循环体。
local i = 1
while a[i] do
print(a[i])
i = i + 1
end
4.3.3 repeat
一条 repeat - until 语句重复执行其循环体直到条件为真时结束。测试是在循环体之后做的,所以循环体至少执行一次:
repeat
line = io.read()
until line ~= " "
print(line)
4.3.4 数字型for(numeric for)
for 语句有两种形式:数字型 for (numeric for) 和泛型 for (genericfor)。
数字型 for 的语法如下:
for var = exp1, exp2, exp3do -- 语句1
<执行体>
end
上述例子语句1中 var值(初始化为exp1)以 exp3 的值作为相加数,使 var的值变化到exp2。若没有exp3,则默认相加数为1。若不想给循环设置上限的话,可将 exp2的值换为math.huge:
for i = 1, math.huge do
if (0.3*i^3 – 20*i^2 – 500 >= 0) then
print(i)
break
end
end
4.3.5 泛型for(generic for)
泛型for循环通过一个迭代器(iterator)函数来遍历所有值:
-- 打印数组a的所有值
for i, v in ipairs(a) do print(v) end
Lua的基础库提供了ipairs,用于遍历数组的迭代器函数。在每次循环中,i会被赋予一个索引值,同时v被赋予索引值i所对应的元素值。
function add(a)
local sum = 0
for i,v in ipairs(a) do
sum = sum + v
end
return sum
end
s = {1,2,3,4}
print(add(s))
4.4 break与return
break和return语句用于跳出当前的块。
break语句用于结束一个循环,它只会跳出包含它的那个内部循环(for、repeat和while),而不会改变外层的循环。
beturn语句用于从一个函数中返回结果,或者用于结束一个函数的执行。