(二)Lua基础语法
作为有一定经验的猿,一些比较简单明了的基础语法,这里就不一一重述了,只选择性的
说一下Lua特有的语法,或者常用的和容易混淆的语法。
Lua是动态类型语言,变量不需要类型定义。Lua中有8个基本类型分别为nil,boolean,
number,string,userdata,function,thread和table。函数type可以测试给定变量或者值的类型。
1、语句
结果:
注: Lua是类C的,所以,他是区分大小写的。Lua脚本语句的结尾,分号是可选的。
2、注释
3、变量
Lua的数字只有double型,64bits,字符串可以用单引号,也可以用双引号,还支持C类型的转义。
C语言中的NULL在Lua中是nil,布尔类型只有nil和false是 false,数字0,‘’空字符串(’\0’)都是true!
另外,需要注意的是:lua中的变量如果没有特殊说明,全是全局变量,哪怕是语句块或是函数里。
变量前加local关键字的是局部变量。将全局变量置为nil,意思是删除这个变量。
优先使用局部变量可以:
1.避免命名冲突
2.访问速度比全局变量更快
对于全局变量,Lua也是用Table来管理全局变量的,Lua把这些全局变量放在了一个叫“_G”的Table里。
我们可以用如下的方式来访问一个全局变量(假设我们这个全局变量名叫globalVar):
4、表达式&运算符
1) 运行时,Lua会自动在string和number之间自动进行类型转换。
2) a and b -- 如果a为false,则返回a,否则返回b
a or b -- 如果a为true,则返回a,否则返回b
3) 一个很实用的技巧: 如果x为false或者nil则给x赋初始值v
x = x or v <==> if not x then x = v end
4) Lua中的三元运算符 (a and b) or c
5) 连接运算符 .. 两个点,如果操作数为数字,Lua将数字转成字符串
6) break语句用来退出当前循环(for,repeat,while)。在循环外部不可以使用。
5、控制语句
上面可以看到: “~=”是不等于,而不是!=, 字符串的拼接操作符“..”, 条件表达式中的与或非为分是:
and, or, not关键字。同时注意:Lua没有++或是+=这样的操作。
6、函数(Lua的函数和Javascript的很像)
1). 递归
执行结果:
2). 闭包
在Lua中,所有的变量都是“指针”。所有的变量都是从堆里分配出来的,不像C与C++,局部变量是从
栈里分配,一旦函数退出,所有局部变量都要被释放。Lua中的所有变量都是从堆里申请的。对象的释放是
自动进行的,只有这个对象的引用计数为0了才会被释放掉。
3).函数的返回值
Lua一条语句上赋多个值,如: name, age, bGay = "haoel", 37, false, "haoel@hotmail.com"
上面的代码中,因为只有3个变量,所以第四个值被丢弃。
函数也可以返回多个值:
注意:上面的示例中,因为没有传id,所以函数中的id输出为nil,因为没有返回bGay,所以bGay也是nil。
4).局部函数
函数前面加上local就是局部函数
5). 尾调函数
当函数的最后返回结果是调用另一个函数,称之为尾调函数。Lua的在调用尾调函数时,先是弹出当前
函数的栈空间,然后再调用尾调函数,从而降低了函数层层调动过程中的栈消耗,非常适用于函数递归调用。
7、Table
所谓Table其实就是一个Key Value的数据结构,它很像Javascript中的Object,在别的语言里叫Dict或Map,
Table长成这个样子:
执行结果:
注意细节:
执行结果:
从上可以看出, 表中的元素都是由key-value组成。如果没有指定key,那就默认以1开始的整数做key,
如上4个{x,y}。如果指定了名称,则以string类型为key,如color, thickness, npoints。
其实,表的key还可以为table, function,file, boolean任意类型。value可以为任何Lua类型。
Person = {["name"] = "Peter", ["age"] = 28} -- 等价于
Person = {name = "Peter", age = 28}
{x=0, y=0} <--> {["x"]=0, ["y"]=0}
{"red", "green", "blue"} <--> {[1]="red", [2]="green", [3]="blue"}
数组相关:
在Lua中习惯上数组下标从1开始,Lua标准库与此习惯保持一致,否则无法直接使用标准库的函数。
习题小练
1、构造一个反向表,交换key-value的位置
2、 pairs(泛型遍历集合和数组)与ipairs(遍历出带索引的数组)的区别
注: print(array[4]) --nil
3、创建一个n行m列矩阵
执行结果:
4、以字母顺序打印出这些函数名