一、Lua table(表)

  1. 特点:
  1. table是Lua的一种数据结构,可以用来创建不同的数据类型,如:数组(索引默认从1开始的简单的线性表),字典等。
  2. table使用关联型数组,可以使用任何类型的值作为数组的索引,nil除外。
  3. 大小不固定。
  1. table(表)的构造
  1. 构造器是创建和初始化表的表达式。最简单的构造函数是{},创建一个空表。
  2. 示例:
  1. t1 = {} --创建了一个空表,变量t1指向了这个表。
  2. t1[1] = 'hello'
  3. t1['two'] = 'lua' --索引可以是任何类型的值。
  4. t2 = t1 --变量t2指向t1所指向的表。
  5. t2['two'] = 'world' --通过变量t2修改索引two的值,此时t1['two']的值也为world。
  6. t1 = nil --释放变量t1,此时变量t2仍能访问表。
  1. table操作:
  1. table.concat(tableName, [sep, [start [, end]]])
  1. 作用:
  1. 将表tableName的数组部分转变为字符串;
  2. 可以指定各个数组元素的连接字符sep;
  3. 可以指定数组部分的起始(start)和截止(end)索引。
  1. 返回值:字符串。
  2. 示例1:
  1. t1 = {'one', 'two', 'three'}
  2. print(table.concat(t1, '-'))  --输出: one-two-three
  3. print(table.concat(t1, ',', 2, 3))  --输出: two,three
  1. 示例2:
  1. t2 = {}
  2. t2[1] = 'one'
  3. t2['two'] = 'two'
  4. t2[3] = 'three'
  5. t2[4] = 'four'
  6. print(table.concat(t2)) --输出:返回错误,提示index=2处,值为nil。
  7. print(table.concat(t2, '-', 1, 1)) --输出:one。
  8. print(table.concat(t2, '-', 3, 4)) --输出:three-four。
  1. table.insert(tableName, [index,] value)
  1. 作用:在表tableName的数组部分的指定位置插入一个元素;index参数可选,默认为数组部分末尾。
  2. 示例:
  1. t2 = {}
  2. t2[1] = 'one'
  3. t2['two'] = 'two'
  4. t2[3] = 'three'
  5. t2[4] = 'four'
  6. table.insert(t2, 'two') --值two,被插入在索引5的位置上。
  1. table.remove(tableName [,index])
  1. 作用:返回表tableName的数组部分,位于index位置的元素,其后的元因素依次前移;pos可选,默认为table的长度,即从最后一个元素删起。
  2. 示例:
  1. t2 = {}
  2. t2[1] = 'one'
  3. t2['two'] = 'two'
  4. t2[3] = 'three'
  5. t2[4] = 'four'
  6. table.remove(t2) --返回one。
  1. table.sort(tableName [,comp])
  1. 作用:对表tableName进行升序排序。
  2. 降序排序:table.sort(tableName, function(a, b) return a>b end)
  1. 注意:使用#获取table的长度时,会在索引中断的位置,停止计数。
  1. 示例:
  1. t1 = {[1]=1, [2]=2, [5]=5} --#t1等于2
  1. 特例:
  1. t1 = {[1]=1, [2]=2, [4]=4} --#t1等于4。难道不应该等于2吗?原因未知???
  1. table表去重示例:
  1. tt = {1, 1, 2, 2, 3, 3, 4, 4, 5, 5}
  2. function table_unique(tt)
  1. local new_table = {}
  2. local value_table = {}
  3. for key, value in pairs(tt) do
  1. if not value_table[value]
  2. then
  1. value_table[value] = value
  2. new_table[key] = value
  1. end
  1. end
  2. return new_table
  1. end

二、模块与包

  1. 模块的作用:
  1. 模块类似于一个封装库。
  2. 把一些公用的代码放在一个文件里,以API接口的形式在其他地方调用,有利于代码的重用和降低代码的耦合度。
  1. 模块的组织:
  1. 模块以文件为单位;
  2. 将公用的变量、函数等添加到table中,返回这个table即可。
  3. 模块就是一个table结构。
  4. 示例:
  1. --文件名为mm.lua
  2. mm = {}
  3. function mm.minfo()
  1. print("This is module : mm.")
  1. end
  2. return mm
  3. 说明:定义了一个名为mm的模块,该模块向外提供了一个公用函数mm.info()。
  1. require函数
  1. 用法:require("mm") --加载mm模块。
  2. 示例:
  1. --test_mm.lua
  2. require("mm")
  3. mm.minfo()
  4. 说明:在测试文件test_mm.lua中,加载mm模块,并执行mm模块中的minfo()函数。
  1. 加载机制:
  1. require()函数会从指定路径加载模块(包括 lua文件或c程序库)
  2. 模块的加载顺序:
  1. 首先加载lua模块;
  1. 搜索lua文件的路径存放在全局变量package.path中,lua启动时使用系统变量LUA_PATH初始化它。
  1. 修改LUA_PATH环境变量示例:export LUA_PATH="~/lua/?.lua;;"。最后的两个分号,表示在原值的基础上追加新值。
  1. 搜索到目标文件后,使用package.loadfile来加载模块。
  1. 其次加载同名的c模块;
  1. 搜索c库文件的路径存放在全局变量package.cpath中,lua启动时使用系统变量LUA_CPATH初始化。
  2. 搜索到目标文件后,require函数使用package.loadlib加载。
  1. C包
  1. 示例:
  1. 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); 
  • }
  1. c库的编译:
  • gcc -g -Wall -I/home/lfc/git/source/lua-5.3.5/src --shared -fPIC -o mm.so ./module.c
  1. lua测试文件的编写:
  • require("mm") --加载c模块mm
  • mm.mlist() --调用c模块mm中实现的函数mlist()