lua 2

表达式

表达式用于表示值。Lua的表达式中可以包含数字常量、字面字符串、变量、一元和二元操作符及函数调用。另外有别于传统的是,表达式中还可以包括函数定义和table构造式。

算术操作符

Lua支持常规的算术操作符有:二元的“+”、“-”、“*”、“/”、“^(指数)”、“%”,一元的“-”。所有这些操作符都可用于实数。

关系操作符

< > <= >= == ~=

所有这些操作符的运算结果都是true或false

对于table、userdata和函数,lua是作引用比较的。也就是说,只有当它们引用同一对象时,才认为它们相等。

逻辑操作符

逻辑操作符有and、or和not。与条件控制语句一样,所有的逻辑操作符将false和nil视为假,而将其他的任何东西视为真。对于操作符and来说,如果它的第一个操作数为假,就返回第一个操作数;不然返回第二个操作数。对于操作符or来说,如果它的第一个操作数为真,就返回第一个操作数;不然就返回第二个操作数。

and和or都使用“短路求值(short-cut evaluation)”,也就是说,它们只会在需要时才去评估第二个操作数。

字符串连接

在lua中连接两个字符串,可以使用操作符“..”。如果其任意一个操作数是数字的话,lua会将这个数字转换成一个字符串。

lua中的字符串是不可改变的值。连接操作符只会创建一个新字符串,而不会对其原操作数进行任何修改。

table构造式

构造式是用于创建和初始化table的表达式。这是lua特有的一种表达式,并且也是lua中最有用、最通用的机制之一。

最简单的构造式就是一个空构造式{},用于创建一个空table。构造式还可以用于初始化数组。days={"sunday","monday","tuesday","wednesday","thursday","friday","saturday"}

print(days[4]) -->wednesday

lua还提供了一种特殊的语法用于初始化记录风格的table:

a={x=10,y=20}

以上这行代码等价于这些语句:

a={};a.x=10;a.y=20;

无论使用哪种方式来创建table,都可以在table创建之后添加或删除其中的某些字段:

w={x=0,y=0.label="console"}

x={math.sin(0),math.sin(1),math.sin(2)}

w[1]="another field" --添加key 1到table w

x.f=w --添加key 'f'到table x

print(w["x"]) -->0

print(w[1]) -->another field

print(x.f[1]) -->another field

w.x=nil --删除字段“x”

那就是所有table都可以构建成一样的,而构造式只是在table初始化时刻发挥作用。每当lua评估一个构造式时,就会先创建一个新的table,然后初始化它。这样,就能用table写出一下的链表代码:

list=nil

for line in io.lines() do

list = {next=list,value=line}

end

这段代码从标准输入中读取每行的内容,然后将每行按相反的次序存储到一个链表中。链表的每个结点都是一个table,table中含有两个字段:value(每行的内容)和next(指向下一个结点的引用)。以下代码遍历了该链表,并打印了其内容:

local l = list

while l do

print(l.value)

l=l.next

end

lua程序中很少会用到链表。列表数据一般是通过数组来实现的。

将记录风格的初始化与列表风格的初始化混合在一个构造式中使用:

polyline={color="blue",thickness=2,npoints=4,

{x=0,y=0},

{x=-10,y=0},

{x=-10,y=1},

{x=0,y=1}

}

上例演示了如何通过嵌套的构造式来表示复杂的数据结构。每个polyline[i]元素都是一个table,表示一条记录:

print(polyline[2].x) -->-10

print(polyline[4].y) -->1

这两种风格的构造式各有其限制。例如,不能使用负数的索引,也不能用运算作为记录的字段名。为了满足这些要求,lua还提供了一种更通用的格式。这种格式允许在方括号之间,显式地用一个表达式来初始化索引值:

opnames={["+"]="add",["-"]="sub",["*"]="mul",["/"]="div"}

i=20;s="-";

a={[i+0]=s,[i+1]=s..s,[i+2]=s..s..s}

print(opnames[s]) -->sub

print(a[22]) -->---

这种语法看似繁琐了一点,但却非常灵活。无论是列表风格初始化,还是记录风格的初始化,其实都是这种通用语法特例。构造式{x=0,y=0}等价于{["x"]=0,["y"]=0},构造式{"r","g","b"}等价于{[1]="r",[2]="g",[3]="b"}。

对于某些情况如果真的需要以0作为一个数组的起始索引的话,通过这种语法可以轻松做到:

days={[0]="sumday","monday","tuesday"省略}

现在第一个值"sunday"的索引就为0了。这个索引0并不影响其他元素,"monday"照常索引为1,因为它是构造式中列表格中的第一个值,后续其他值的索引依次递增。不推荐在lua中以0作为数组的起始索引。大多数内建函数都假设数组起始于索引1,若遇到以索引0开始的数组,它们就无法进行正确地处理了。

可以在最后一个元素后面写一个逗号,这个特征是可选的,也是合法的:

a={[1]="red",[2]="green",[3]="blue",}

再一个构造式中还可以用分号代替逗号。通常会将分号用于分割构造式中不同的成分。