Lua表达式中可以包含数字常量,字面字符串,变量,一元和二元操作符及函数调用。另外有别于传统的是,表达式还可以包含函数定义和table构造式。
3.1 算术操作符
算术操作符有:二元加“+”,减“-”,乘“*”,除“/”, 指数“^”,取模“%”,一元的负号“-”。
在Lua中,所有操作符均可用于实数,特别要注意取模运算的使用。
取模操作符是根据以下规则定义的:
a%b=a-floor(a/b)*b; //floor(x)为向下取整,取不大于x的最大整数
对于整数而言,计算结果的符号永远与第二个参数相同。
而对于实数,有如下使用方式:
x%1 -->结果为x的小数部分
x-x%1 -->结果为x的整数部分
x-x%0.01 -->x精确到小数点后两位的结果
angle%(2*math.pi) -->将任意角度转换为区间[0,2π]
3.2 关系操作符
Lua提供的关系操作符:
< > <= >= == ~=
要注意的是,如果两个值具有不同的类型,则Lua认为它们是不相等的。nil只与自身相等。
只能对两个数字或者两个字符串进行大小性比较,其他类型均不支持此操作。如果比较的两个值类型不同,则会引发一个错误,故一个字符串和一个数字是不能进行大小性比较的。对于字符串的大小,Lua是按照字典顺序进行比较的。
3.3 逻辑操作符
逻辑操作符有:
and or not
对于and而言,如果它的第一个操作数为假,则返回第一个操作数,否则返回第二个操作数。对于or而言,如果它的第一个操作数为真,则返回第一个操作数,否则返回第二个操作数。
从上我们知道and和or也采用短路求值,但是不同的是它们的返回值并不是true或者false,而是可以是任何类型的值。
print(4 and 5) -->5
print(nil and 13) -->nil
print(false and 13) -->false
print(4 or 5) -->4
print(false or 5) -->5
基于这种特性,Lua中有一种常用写法“x=x or v”,它等价于“if not x then x = v end”,这种写法可以用于给参数设定默认值
function(a)
a = a or 5 -->将参数a默认值设为5
...
end
还有另一种习惯写法“(a and b) or c”,类似于a ? b :c,但前提是b不为假。
not用于取反,其永远只返回true或false。
3.4 字符串连接符
在Lua中连接两个字符串,可以使用“..”。
要注意的是,Lua中字符串是不可变的值,连接操作只会创建一个新的字符串,而不会对原来的字符串进行修改。
3.5 优先级
略
3.6 table构造式
构造式是用于创建和初始化table的表达式。
最简单的构造式是一个空构造式{},用于创建一个空table。
构造式还可用于初始化数组,索引默认从1开始。
num = {1, 2, 3} //a[1] = 1, a[2] = 2, a[3] = 3
另外还提供了一种特殊的语法用于初始化table
a = {x = 10, y = 20} //a["x"] = 10, a["y"] = 20,如果自己指定了索引,则程序不会为其生成数字索引
每当Lua评估一个构造式时,都会创建一个新的table,然后初始化它,这样,就能用table写出以下的链表代码:
//创建链表
list = nil
for line in io.lines() do
list = {next = list, value = line}
end
//遍历链表
local l = list
while l do
print(l.value)
l = l.next
end
Lua还提供了一个更通用的初始化方式
opnames = {["+"] = "add", ["-"] = "sub", ["*"] = "mul", ["/"] = "div"}
通过这种方式,我们可以在初始化中使用任何类型的索引值。
某些情况下你可以指定数组的初始索引值
num = {[0] = 0, 1, 2, 3, 4, 5} -->这样数组索引从0开始,后面的元素索引依次递增
最后,在一个构造式中可以用分号代替逗号,通常用于分割不同的成分。
local t = {x= 10, y = 45; "one", "two", "three"} -->t[1] = "one", t[2] = "two"