Lua 语言Lua 具有现代脚本语言中的很多便利:作用域,控制结构,迭代器,以及一组用来处理字符串、产生及收集数据和执行数学计算操作的标准库。在 Lua 5.0 Reference Manual 中有对 Lua 语言的完整介绍(请参见 )。
在 Lua 中,只有值 具有类型,而变量的类型是动态决定的。Lua 中的基本类型(值)有 8 种: nil,布尔型,数字,字符串,函数,线程,表 以及 用户数据。前 6 种类型基本上是自描述的(例外情况请参见上面的 一节);最后两个需要一点解释。
Lua 表在 Lua 中,表是用来保存所有数据的结构。实际上,表是 Lua 中惟一的 数据结构。我们可以将表作为数组、字典(也称为散列 或联合数组)、树、记录,等等。
与其他编程语言不同,Lua 表的概念不需要是异构的:表可以包含任何类型的组合,也可以包含类数组元素和类字典元素的混合体。另外,任何 Lua 值 —— 包括函数或其他表 —— 都可以用作字典元素的键值。
要对表进行浏览,请启动 Lua 解释器,并输入清单 1 中的黑体显示的代码。
清单 1. 体验 Lua 表1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| $ lua
> -- create an empty table and add some elements
> t1 = {}
> t1[1] = "moustache"
> t1[2] = 3
> t1["brothers"] = true
> -- more commonly, create the table and define elements
> all at once
> t2 = {[1] = "groucho", [3] = "chico", [5] = "harpo"}
> t3 = {[t1[1]] = t2[1], accent = t2[3], horn = t2[5]}
> t4 = {}
> t4[t3] = "the marx brothers"
> t5 = {characters = t2, marks = t3}
> t6 = {["a night at the opera"] = "classic"}
> -- make a reference and a string
> i = t3
> s = "a night at the opera"
> -- indices can be any Lua value
> print(t1[1], t4[t3], t6[s])
moustache the marx brothers classic
> -- the phrase table.string is the same as table["string"]
> print(t3.horn, t3["horn"])
harpo harpo
> -- indices can also be "multi-dimensional"
> print (t5["marks"]["horn"], t5.marks.horn)
harpo harpo
> -- i points to the same table as t3
> = t4
the marx brothers
> -- non-existent indices return nil values
> print(t1[2], t2[2], t5.films)
nil nil nil
> -- even a function can be a key
> t = {}
> function t.add(i,j)
>> return(i+j)
>> end
> print(t.add(1,2))
3
> print(t['add'](1,2))
3
> -- and another variation of a function as a key
> t = {}
> function v(x)
>> print(x)
>> end
> t[v] = "The Big Store"
> for key,value in t do key(value) end
The Big Store
|
正如我们可能期望的一样,Lua 还提供了很多迭代器函数来对表进行处理。全局变量 table 提供了这些函数(是的,Lua 包就是表)。有些函数,例如 table.foreachi(),会期望一个从 1(数字 1)开始的连续整数范围:
1
2
3
| > table.foreachi(t1, print)
1 moustache
2 3
|
另外一些函数,例如 table.foreach(),会对整个表进行迭代:
1
2
3
4
5
6
7
8
| > table.foreach(t2,print)
1 groucho
3 chico
5 harpo
> table.foreach(t1,print)
1 moustache
2 3
brothers true
|
尽管有些迭代器对整数索引进行了优化,但是所有迭代器都只简单地处理 (key, value) 对。
现在我们可以创建一个表 t,其元素是 {2, 4, 6, language="Lua", version="5", 8, 10, 12, web="www.lua.org"},然后运行 table.foreach(t, print) 和 table.foreachi(t, print)。
用户数据由于 Lua 是为了嵌入到使用另外一种语言(例如 C 或 C++)编写的宿主应用程序中,并与宿主应用程序协同工作,因此数据可以在 C 环境和 Lua 之间进行共享。正如 Lua 5.0 Reference Manual 所说,userdata 类型允许我们在 Lua 变量中保存任意的 C 数据。我们可以认为 userdata 就是一个字节数组 —— 字节可以表示指针、结构或宿主应用程序中的文件。
用户数据的内容源自于 C,因此在 Lua 中不能对其进行修改。当然,由于用户数据源自于 C,因此在 Lua 中也没有对用户数据预定义操作。不过我们可以使用另外一种 Lua 机制来创建对 userdata 进行处理的操作,这种机制称为 元表(metatable)。 |