本文对Lua的基础知识做一些简介帮助读者入门。一、基本变量Lua的最常见变量类型有nilnumberstringboolean。和python类似Lua也是一种弱类型的语言。变量的类型可以随意更改不会报错。和很多编程语言不同在Lua里即使该变量从未被声明和初始化调用它也不会出错只是会返回nil。b4.5cI love bad muslimdtrueprint(a,a)--even if a non-existing variable is called, no error is triggered. Just give nilprint(b,b)--just number, no int or doubleprint(c,c)print(d,d)print(type of a is ,type(a))print(type of b is ,type(b))print(type of c is ,type(c))print(type of d is ,type(d))输出a nil b 4.5 c I love bad muslim d true type of a is nil type of b is number type of c is string type of d is boolean变量a未被声明或初始化所以类型是nil。如果想要返回它的值也是nil。另外通过type函数返回的变量的类型是string字符串。print(type of type is ,type(type(a)))输出type of type is string二、Lua的常见操作符Lua里的-*/^等常见数学运算符和大多数编程语言类似但Lua里没有或者等写法。另外Lua不需要分号结束句子。以下是Lua中常见的和其他编程语言不同的操作符1、注释Lua注释的前缀是--。-- The following does not run2、不等号Lua里表示“不等于”的符号是~和Matlab一样。neq4~3print(neq)输出true3、字符串连接Lua里连接两个字符串使用..。ssconcatToms best friend is ..Jerry输出Toms best friend is Jerry4、字符串长度Lua里求字符串长度可以在变量前面加#。print(length of c is ,#c)输出length of c is 175、字符串的拼接字符串的拼接和很多编程语言类似用%s%d放在要插入字符的地方。使用函数string.format()按照以下格式进行字符串拼接。ssformatstring.format(Both %d and %d are even number,4,6)输出formatted string: Both 4 and 6 are even number6、代码块和CJava的{}Python的缩进不同Lua的代码块表示和Matlab比较类似也以ifwhile等表示开始end表示代码块结束。具体在后面几章会详述。三、分支结构Lua的if语句的格式是if … elseif … else … endg4ifg4thenprint(g4)elseifg7thenprint(g7)elseprint(neither)endLua里没有switch … case …的语句四、循环结构Lua里有固定次数的for循环也有条件循环。1、for循环for循环可以让一个变量从起始值到终点值逐步增加。步长默认唯一也可自定义。句法为for … do … endfori2,5do--from 2 to 5 step 1. Both start and end are includedprint(i,i)end以上语句是i从2到5步长为1的for循环。注意和python的range()不同lua里最大值和最小值都包括。所以输出是i 2 i 3 i 4 i 5也可以步数不为1例如forj3,12,3do--from 3 to 12 step 3print(j,j)end以上语句是i从3到12步数为3的循环。输出是j 3 j 6 j 9 j 122、while循环while循环是一种“当循环”结构表明在符合某条件时执行循环。句法为while … do … end。num0whilenum5doprint(num,num)numnum1--Dont use num 1 or numend该语句表示当num 5时执行循环。3、repeat循环repeat循环是一种“知道循环”结构表明在符合某条件时退出循环。句法为repeat … until …。注意这里不需要end。repeatprint(num,num)numnum-1untilnum0该语句表示当num 0时退出循环。五、函数1、函数的定义Lua中的函数也是一个变量类似Swift里的closure闭包。有两种定义函数的方式第一种functionF1()print(This is function F1)end第二种F2function()print(This is function F2)end注意F1可以被当成一个变量。现在运行下列语句F1DF1此时函数F1D()和F1()一模一样。2、函数的输入和输出同样函数很多时候是需要有输入和输出的。下面构建一个有4个输入4个输出的函数functiongetEachVariablePlus1(v1,v2,v3,v4)--a function can have multiple inputs and also multiple outputsiftype(v1)numberthenout_v1v11endiftype(v2)numberthenout_v2v21endiftype(v3)numberthenout_v3v31endiftype(v4)numberthenout_v4v41endreturnout_v1,out_v2,out_v3,out_v4现在运行这个函数a,b,c,dgetEachVariablePlus1(3,13,23,nn)print(string.format(values of a, b, c, d are %s, %s, %s, %s,a,b,c,d))显然v4的类型不是number所以out_v4不会被赋值。因此out_v4的输出值为nil。values of a, b, c, d are 4, 14, 24, nil那么如果一个函数没有输出我把函数输出赋予一个变量PythonMatlabCJava等都会出错。那么在Lua中呢rF1F1()print(The return of F1 is ,rF1)答案是不会。既然F1()无输出rF1就被赋予nil。The return of F1 is nil同样如果函数的实际输入参数个数超过了定义的个数运行时也不会报错。getEachVariablePlus1(4,6,1,3,8)最后一个输入8就会被忽略。如果我函数有多个输出我只要前几个输出呢aq,bqgetEachVariablePlus1(4,6,1,3)此时函数的前两个输出out_v1和out_v2分别被赋予aq和bq。另外两个输出被舍弃。那我想要后几个输出呢答案是把前几个输出用_代替。_,_,cq,dqgetEachVariablePlus1(4,6,1,3)此时函数的后两个输出out_v3和out_v4分别被赋予cq和dq。不过如果把函数的运行结果直接放入print将会打印函数的所有输出print(return of the function is ,getEachVariablePlus1(4,6,1,3))输出return of the function is 5 7 2 43、函数输出函数不像在C中函数定义不允许嵌套在Lua以及Swift等函数也可以输出另一个函数。calculatorfunction(operator)ifoperatorthenreturnfunction(a,b)returnabendelseifoperator-thenreturnfunction(a,b)returna-bendelsereturnfunction()endendend这个函数返回的也是一个函数。getCalccalculator(t)print(getCalc(2,3),getCalc(2,3))输出getCalc(2,3)因为getCalc是由calculator函数里的分支结构里依据第三种情况给出的是没有输出的函数所以getCalc(2,3)是nil。4、局部变量和全局变量和大多数常见编程语言不同Lua中的变量在没有特别说明时都是全局变量。functionloc()gbv10endloc()print(gbv, which is a global variable, is now ,gbv)在该函数中gbv是全局变量。所以尽管loc()已经运行完毕gbv仍然存在且值为10gbv, which is a global variable, is now 10但可以通过关键字local规定一个变量是局部变量functionloc2()locallcv10endloc2()print(lcv, which is a local variable, is now,lcv)在该函数中以local为前缀的lcv是局部变量。一旦loc2()运行完毕lcv就不再存在成为nil。lcv, which is a local variable, is now nil六、表在Lua中表和Python的list一样每个元素的类型不一定要相同。Lua中的表用大括号表示。tab1{Good,30,nil,tg,true,nil}1、表的长度和字符串类似表的长度也可用#。注意这个用#算出的长度不包括最后的nilprint(the length of tab1 is ,#tab1)输出the length of tab1 is 5显然只计到第五个true为止。2、表的元素提取和PythonCSwift不同在Lua中表的默认索引值和Matlab类似以1开头。print(element 2 of tab1 is,tab1[2])--in Lua, table index starts from 1print(element 10 of tab1 is,tab1[10])--even it is out of index, no error will be triggered, just return nil输出element 2 of tab1 is 30 element 10 of tab1 is nil同样索引号为10时虽然超出了表的长度但不会报错只返回nil。3、表的自定义索引除了Lua给每个元素自动赋予的从1开始的索引值外也可以自行给元素赋予数字或非数字索引。Tom{[job]sales,[age]45,[5]really?}这里表Tom有三个索引jobage5。这个表有些类似Python、Swift里的字典。根据非数字索引提取元素的方式有两种Tom[job]或者Tom.job两者等价。但是根据数字索引提取元素的方式只有一种Tom[5]print(Toms job is ,Tom[job], and his age is ,Tom.age, and 5 element is ,Tom[5])--even the index is string 5, still can not use dot to get element输出Toms job is sales and his age is 45 and 5 element is really?4、更改或添加或删除元素更改元素更改元素的方法Tom.age50添加元素添加元素的方法也类似可以理解为把一个索引对应的元素的值从nil改为非nil值。如果想附加一个元素到最后一个索引后面使用table.insert(Tom, China)删除元素删除元素如果是依据数字索引值请用table.remove(Tom, 1)移除第一个元素也可以用Tom[1] nil效果一致。如果是依据非数字索引值只能用Tom[age] nil。如果运行table.remove(Tom, age)则会出错5、遍历表中元素有两种方法遍历表中元素pairspairs函数遍历表中所有的非nil元素。输出索引及其对应的元素。Linda{[1]ele1,[age]20,[e]nil}fori,vinpairs(Linda)doprint(the element ,i, of Linda is ,v)end输出the element 1 of Linda is ele1 the element age of Linda is 20ipairsipairs只遍历索引为数字的元素从1开始出现元素值为nil的就停止。Linda{[1]ele1,[age]20,[e]nil}fori,vinipairs(Linda)doprint(the element ,i, of Linda is ,v)end输出the element 1 of Linda is ele16、一个Lua自带的表Lua自带了一个表叫_G。该表包括所有已加载的元素。functionhello()print(Hello Lua)endfori,vinpairs(_G)doprint(i,v)end输出pairs function: 0x1006ad9ac select function: 0x1006addac rawset function: 0x1006add50 print function: 0x1006b63d8 rawget function: 0x1006add00 __lua_objc userdata: 0x140bcbe60 os table: 0x15a60b140 io table: 0x15a60b080 string table: 0x15a60b180 coroutine table: 0x15a60b000 package table: 0x15a60ae00 ipairs function: 0x1006ad774 table table: 0x15a60b040 pcall function: 0x1006ada40 warn function: 0x1006adb8c loadfile function: 0x1006ad7c8 require function: 0x157b77000 hello function: 0x157b762e0 debug table: 0x15a60b2c0 utf8 table: 0x15a60b280 getmetatable function: 0x1006ad71c math table: 0x15a60b200 collectgarbage function: 0x1006ad444 type function: 0x1006ae180 rawlen function: 0x1006adc9c dofile function: 0x1006b64c4 next function: 0x1006ad954 rawequal function: 0x1006adc4c assert function: 0x1006ad3c4 tostring function: 0x1006ae148 load function: 0x1006ad84c error function: 0x1006ad6a0 setmetatable function: 0x1006ade68 tonumber function: 0x1006adf0c _VERSION Lua 5.4 _G table: 0x15a60a580 xpcall function: 0x1006ae1e4