由于lua是一门动态类型语言,所以对于lua的变量,是不需要提前声明类型的。lua的变量在使用时才会确定它的类型。
lua支持的类型有以下几种:nil、boolean、 number、string、userdata、function、thread 和 table。使用type函数可以用来测试变量的类型,如:
t = 10 print(type(t)) -- number t = "hello world" print(type(t)) -- string t = type print(type(t)) -- function t = nil print(type(t)) -- nil t = false print(type(t)) -- boolean t = {a, b, c} print(type(t)) -- table通过以上的代码可以看出,t的类型并不是固定的,实际的类型需要使用时才能确定。
nil:
空类型。只有一个值nil。每一个声明但是未定义的变量都会等于默认值nil。对一个变量赋值为nil,相当于删除这个变量。
boolean:
布尔类型,有两个值,false和true。在lua中,所有值都可以作为控制语句的条件进行判断,但是只有nil和false会认定为假。其余都认为是真。注意:0及空串也会被认为是真。
t="" --或是t = 0 if t then print(true) else print(false) end以上语句执行结果为true。
Numbers:
表示数字。注意:并不是表示整数。在lua中,numbers类型的变量可以处理任何长度的数字,不论是整数,还是负数,还是小数。
t = -1 print(t) -- -1 t = 0.3e12 print(t) -- 300000000000.0 t = 0.4 print(t) -- 0.4 t = 4.57e-3 print(t) -- 0.00457 t = 5e+20 print(t) --5e+20
表示字符串序列。lua中字符串是不可以修改的,如果要修改一个字符串,必须将修改后的字符串存放到一个新的变量中。字符串可以用双引号、单引号或是[[..]]来囊括。如果字符串中存在引号的话,可以使用转义字符‘\'来保证。
\a bell \b backspace -- 后退 \f form feed -- 换页 \n newline -- 换行 \r carriage return --回车 \t horizontal tab --制表 \v verticaltab \\ backslash -- "\" \" doublequote --双引号 \' single quote -- 单引号 \[ leftsquare bracket --左中括号 \] right square bracket -- 右中括号
[[..]]多用来包含多行的字符串序列,这种形式的字符串属于纯字符串,不会解释其内部可能包括的转义字符。注意:这种形式的[[..]]不能嵌套使用
page = [[ \t\b\'\'"this is a test ]] io.write(page)打印结果如下:\t\b\'\'"this is a test。lua解释器不会解释[[..]]内包含的转义字符等。
lua会在需要时自动转化string和numbers。当string需要进行算术操作时,会转化成numbers。如:
print("10" + 10)执行结果为:20.0。string “10”被转化为numbers:10。
如果string不能被转化为numbers时,就会报错。
print("hello" + 1) -- ERROR(cannot convert"hello")
当lua解释器检测到期望string时,会将numbers变量转化为string。如:
print(10 .. 20) -->1020符号“..”是字符串连接符,会将两段字符串连接到一起。上述代码中,将10与20都转化为了string,然后连接到一起,输出完整的string,1020。
注意:.. 字符串连接符。 当数字作为该符号的参数时,需要以空格间隔,避免出错。
注意:虽然lua会自动转化字符串和数字,但是不能用来直接对比。如:10 == "10" 这样永远都是错的。如果需要对比,需要使用tonumber函数。10 == tonumber("10"),如果不能转换,tonumber会返回nil。
function:
lua中的function类型表示函数变量,它可以像其他类型的变量一样,可以赋值给变量,可以当做其他函数的实参使用,也可以作为函数的返回值。这一点有点像C语言的函数指针。
userdata 可以将 C数据存放在 Lua变量中,userdata 在 Lua 中除了赋值和相等比较外 没有预定义的操作。userdata 用来描述应用程序或者使用C实现的库创建的新类型。
线程类型的变量稍后再叙述。
table:
类似于python中的字典,只能通过构造式来构造。最简单的构造函数为{},这种方式会创建一个空表。如:t = {}, t 就是一个空表。
定义方式1:
mytable = { a = 10, b = 11, c = 20, ddd = 30 } -->等价于 mytable = {}; mytable.a = 10; mytable.b = 11; mytable.c = 20; mytable.ddd = 30 print(mytable["a"]) -- 101)、 table 中的每项要求是 key = value 的形式
mytable = { 10, 12, 13 } print(mytable[1]) -- 10 print(mytable[2]) -- 12 print(mytable[3]) -- 13table 中可以出现没有 key 的项,这个时候,lua 会把这个 table 当做一个数组来看待,这个项的key就是它在数组中的下标(从1开始)
定义方式3:
如果在构造式中,以上两种方式都出现了,类似下面这种:
mytable = { 10, ddd = 30, 12, 13 } print(mytable[1]) -- 10 print(mytable[2]) -- 12 print(mytable[3]) -- 13lua解释器,会按照定义方式2的方式解释这个table,“ddd = 30”项在以数字为下标的数组中,被忽略掉了。会跳过这个项,查找符合规则的数组项来填充数组,下标会取下一个连续值。如果要访问"ddd=30"的话,可以使用如下方式:mytable["ddd"],这个值为30。
定义方式4:
在构造式中,显示的指明数组下标:
a={[1]=5,[2]=6,[34]=7} print(a[1]) -- 5 print(a[2]) -- 6 print(a[34]) -- 7这种方式与第一种方式类似,只不过它显示指明的下标不是字符串,而是数字,需要用[]将下标包起来。
注意:lua的构造函数中可以使用分号和逗号。逗号一般被用来分割不同类型的表元素。如:{x=10, y=45;"one","two","three"}
lua中的表中,有显式索引的可以使用显式索引,没有显式索引的则以1、2、3为索引。如:
polyline ={x=10, y=45;"one","two","three";z=3;"bs"}, print(polyline.x) --10 print(polyline.y) --45 print(polyline.z) --3 print(polyline[1]) --one print(polyline[2]) --two print(polyline[3]) --three print(polyline[4]) --bs
注意:表的构建元素没有限制,可以使用字符串,或是数字,或是表达式。而且可以在构建完成后,随意增加删除table内的元素。
function my_api(x) return x end w = {x=0,y=0, label="console"} x = {my_api(0),my_api(1), my_api(2)} print(w[1]) -->nil w[1] ="another field" -->create new elem x.f = w print(w["x"]) --> 0 print(w[1]) --> another field print(x.f[1]) --> another field w.x = nil -- removefield "x"
table的定义方式很灵活。
另外,利用构造函数嵌套,可以构造复杂的table变量,如:
polyline ={color="blue", thickness=2, npoints=4, {x=0, y=0}, {x=-20, y=0}, {x=-10, y=1}, {x=0, y=1} } print(polyline[2].x) --> -20
练习示例:
<span style="color:#362e2b;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;">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]) --> --- </span></span>
算术运算符:
lua的算术运算符,包括 + - * \ ^(加减乘除幂)等。与其他语言一样,不再赘述。
关系运算符:
< > <= >= == ~=(不等于)
这些运算符返回结果false或是true。对于 == 和 ~=,如果两个比较项是不同的类型,则认为两者不相等。注意:nil只和自己相等。当lua通过引用比较userdata、table、function类型的变量时,只有当引用为同一对象时才相等。即便两个比较项内部的数值一样,也不相等。如:
a = {} a.x = 1; a.y = 0 b = {} b.x = 1; b.y = 0 c =a print(a==c) --true print(a==b) --false
Lua 比较数字按传统的数字大小进行,比较字符串按字母的顺序进行,但是字母顺序依赖于本地环境。
当比较不同类型的值的时候要特别注意:
print("0" == 0) -- false print(2 < 15) -- true print("2" < "15") -- false (alphabetical order!)为了避免不一致的结果,混合比较数字和字符串,Lua 会报错,比如:2 < "15"
and or not
and和or代表与和或的意思,and的优先级比or高。需要注意的一点是,and 和 or 的运算结果不是 true 和 false,而是和它的两个操作数相关。如:
b = 10 print(a and b) -- 如果 a 为 false,则返回 a,否则返回 b 结果为nil print(a or b ) -- 如果 a 为 true,则返回 a,否则返回 b 结果为10这一点与其他语言不同,需要注意。
利用以上这点,可以很方便的达到某些目的。比如:如果x为false或nil,则给x赋初值为x:
x = x or v
not相当于C语言中的取反操作,这个运算符的返回值只有两种,false或是true。
print(not nil) --> true print(not false) --> true print(not 0) --> false print(not not nil) --> false
主要为'..',前面介绍过,主要用来连接两个字符串。
优先级:
^ not - (unary) * / + - .. < > <= >= ~= == and or