Lua入门
1 注释
行注释:--
;
块注释:--[[注释内容]]
,推荐用--[=[注释内容]=]
,其中=
的个数前后一致。
2 数据类型
基础类型有8种:
nil
未初始化的变量默认为nil
;删除一个全局变量b=nil
boolean
只有false和nil视为false
,其他值都为true
number
默认只有一种double
类型string
一对单引号或双引号;表示一块字符串[[]]
;字符串连接符..
;长度操作符#
;计算时数字与字符串自动转换table
数组+哈希表,一种动态分配的对象,程序仅持有一个对他们的引用;注意a['x']
和a.x
等价,但容易出错;索引的起始值为1;包含空隙Hole的数组,#会认为nil就是结尾标记,这时应该用table.maxn()
,Lua5.2之后该方法不存在function
看做“第一类值”,可以赋给变量;允许以匿名函数的形式通过参数传递thread
在Lua里主要是协同程序,跟线程差不多,拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西;线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起suspend
时才会暂停。userdata
用户自定义数据,可以将C/C++的任意数据类型(通常是 struct 和 指针)存储到 Lua 变量中调用。
注意:对于 table/userdata/function
,只做引用的比较,a~=b
。
3 变量
- Lua中的变量全是全局变量,哪怕是语句块或是函数里,除非用
local
显式声明; - 局部变量的作用域为从声明位置开始到所在语句块结束,缩短变量的作用域能提高代码的可读性,块作用域
do-end
; - 尽可能使用局部变量:
local foo = foo
,避免命名冲突,同时加速在当前作用域对 foo 的访问; - 对 table 的索引使用方括号
[]
,.
操作符是索引为字符串类型时的一种简化写法。
4 表达式
- 先计算右边所有的值然后再执行赋值操作:
x, y = y, x
; - 变量和值的个数不一致时:
a, b = 0 --b=nil
,a, b = 0, 1, 2 --2 is ignored
; - and和or都是短路求值,只在需要时才评估第二个数,
x = x or v
,max = (x>y) and x or y
;
5 迭代器
迭代器获取三个值:迭代函数、状态常量、控制变量;
无状态迭代器,避免创建闭包花费额外的代价;多状态迭代器,对应“多个状态信息”,将所有的状态封装到table内,作为迭代函数的唯一参数;
不同类型的迭代器:文件中的每行 io.lines
,table元素 pairs
(遍历所有的值,包括nil),数组元素 ipairs
(不能返回nil),字符串元素 string.gmatch
。
6 函数
- 函数的两个用途:作为调用语句,完成指定任务;
- 多返回值、可变参数
(fmt, …)
、具名实参; - 支持“尾调用消除”:递归不会造成栈溢出;编写“状态机”;
- 判断“尾调用”:一个函数在调用完另一个函数后,是否无需做其他事情;完成一条 goto 语句到另一个函数,非传统的函数调用;
return <func>(<args>)
。 - 冒号操作符:面向对象式的调用,
o.foo(o, x)
等价于o:foo(x)
;所有Lua标准程序库的函数都是用C语言写的,但对于Lua程序员来说是透明的。