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"