lua支持的常规语句基本上与C/Java等语言中所支持语句差不多,包括了赋值、控制结构等,当然也有一些区别,如lua中的多重赋值等。

1. 赋值语句

赋值是最基本、最简单的语句,将变量与值用=相连,=左边为变量,右边为值:

name="Tom"age=201.1 全局变量与局部变量

直接通过上述方式赋值,则变量为全局变量,在任何位置均可被访问。与全局变量相对的是局部变量,只能在被赋值的语句块即当前作用域中被访问。在lua中,语句块可以是一个控制结构的执行体、函数的执行体或使用do end手动构造的程序块:

--手动构造程序块dolocalname,sex="Lucy","female"print(name.."&"..sex)--Lucy&femaleendprint(name.."&"..sex)--stdin:1:attempttoconcatenateglobal'sex'(anilvalue)

建议在编写lua代码时尽可能地使用局部变量。使用局部变量有以下几点好处:

避免污染全局命名空间;

局部变量的访问速度比全局变量更快;

局部变量会随其作用域的结束而消失,使GC可以更快的释放其值。

关于局部变量,在lua中还有一种常见的用法:

localfoo=foo

该语句创建局部变量foo,并用全局变量foo的值对其进行初始化,这样做一来可以暂存全部变量foo的值,二来可以加速在当前作用域对foo的访问。

1.2 多重赋值

python相似,在lua中允许多重赋值:

name,age="Tom",20

为什么说与python相似而没有说相同呢,这是因为在python中,变量的个数和值的个数必须相同,否则会抛出Error。而在lua中,如果变量个数多于值的个数,则多出的变量不会被赋值,即值为nil;如果变量个数小于值的个数,则多出的值会被直接忽略:

--luaname,age,sex="Tom",20--此时name=="Tom",age==20,sex==nilname,age="Tom",20,"male"--此时name=="Tom",age==20,值"male"被忽略#pythonname,age,sex="Tom",20#ValueErrorname,age="Tom",20,"male"#ValueErrorname,age=20#TypeError

多重赋值可以在不引入中间变量的情况下交换两个变量的值:

key="name"value="Tom"key,value=value,keyprint("key=="..key.."&value=="..value)--key==Tom&value==name

多重赋值的另一个比较常见的应用是收集函数的多个返回值,在讲到函数时再做具体展开。

2. 控制语句

控制语句通过逻辑判断即true或false控制程序流程。在提到逻辑判断时还要再强调一遍,lua中所有非false和nil的值都为true,包括数字0和空字符串。

2.1 if/elseif/else

if/elseif/else用于控制单次流程的进行:

name="Tom"ifname=="Lucy"thenprint("Hello,Lucy.")elseifname=="Jordan"thenprint("Hi,Jordan.")elseprint("Yoho,Buddy.")end

elseif的出现使流程更简便,可以省去else if的一个多余的end。

2.2 while & repeat until

while和repeat until都用来循环,repeat until与C/C++/Java中的do while相同,先执行后判断,循环至少会执行一次;while则先判断后执行,循环可能一次都不执行:

--whilecond=truewhileconddoline=io.read()ifline~=""thenprint(line)cond=falseendend--repeatuntilrepeatline=io.read()untilline~=""print(line)2.3 for

for同样用来做循环,用for做循环有两种形式,一种针对数字,一种针对泛型:

--针对数字--从1循环到10,步长为1(不指定步长时默认为1)fori=1,10,1doprint(i*2)--针对泛型--两个内置函数,pairs()针对数组形式的table,ipairs()针对对象形式的table--数组形式的tabledays={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}fork,vinipairs(days)doprint("index=="..k.."&value=="..v)end--对象形式的tablepeople={name="Tom",sex="male",job="engineer",address="Beijing"}fork,vinpairs(people)doprint("key=="..k.."&value=="..v)end

下面我们给出for循环在python中的实现形式,方便对照理解:

#针对数字#从1循环到10,步长为1(不指定步长时默认为1)foriinxrange(1,10,1):#可以用range()代替xrange()printi#针对泛型#listdays=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]#方式一foriindays:print"index==%s&value==%s"%(days.index(i),i)#方式二foriinxrange(len(days)):print"index==%s&value==%s"%(i,days[i])#dictpeople={"name":"Tom","sex":"male","job":"engineer","address":"Beijing"}fork,vinpeople.iteritems():#print"key==%s&value==%s"%(k,v)#可以用people.items()代替people.iteritems()3. 退出语句3.1 break

break用于退出循环:

fori=1,10doifi%3==0thenprint(i)breakendend

要注意的一点是,lua中没有大多数编程语言中都有的continue关键字,即不可使用continue直接退出单次循环。

3.2 return

return用于退出函数:

functionplus(num1,num2)returnnum1+num2end

如果函数中没有显式return,则函数会返回nil,和JavaScript中返回undefined,python中返回None相同。

在调试程序时,如果想让一个函数什么都不做,可以使其直接return,但return必须是语句块中的最后一条语句,如下做法会报语法错误:

functionfoo()return--someactions--dosomething

若想达到所要的效果,可以将return用一个do end构造的语句块包起来:

functionfoo()doreturnend--someactions--dosomething

完。