数据结构
数组
lua
语言中,简单地使用整数来索引表即可实现数组。因此,数组的大小不用非得是固定的,而是可以按需增长的。
1 2 3 4 5 |
local a = {} --新数组 for i = 1, 1000 do a[i] = 0 end |
长度运算符
#
可以用来计算数组大小。
1 |
pirnt(#a) |
lua
语言中,有两种方式来表示矩阵。
- 使用一个不规则数组,即数组的数组。
- 将两个索引合并为一个。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
//1. local mt = {} for i = 1, N do local row = {} mt[i] = row for j = 1, M do row[j] = 0 end end //2. local mt = {} for i = 1, N do local aux = (i - 1) * M for j = 1, M do mt[aux + j] = 0 end end |
由于在有效元素之间存在空值,因此不能对稀疏矩阵使用长度运算符
#
。可以使用pairs
来只遍历非nil
元素。
链表
由于表是动态对象,所以在
lua
语言中可以很容易地实现链表。
可以把每个节点用一个表来表示,链表则为一个包含指向其他表的引用的简单表字段。
1 2 3 4 5 6 7 8 9 10 11 12 |
//根节点 list = nil //表头插入一个元素 list = {next = list, value = v} //遍历 local l = list while l do visit l.value l = l.next end |
队列和双端队列
在
lua
语言中实现队列的一种简单方法是使用table
标准库中的函数insert
和remove
。
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 |
function listNew () return {first = 0, last = -1} end function pushFirst(list,value) local first = list.first - 1 list.first = first list[first] = value end function pushLast(list,value) local last = list.last + 1 list.last = last list[last] = value end function popFirst(list) local first = list.first if first > list.last then error("list is empty") end local value = list[first] list[first] = nil list.first = first + 1 return value end function popLast(list) local last = list.last if list.first > last then error("list is empty") end local value = list[last] list[last] = nil list.last = last - 1 return value end |
反向表
很少在
lua
中进行搜索操作,而是使用索引表或反向表的数据结构。
1 2 3 4 5 6 7 8 9 |
days = {"Sunday","Monday","Tuesday","Wednessday","Thursday","Friday","Saturday"} //反向表 revDays = {["Sunday"] = 1,["Monday"] = 2, ["Tuesday"] = 3,["Wednessday"] = 4, ["Thursday"] = 5,["Friday"] = 6,["Saturday"] = 7} x = "Friday" print(revDays[x]) --6 |
集合与包
在
lua
语言中,还可以使用一种高效且简单的方式来表示这类集合,即将集合元素作为索引放入表中。
1 2 3 4 5 6 7 8 9 10 |
reserved = { ["while"] = true, ["if"] = true, ["else"] = true, ["do"] = true, } for w in string.gmatch(s. "[%a_][%w_]") do if not reserved[w] then do something with 'w' end end |
包也被称为多重集合,与普通集合的不同之处在于其中的元素可以出现多次。
在lua
语言中,包的简单表示类似于此前集合的表示,只不过其中的每一个键都有对应的计数器。
1 2 3 4 5 6 7 8 |
function insert(bag, element) bag[element] = (bag[element] or 0) + 1 end function remove(bag, element) local count = bag[element] bag[element] = (count and count > 1) and count - 1 or nil end |
字符缓冲区
在
lua
语言中,可以把一个表当作字符串缓冲区,其关键是使用函数table.concat
。这个函数将会指定猎列表中的所有字符串连接起来并返回连接后的结果。
concat
还有第二个可选参数,用于指定插在字符串间的分隔符。
图形
使用对象来表示节点,将边表示为节点之间的引用。
数据文件和序列号
数据文件
对于文件格式来说,表构造器提供了一种有趣的替代方式:将数据文件写成
lua
代码,当这些代码运行时,程序也就把数据重建了。
序列化
将某些数据转换为字节流或字符流,以便将其存储到文件中或者通过网络传输。
编译执行以及错误
编译
dofile
,时运行lua
代码段的主要方式之一。实质上,函数dofile
是一个辅助函数,函数loadfile
才是完成了真正的核心工作。
与函数dofile
类似,函数loadfile
也是从文件中加载lua
代码段,但它不会运行代码,而只是编译代码,然后,将编译后的代码段作为一个函数返回。
此外,与函数dofile
不同,函数loadfile
只返回错误码而不抛出异常。在发数错误的情况下,函数
loadfile
会返回nil
以及错误信息,以允许我们按自定义的方式来处理错误。
此外,如果需要多次运行同一个文件,那么只需调用一次loadfile
函数后再多次调用它的返回结果即可。
由于只编译一次文件,因此这种方式的开销要比多次调用函数dofile
小得多。函数
load
与函数loadfile
类似,不同之处在于该函数从一个字符串或函数中读取代码段,而不是从文件中读取。(load
总是在全局环境中编译代码段)
错误
函数
assert
检查它的第一个参数是否为真,如果该参数为真则返回该参数,如果该参数为假则引发一个错误。函数
pcall
会以一种保护模式来调用它的第一个参数,以便捕获该函数执行中的错误。无论是否有错误发生,函数pcall
都不会引发错误。如果没有错误发生,那么pcall
返回true
以及被调用函数的所有返回值;否则返回false
和错误信息。
模块和包
从用户观点来看,一个模块就是一些代码,这些代码可以通过函数
require
加载,然后创建和返回一个表。
1 2 3 4 5 6 7 |
local m = require "math" print(m.sin(3.14)) //另外的形式 local test = require('math') local modname = 'math' local test = require(modname) |
关于
require
:首先,该函数在表
package.loaded
中检查模块是否已被加载。如果模块已经被加载,函数require
就返回相应的值。因此,一旦一个模块被加载过,后续对所有模块的require
调用都将返回同一个值,而不会再运行任何代码。如果模块尚未加载,那么函数
require
则搜索具有指定模块名的lua
文件。如果该函数找到了相应的文件,那么就用函数loadfile
将其加载,结果是一个我们称之为加载器的函数。如果该函数找不到对应的文件,那么它就会搜索C标准库。如果找到了一个C标准库,则使用底层函数package.loadlib
进行加载,这个底层函数会查找名为luaopen_modname
的函数。不管模块是在
lua
文件还是C标准库中找到的,函数require
此时都具有了用于加载它的加载函数。而为了最终加载模块,函数require
带着两个参数调用加载函数(模块名和加载函数所在文件的名称)。如果加载函数有返回值,那么函数require
会返回这个值,然后将其保存在package.loaded
中,以便于将来在加载同一模块时返回相同的值。
迭代器和泛型循环
迭代器是一种可以让我们遍历一个集合中所有元素的代码结构。在
lua
语言中,通常使用函数表示迭代器:每一次调用函数时,函数会返回集合中的“下一个”元素。
1 2 3 4 |
function values(t) local i = 0 return function() i = i + 1; return t[i] end end |
1 2 3 |
for var-list in exp-list do body end |
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ C++_调用 Lua函数:错误处理10/11
- ♥ lua学习记述一08/11
- ♥ Lua程序设计:二11/07
- ♥ Lua_基础 类型&&值09/26
- ♥ Lua_调用 C++函数:传递普通参数10/01
- ♥ C++_调用 Lua内容:全局表 获取&&设置10/09