Lua 101 - 基本语法
最近在重构我司项目,删掉那些又臭又长的代码,用精简的函数实现同样的功能心里巨爽,而且也没了历史包袱。一些新特性用着很嗨皮。不过也遇到了一些坑,其中有一段就是要调用 Lua 函数。然而 Lua 从未接触过。先瞅瞅基本语法。
Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua 特性
- 轻量级: 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。
- 可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
- 支持面向过程(procedure-oriented)编程和函数式编程(functional programming)
- 自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象
- 语言内置模式匹配;闭包(closure);函数也可以看做一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持
- 通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等。
配置环境
使用 Homebrew 安装 Lua 异常简单,只需要一行命令。
1 | brew install lua |
交互式编程
Lua 提供了交互式编程模式。我们可以在命令行中输入程序并立即查看效果。
Lua 交互式编程模式可以通过命令 lua -i
或 lua
来启用:
1 | $ lua |
脚本式编程
我们可以将 Lua
程序代码保持到一个以 lua
结尾的文件,并执行,该模式称为脚本式编程,如我们将如下代码存储在名为 hello.lua
的脚本文件中:
1 | print("Hello World!") |
使用 lua
执行以上脚本,输出结果为
1 | $ lua hello.lua |
基本语法
使用 Lua 输出”Hello World!”
1 | > print("Hello World!") |
注释
1 | -- 两个减号为单行注释 |
标识符
Lua 表示符用于定义一个变量,函数获取其他用户定义的项。标示符以一个字母 A 到 Z 或 a 到 z 或下划线 _ 开头后加上0个或多个字母,下划线,数字(0到9)。
变量
数据类型
数据类型 | 描述 |
---|---|
nil | 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。 |
boolean | 包含两个值:false和true。 |
number | 表示双精度类型的实浮点数 |
string | 字符串由一对双引号或单引号来表示 |
function | 由 C 或 Lua 编写的函数 |
userdata | 表示任意存储在变量中的C数据结构 |
thread | 表示执行的独立线路,用于执行协同程序 |
table | Lua 中的表(table)其实是一个”关联数组”(associative arrays),数组的索引可以是数字或者是字符串。在 Lua 里,table 的创建是通过”构造表达式”来完成,最简单构造表达式是{},用来创建一个空表。 |
所谓Table其实就是一个Key Value的数据结构,它很像Javascript中的Object,或是PHP中的数组,在别的语言里叫Dict或Map,Table长成这个样子:
1 | brikerMan = {name="BrikerMan", age=18} |
Lua 的数字只有 double 型,64bits,Lua 允许按照以下方式为数字赋值。
1 | num = 1024 |
字符串你可以用单引号,也可以用双引号,还支持C类型的转义,比如: ‘\a’ (响铃), ‘\b’ (退格), ‘\f’ (表单), ‘\n’ (换行), ‘\r’ (回车), ‘\t’ (横向制表), ‘\v’ (纵向制表), ‘\‘ (反斜杠), ‘\”‘ (双引号), 以及 ‘\” (单引号)
下面的四种方式定义了完全相同的字符串(其中的两个中括号可以用于定义有换行的字符串)
1 | a = 'alo\n123"' |
C语言中的NULL在Lua中是nil,比如你访问一个没有声明过的变量,就是nil,比如下面的n的值就是nil
1 | > print(n) |
布尔类型只有nil和false是 false,数字0,’’空字符串(’\0’)都是true。
默认情况下,变量总是认为是全局的,那怕是语句块或是函数里。变量前加local关键字的是局部变量。
1 | > print(n) |
如果你想删除一个全局变量,只需要将变量赋值为nil。
控制语句
while循环
1 | sum = 0 |
if else 分支
1 | age = 10 |
- “~=” 是不等于,而不是 !=
- io 库的分别从 stdin 和 stdout 读写的
read
和write
函数 - 字符串的拼接操作符”..”
- 条件表达式中的与或非为分是:and, or, not关键字
for 循环
从 1 加到 100
1 | sum = 0 |
从 1 到 100 的奇数和
1 | sum = 0 |
从100到1的偶数和
1 | sum = 0 |
until 循环
1 | sum = 2 |
函数
Lua 函数和 javascript 很像
递归
1 | function fib(n) |
1 | --[[ 函数返回两个值的最大值 --]] |
Lua 中我们可以将函数作为参数传递给函数,如下实例:
1 | myprint = function(param) |
函数的返回值
和Go语言一样,可以一条语句上赋多个值,如
1 | name, age, bWoman = "BrikerMan", 18, false, "BrikerMan@gmail.com" |
上面的代码中,因为只有3个变量,所以第四个值被丢弃。
函数也可以返回多个值:
1 | function getUserInfo(id) |
注意:上面的示例中,因为没有传 id ,所以函数中的 id 输出为 nil,因为没有返回 bWoman,所以 bWoman 也是nil。