一、Lua table(表)
- 特点:
- table是Lua的一种数据结构,可以用来创建不同的数据类型,如:数组(索引默认从1开始的简单的线性表),字典等。
- table使用关联型数组,可以使用任何类型的值作为数组的索引,nil除外。
- 大小不固定。
- table(表)的构造
- 构造器是创建和初始化表的表达式。最简单的构造函数是{},创建一个空表。
- 示例:
- t1 = {} --创建了一个空表,变量t1指向了这个表。
- t1[1] = 'hello'
- t1['two'] = 'lua' --索引可以是任何类型的值。
- t2 = t1 --变量t2指向t1所指向的表。
- t2['two'] = 'world' --通过变量t2修改索引two的值,此时t1['two']的值也为world。
- t1 = nil --释放变量t1,此时变量t2仍能访问表。
- table操作:
- table.concat(tableName, [sep, [start [, end]]])
- 作用:
- 将表tableName的数组部分转变为字符串;
- 可以指定各个数组元素的连接字符sep;
- 可以指定数组部分的起始(start)和截止(end)索引。
- 返回值:字符串。
- 示例1:
- t1 = {'one', 'two', 'three'}
- print(table.concat(t1, '-')) --输出: one-two-three
- print(table.concat(t1, ',', 2, 3)) --输出: two,three
- 示例2:
- t2 = {}
- t2[1] = 'one'
- t2['two'] = 'two'
- t2[3] = 'three'
- t2[4] = 'four'
- print(table.concat(t2)) --输出:返回错误,提示index=2处,值为nil。
- print(table.concat(t2, '-', 1, 1)) --输出:one。
- print(table.concat(t2, '-', 3, 4)) --输出:three-four。
- table.insert(tableName, [index,] value)
- 作用:在表tableName的数组部分的指定位置插入一个元素;index参数可选,默认为数组部分末尾。
- 示例:
- t2 = {}
- t2[1] = 'one'
- t2['two'] = 'two'
- t2[3] = 'three'
- t2[4] = 'four'
- table.insert(t2, 'two') --值two,被插入在索引5的位置上。
- table.remove(tableName [,index])
- 作用:返回表tableName的数组部分,位于index位置的元素,其后的元因素依次前移;pos可选,默认为table的长度,即从最后一个元素删起。
- 示例:
- t2 = {}
- t2[1] = 'one'
- t2['two'] = 'two'
- t2[3] = 'three'
- t2[4] = 'four'
- table.remove(t2) --返回one。
- table.sort(tableName [,comp])
- 作用:对表tableName进行升序排序。
- 降序排序:table.sort(tableName, function(a, b) return a>b end)
- 注意:使用#获取table的长度时,会在索引中断的位置,停止计数。
- 示例:
- t1 = {[1]=1, [2]=2, [5]=5} --#t1等于2
- 特例:
- t1 = {[1]=1, [2]=2, [4]=4} --#t1等于4。难道不应该等于2吗?原因未知???
- table表去重示例:
- tt = {1, 1, 2, 2, 3, 3, 4, 4, 5, 5}
- function table_unique(tt)
- local new_table = {}
- local value_table = {}
- for key, value in pairs(tt) do
- if not value_table[value]
- then
- value_table[value] = value
- new_table[key] = value
- end
- end
- return new_table
- end
二、模块与包
- 模块的作用:
- 模块类似于一个封装库。
- 把一些公用的代码放在一个文件里,以API接口的形式在其他地方调用,有利于代码的重用和降低代码的耦合度。
- 模块的组织:
- 模块以文件为单位;
- 将公用的变量、函数等添加到table中,返回这个table即可。
- 模块就是一个table结构。
- 示例:
- --文件名为mm.lua
- mm = {}
- function mm.minfo()
- print("This is module : mm.")
- end
- return mm
- 说明:定义了一个名为mm的模块,该模块向外提供了一个公用函数mm.info()。
- require函数
- 用法:require("mm") --加载mm模块。
- 示例:
- --test_mm.lua
- require("mm")
- mm.minfo()
- 说明:在测试文件test_mm.lua中,加载mm模块,并执行mm模块中的minfo()函数。
- 加载机制:
- require()函数会从指定路径加载模块(包括 lua文件或c程序库)
- 模块的加载顺序:
- 首先加载lua模块;
- 搜索lua文件的路径存放在全局变量package.path中,lua启动时使用系统变量LUA_PATH初始化它。
- 修改LUA_PATH环境变量示例:export LUA_PATH="~/lua/?.lua;;"。最后的两个分号,表示在原值的基础上追加新值。
- 搜索到目标文件后,使用package.loadfile来加载模块。
- 其次加载同名的c模块;
- 搜索c库文件的路径存放在全局变量package.cpath中,lua启动时使用系统变量LUA_CPATH初始化。
- 搜索到目标文件后,require函数使用package.loadlib加载。
- C包
- 示例:
- c库文件的编写:
- /* filename: module.c */
- #include<lua.h>
- #include <lauxlib.h>
- #include <stdio.h>
- /* 该函数为c语言实现的功能函数 */
- void list_num(void)
- {
- int i;
- for (i = 0; i < 10; i++) {
- printf("%d\n", i);
- }
- }
- /* 该函数为lua的桩函数,调用了c语言实现的功能函数 */
- static int mlist(lua_State *L)
- {
- list_num();
- return 0;
- }
- /* 将包含各个功能函数的桩函数,添加在luaL_Reg数组中;注册模块名为mm */
- int luaopen_mm(lua_State *L)
- {
- luaL_Reg mm[] = {
- {"mlist", mlist}, // "mlist"为在lua中调用的函数名;mlist为c文件的桩函数名。
- {NULL, NULL}
- };
- /* 1. "mm"为lua中需要加载的模块名。
- 2. lua5.0中使用:luaL_openlib(L, "mm", mm, 0);lua5.3中使用:luaL_newlib(L,mm);*/
- luaL_openlib(L, "mm", mm, 0);
- }
- c库的编译:
- gcc -g -Wall -I/home/lfc/git/source/lua-5.3.5/src --shared -fPIC -o mm.so ./module.c
- lua测试文件的编写:
- require("mm") --加载c模块mm
- mm.mlist() --调用c模块mm中实现的函数mlist()