Lua学习笔记
学习资料地址:http://www.runoob.com/lua/lua-tutorial.html
安装环境
在Windows环境下,使用SciTE来运行Lua程序。
项目GitHub地址:https://github.com/rjpcomputing/luaforwindows/releases
上面的官方下载无法保证下载速度,我使用的是菜鸟教程分流的下载地址:http://static.runoob.com/download/LuaForWindows_v5.1.4-46.exe
开始编程
和Python一样,Lua也有交互式的编程方式。在命令行中输入lua
或者lua -i
启用。
同时也可以使用脚本式编程,就是将代码存放在一个lua文件中,命令行执行lua xxx.lua
即可。
需要注意的是,交互式编程状态下不能使用lua命令,会出现下面的错误,这一点我也是犯了好多次:
|
|
教程中没有提到怎样退出lua环境 。os.exit()
退出。
基础知识
注释
单行注释:
|
多行注释:
|
|
输入输出
|
|
数据类型与变量
变量
概述
Lua有三种变量类型:全局变量,局部变量和表中的域。默认情况下,变量都是全局变量,函数里面没有做特殊声明的变量也都是全局变量。全局变量不需要声明,直接赋值即创建了这个全局变量。如果访问了一个没有创建的变量,会返回一个nil。同样,如果想要删除一个变量,直接赋值nil即可。
|
|
如果想要一个局部变量,需要使用local
显式声明:
|
|
赋值语句
赋值时改变一个变量的值和改变表域的最基本方法。同大多数编程语言类似,Lua使用从右到左的赋值方式。除此之外,还能够实现多个变量同时赋值:
|
|
上面的语句在功能上,等同于:
|
|
在对多个变量进行赋值时,Lua采用的计算方式是先计算右侧的值,再进行赋值的操作。所以再Lua中,实现两个变量值的交换只需要一行代码:
|
|
除此之外,当变量的个数和数值的个数不一致时,Lua会遵循这个策略:
- 当 变量个数 > 值的个数 时,右侧没有指定值的变量赋值为nil
- 当 变量个数 < 值的个数 时,右侧多余的值会被忽略掉。
所以比较容易出现的错误是,在对多个变量进行相同赋值时:
|
|
多赋值语句,除了用在上面的值交换的过程中之外,还常用于记录函数的多个返回值。Lua中,函数可以有多个返回值。如果想要将函数f()
的两个返回值存放到全局变量a
和b
中去,可以使用下面的语句:
|
|
上面的语句,实现了将函数的第一个返回值给a,第二个给b。
虽然Lua定义全局变量比较方便,但是应当尽可能地使用局部变量。因为局部变量的访问时间要比全局变量更快,同时也避免了变量命名的冲突。
数据类型
概述
以下是常见的集中变量类型。
数据类型 | 描述 |
---|---|
nil | 无效值,没有赋值的变量都会返回nil |
boolean | 布尔 |
number | 双精度浮点型 |
string | 字符串,用单引号或双引号括起来 |
function | 由C或Lua编写的函数 |
userdata | *表示任意存储在变量中的C数据结构 |
thread | *表示执行的独立线路,用于执行协同程序 |
table | *Lua 中的表(table)其实是一个”关联数组”(associative arrays),数组的索引可以是数字或者是字符串。在 Lua 里,table 的创建是通过”构造表达式”来完成,最简单构造表达式是{},用来创建一个空表。 |
可以使用type函数测试给定变量或常量的类型:
|
|
nil(空)
nil类型表示没有任何有效值,只有一个值,nil。打印一个没有赋值的变量会输出nil。对于全局变量和table变量,nil可以起到删除的作用。全局变量或者 table表里的变量赋一个nil值,等同于将他们删除。
nil在比较时,需要使用双引号括起来。
|
|
boolean(布尔)
Lua的布尔值与其他语言有一个显著的区别,它将false和nil看作假,其他的值,包括0,都为真。长时间使用其他编程语言的人可能会很难反应过来。
除此之外,在进行逻辑判断时也和其他语言有很多不同。进行或、与运算时,如0 or false的值就为0,10 and 20返回值就为20。
number(数字)
Lua默认只有一种number类型,即双精度浮点型。
string(字符串)
字符串由一对单引号或者双引号括起来。
|
|
也可以使用两个方括号[[]]
来表示一块字符串。
|
|
运行时,Lua会自动在string和number之间进行格式转换。
|
|
在一个数字后写..
时应该加空格,防止被错误解释。
可以使用两点..
来连接两个字符串:
|
|
可以使用#
来计算字符串的长度:
|
|
table(表)
表是一个关联数组,可以创建空表,也可以在创建的时候初始化:
|
|
数组的索引可以是数字或者字符串:
|
|
需要注意的是,与其他语言不同,Lua默认初始索引是从1开始的!!!!
|
|
程序的运行结果是:
|
|
对table的索引除了使用国际惯例[]
之外,还可以使用.
进行操作。需要注意的是,使用点号来索引时,索引的关键字不能为数字。
|
|
最后,table不会固定长度,没有被赋值的部分,返回值都为nil。如果直接使用for循环进行遍历,循环会在遇到nil值时终止,可能无法实现对整个数组的遍历。(如果其中有空值的话)具体的解决方法在table部分给出。
function(函数)
在Lua中,函数被看作第一类值,函数可以存在变量里。
|
|
可以以匿名函数的方式,通过参数传递。函数之所以有名字,就是为了方便进行调用。而只使用一次的函数,则可以不起名字,也就是匿名函数。
|
|
循环与流程控制
循环语句
while循环
条件为true
时会重复执行循环体的语句。
|
|
for循环
for循环是可以制定循环体执行次数的循环语句。Lua中的for循环需要相当地注意,分为两大类:
数值for循环
|
|
exp1
为初值,exp2
为终值,exp3
为步长。若exp3
不指定,值默认为1。需要注意的是,表达式中三个参数的值都会在循环开始前一次性求值,以后不再进行求值。
参数
泛型for循环
泛型for循环,通过一个迭代器来遍历所有的值,与C++类似。
|
|
其中,i
是索引,v
是索引对应的元素的值,ipairs是Lua提供的一个迭代器函数,用来迭代数组。它的参数a
就是数组名。下面是一个对数组进行泛型for循环输出的例子。
|
|
repeat … until循环
即do … while,重复执行循环体到循环条件为真时。
|
|
break语句
Lua支持break语句。
流程控制
if语句的格式:
|
|
if … else 语句格式:
|
|
需要注意的是,Lua中0也为真值,只有false和nil为假。
函数
定义
Lua中,函数的标准格式如下:
|
|
optional_function_scope
这个参数是可选的,表示函数是全局的还是局部的。默认为全局函数,设置为局部函数需要加关键字localfunction_name
函数名argument
函数的参数,用逗号隔开,也可以不带参数function_body
函数体result_params_comma_separated
返回值,可以有多个。
函数可以作为参数。
多返回值
Lua中的函数可以有多个返回值。
|
|
可变参数
Lua中的函数可以接受可变数目的参数,用三点…
来代表多个参数。计算平均值的程序,可以这样写:
|
|
在新的版本里,#
不能用于返回数组元素的个数了,而是需要使用:
|
|
运算符
算数运算符
常用的算术运算符与其他语言类似。需要注意的是,Lua里没有整数,所以如果想要取整操作,必须要进行取整操作:
|
|
需要注意的是,这里的取整仍然是向上取整。也就是说,无论小数部分有多小,取整的结果都是要比原数的整数部分大1。
除此之外,常用的操作应该还有数据精度的控制:
|
|
关系运算符
符号 | 含义 |
---|---|
== | 等于 |
~= | 不等 |
>= | 大于等于 |
<= | 小于等于 |
> | 大于 |
< | 小于 |
逻辑运算符
符号 | 含义 |
---|---|
and | 与 |
or | 或 |
not | 非 |
其他运算符
符号 | 含义 |
---|---|
.. | 连结两个字符串 |
# | 返回字符串或表的长度 |
#
运算符,获取的表的长度实际上获取的是表最大的索引值。
|
|