本文目录

  • 碎碎念
  • 一、Lua的集成开发环境
  • 二、Lua常用语法
  • 三、习题小练
  • 参考

碎碎念

  鉴于接下去公司的下一个项目又要写Lua代码了,并且进入公司,也是从学习Lua开始,相比于公司里勤勤勉勉,兢兢业业的同事&大神,自己着实好生懒惰,一不经意间,又在蹉跎岁月,虚度时光.但也深信,在一个牛叉的团队里,早晚自己也能变得比较牛B(装在A与C之间),即使难堪大用,也得让自己尽量向他们看齐,总得想法充实并努力跟上吧.同时,回想起当时刚学Lua时的茫然,也希望这文对公司新人在加速并有效学习Lua方面有所帮助.另外,对于没有编程天赋的程序猿,年纪大了,记性也不好了,什么都要记下来才比较放心,也为方便以后用到时查找复习吧.诚然,相比于公司里的大神,这点水准,实属于班门弄斧,但这已无关紧要,能把自己会的一点知识分享出来,帮助别人在学习过程中少走弯路,甚至起到抛砖引玉,引发技术探讨,对自己本身也是个促进和巩固的过程.于是乎,废话不多说,想来无事就从复习Lua开始吧.

  至于Lua怎么好,这些就不废话多说了,个人简单粗暴的认为,只要是实用的,高效的,公司项目需要的,它就是好的,值得学习的.这里也只是简明的概要一下自己在工作中,学习并简单使用的历程,主要是个人感觉比较重要的一些知识要点的小结.因为长篇大论书籍对初学者来说,的确也很容易挫伤自己的学习热情,而简明精华的要点与实践,才是我们共同追求.

  那么正所谓,工欲善其事,必先利其器,磨刀不误砍柴功,有一款好的Lua集成开发环境,对于我们快速并高效地学习Lua肯定大有裨益.只有站在前人的基础上,我们才能走的更高,看得更远.(这里我补充一点,承认有轻微强迫症的人,对于那种有好的集成开发工具不用,而坚持使用纯文本开发的,我不觉得他有多牛叉,而觉得他像是个傻叉.)当然,仅限是个人观点,个人喜好,对事不对人哦.

 

一. Lua的集成开发环境

  由于每个程序猿的技术背景不同,熟悉的开发工具就不太一样,那么请先看这里:  Lua开发相关

    1. Lua for IntelliJ IDEA

  Lua for IntelliJ IDEA  是一款 IDEA 集成开发环境的插件,用来支持对 Lua 编程语言的开发。支持语法高亮、代码重构等基本功能。Lua for IntelliJ IDEA 1.0a40 发布,该版本增加了基本数据类型推断。

  

  相关链接

    * IntelliJ IDEA详情

      * Lua for IntelliJ IDEA 的下载地址

  2. Lua集成开发环境 Decoda

  Decoda 是一个开源的 Lua 集成开发环境和调试器。需要 premake4 项目文件进行构建。

  

  相关链接 

    * Decoda详情

  3. Eclipse的Lua开发插件LDT

  对于熟悉Java开发的程序猿,对Eclipse应该是比较熟悉的,那么在Eclipse上加插件写Lua代码应该是个不错的选择.而LDT (Lua Development Tools) 为 Lua 开发者提供了 Eclipse 开发 Lua 应用的插件。

  

  相关链接

    * Eclipse Update

     * LDT插件   

  由于本人是Java技术背景,习惯使用Eclipse,因此后面的实例采用的是Eclipse+LDT插件的方式学习并演示Lua.还有就是工作中项目用的Mac+Sublime Text2作为编译调式工具.至于其它零零总总,五花八门的开发工具,不甚了解,也不想了解,有一个熟知的开发工具,便于学习理解和动手实践就够了,这里就不舍本求末了,有兴趣的读者,或者有需要的,自行再去了解.

   3.1 Eclipse+ LDT (Lua Development Tools)插件的安装

   (1) 到 Eclipse官网  下载 Eclipse IDE for C/C++ Developers 这个版本,原因呢,Lua是被设计成与C/C++很容易整合的语言么,当道就首先这个集成开发环境了.

   

   (2) 安装LDT插件,就像安装普通Eclipse插件一样.   

   

  或者参照: 插件安装 

   具体操作: 在高于Eclipse 4.3+ 以上选择菜单Help --> Install New Software 然后到

   

  

  然后点击下一步,Finish后重启Eclipse,检查Preferences首选项中,有无Lua选项,并创建Lua工程验证即可!

      

  环境搭建好了,那么,我们就可以更愉快地开始我们的Lua之旅了.

   相关链接

     * 官网详情

  

二. Lua常用语法

  作为有一定经验的猿,一些比较简单明了的基础语法,这里就不一一重述了,只选择性的说一下Lua特有的语法,或者常用的和容易混淆的语法.

  Lua是动态类型语言,变量不需要类型定义.Lua中有8个基本类型分别为nil,boolean,number,string,userdata,function,thread和table.函数type可以测试给定变量或者值的类型.

  1. 语句 

1 print("Hello World") --输出字符串: "Hello World"
2 print(type(type)) --> function
3 print(type(10.4*3)) --> number(type为判断类型函数)

  结果:

  注: Lua是类C的,所以,他是区分大小写的。Lua脚本语句的结尾,分号是可选的.

  2. 注释:       
1 -- 两个减号是行注释 
2 
3 --[[
4 
5   这是块注释
6 
7     这是块注释
8 
9 --]]

  3. 变量

   Lua的数字只有double型,64bits, 字符串你可以用单引号,也可以用双引号,还支持C类型的转义.
    C语言中的NULL在Lua中是nil,布尔类型只有nil和false是 false,数字0啊,‘’空字符串(’\0’)都是true!

  另外,需要注意的是:lua中的变量如果没有特殊说明,全是全局变量,那怕是语句块或是函数里。变量前加local关键字的是局部变量。将全局变量置为nil,意思是删除这个变量.

  优先使用局部变量可以:

  1. 避免命名冲突

  2. 访问速度比全局变量更快

  对于全局变量,Lua也是用Table来管理全局变量的,Lua把这些全局变量放在了一个叫“_G”的Table里。

  我们可以用如下的方式来访问一个全局变量(假设我们这个全局变量名叫globalVar):

1 _G.globalVar
2 _G["globalVar"]
1 -- 遍历全局变量Table _G
2 for k, v in pairs(_G) do
3     print(k, v)
4 end

  4. 表达式&运算符

  1) 运行时,Lua会自动在string和number之间自动进行类型转换.

  2)   a and b --如果a为false,则返回a,否则返回b

    a or b -- 如果a为true,则返回a,否则返回b

  3)   一个很实用的技巧: 如果x为false或者nil则给x赋初始值v

    x = x or v  <==> if not x then x = v end

  4) Lua中的三元运算符 (a and b) or c

  

  5) 连接运算符 ..  --两个点,如果操作数为数字,Lua将数字转成字符串 

  6) break语句用来退出当前循环(for,repeat,while).在循环外部不可以使用.

  5. 控制语句  

1 -- while循环
2 sum = 0
3 num = 1
4 while num <= 100 do
5     sum = sum + num
6     num = num + 1
7 end
8 print("sum =",sum)  
 1 -- if-else分支
 2 if age == 40 and sex =="Male" then
 3     print("男人四十一枝花")
 4 elseif age > 60 and sex ~="Female" then
 5     print("old man without country!")
 6 elseif age < 20 then
 7     io.write("too young, too naive!\n")
 8 else
 9     local age = io.read()
10     print("Your age is "..age)
11 end

  从上面可以看到: “~=”是不等于,而不是!=, 字符串的拼接操作符“..”, 条件表达式中的与或非为分是:and, or, not关键字。

  同时注意:Lua没有++或是+=这样的操作.

1 -- 普通for 循环
2 -- 从1加到100
3 sum = 0
4 for i = 1, 100 do
5     sum = sum + i
6 end
1 --until循环
2 sum = 2
3 repeat
4    sum = sum ^ 2 --幂操作
5    print(sum)
6 until sum >1000

   6. 函数(Lua的函数和Javascript的很像)

   1). 递归     

 1 -- 1.计算数n的阶乘
 2 function fact(n)
 3     if 0 == n then
 4         return 1
 5     else
 6         return n * fact(n - 1)
 7     end
 8 end
 9 
10 print("请输入数n: ")
11 number = io.read("*number")
12 print(tostring(number).."的阶乘为: "..tostring(fact(number)))

  执行结果:   

  2). 闭包  

 1 -- 调用newCounter()返回一个function,而这个function引用了newCounter()函数内部的局部变量local i
 2 ----------------------------
 3 function newCounter()
 4     local i = 0
 5     return function()
 6         i = i + 1
 7         return i
 8     end
 9 end
10 
11 c1 = newCounter
12 print(c1())  --> 1
13 
14 newCounter = nil  -- 就算我把这个函数销毁了
15 print(c1())  --> 3  还是生效

  在Lua中,所有的变量都是“指针”。所有的变量都是从堆里分配出来的,不像C与C++,局部变量是从栈里分配,一旦函数退出,所有局部变量都要被释放。Lua中的所有变量都是从堆里申请的。对象的释放是自动进行的,只有这个对象的引用计数为0了才会被释放掉。

 1 -- 示例二
 2 function myPower(x)
 3     return function(y) return y^x end
 4 end
 5  
 6 power2 = myPower(2)
 7 power3 = myPower(3)
 8  
 9 print(power2(4)) --4的2次方
10 print(power3(5)) --5的3次方

  3). 函数的返回值

  Lua一条语句上赋多个值,如: name, age, bGay = "haoel", 37, false, "haoel@hotmail.com"

  上面的代码中,因为只有3个变量,所以第四个值被丢弃。

  函数也可以返回多个值:

1 function getUserInfo(id)
2     print(id)
3     return "haoel", 37, "haoel@hotmail.com", "http://coolshell.cn"
4 end
5  
6 name, age, email, website, bGay = getUserInfo()

  注意:上面的示例中,因为没有传id,所以函数中的id输出为nil,因为没有返回bGay,所以bGay也是nil。

  4). 局部函数

  函数前面加上local就是局部函数    

1 -- 比如:下面的两个函数是一样的:
2 function foo(x) return x^2 end
3 foo = function(x) return x^2 end

  5). 尾调函数

  当函数的最后返回结果是调用另一个函数,称之为尾调函数。Lua的在调用尾调函数时,先是弹出当前函数的栈空间,然后再调用尾调函数,从而降低了函数层层调动过程中的栈消耗,非常适用于函数递归调用。

  7. Table

  所谓Table其实就是一个Key Value的数据结构,它很像Javascript中的Object,在别的语言里叫Dict或Map,Table长成这个样子: 

1 t = {name = "ChenHao", age = 37, handsome = True}  
 1 -- table的CRUD操作
 2 t = {name = "ChenHao", age = 37, handsome = True}
 3 
 4 t.website = "http://coolshelll.cn/" --
 5 local age = t.age --
 6 t.handsome = false --
 7 t.name = nil --
 8 
 9 for key, value in pairs(t) do
10     print(key,value)
11 end
12 
13 
14 --访问方式
15 t = {[20] = 100, ['name'] = "lzz", [3.14] = "PI"}
16 print(t[20], t["name"], t[3.14])

  执行结果:  

  注意细节:

 1 -- Lua中,表的索引推荐是从1开始的,不是0
 2 Polyline = { color = "blue", thickness = 2, npoints =4,
 3   {x = 0, y = 0},
 4   {x = -10, y = 0},
 5   {x = -10, y = 10},
 6   {x = 0, y = 10}
 7 }
 8 
 9 print(Polyline["color"])
10 print(Polyline.color)
11 print(Polyline[1])
12 print(Polyline[1].x)

执行结果:

  从上可以看出, 表中的元素都是由key-value组成。如果没有指定key,那就默认以1开始的整数做key,
如上4个{x,y}。如果指定了名称,则以string类型为key,如color, thickness, npoints。
其实,表的key还可以为table, function, file, boolean任意类型.value可以为任何Lua类型。

Person = {["name"] = "Peter", ["age"] = 28}  -- 等价于
Person = {name = "Peter", age = 28}

{x=0, y=0}  <--> {["x"]=0, ["y"]=0}
{"red", "green", "blue"}  <--> {[1]="red", [2]="green", [3]="blue"}

  数组相关:

 1 -- 数组细则
 2 arr = {10, 20, 30, 40, 50}
 3 --等价于
 4 arr = {[1]=10, [2]=20, [3]=30, [4]=40, [5]=50}
 5 
 6 arr = {"string", 100, "haoel", function() print("coolshell.cn") end}
 7 --其中的函数可以这样调用
 8 print(arr[4]())
 9 
10 --Lua中的数组是从1开始的,#arr为数组长度
11 for i=1, #arr do
12     print(arr[i])
13 End注:上面的程序中:#arr的意思就是arr的长度。

  注:上面的程序中:#arr的意思就是arr的长度。

    在Lua中习惯上数组下标从1开始,Lua标准库与此习惯保持一致,否则无法直接使用标准库的函数.

  执行结果:

 1 -- 数组操作
 2 local a = {10,20,30}
 3 table.insert(a,1,15) --指定位置插入
 4 table.sort(a) --排序
 5 
 6 --遍历
 7 for index,value in ipairs(a) do
 8     print(index,value)
 9 end
10 
11 table.remove(a,2) --移除

  结果:

  8. MetaTable 和 MetaMethod

  MetaTable和MetaMethod是Lua中的重要的语法,MetaTable主要是用来做一些类似于C++重载操作符式的功能。

  比如,我们想实现分数间的相加:2/3 + 4/7,我们如果要执行: fraction_a + fraction_b,会报错的。

  * setmetatable(table, meta_table)      设置元表
  * getmetatable(table)                       获取元表 

  所以,我们可以动用MetaTable,于是可以这么做: 

 1 -- 15.MetaTable 和 MetaMethod
 2 -- MetaTable主要是用来做一些类似于C++重载操作符式的功能
 3 
 4 -- 实现两个分数相加: 2/3 + 4/7
 5 fraction_a = {numerator=2, denominator=3}
 6 fraction_b = {numerator=4, denominator=7}
 7 
 8 fraction_op = {}
 9 function fraction_op.__add(f1, f2)
10     ret = {}
11     ret.numerator = f1.numerator * f2.denominator + f2.numerator * f1.denominator
12     ret.denominator = f1.denominator * f2.denominator
13     return ret
14 end
15 
16 -- 为之前定义的两个table设置MetaTable:(其中的setmetatble是库函数
17 setmetatable(fraction_a, fraction_op)
18 setmetatable(fraction_b, fraction_op)
19 
20 -- 调用的是fraction_op.__add()函数
21 fraction_s = fraction_a + fraction_b
22 
23 print("fraction_s的类型: ",type(fraction_s))
24 for key,value in pairs(fraction_s) do
25     if "numerator" == key then
26         print("分子",value)
27     else
28         print("分母",value)
29     end
30 End

  执行结果:

  至于__add这是MetaMethod,这是Lua内建约定的,其它的还有如下的MetaMethod:

  

  表相关: 

1 __index = function(tb, key)
2 __index = tb

  访问索引,如果执行读取一个表中的操作,而这个表里又没有这个域,那么Lua就去查询metatable中的__index域。如果__index是表, 那么就去查__index表中有没有这个域,如果有就从__index这个表里的这个域里去取值。如果__index是函数,那么就调用 __index(tb, key)函数。

1 __newindex = function(tb, key)

  更新索引,在更改表域的时候,如果这个表中没有这个域,那么就会从元表的__index里去找。与__index同理。

这两个东西,在类继承里用到.

  9. 面向对象

  上面我们看到有__index这个重载,这个东西主要是重载了find key的操作。这操作可以让Lua变得有点面向对象的感觉,让其有点像Javascript的prototype。

  所谓__index,说得明确一点,如果我们有两个对象a和b,我们想让b作为a的prototype只需要:

1 setmetatable(a, {__index = b})

  例如下面的示例:你可以用一个Window_Prototype的模板加上__index的MetaMethod来创建另一个实例: 

1 Window_Prototype = {x=0, y=0, width=100, height=100}
2 MyWin = {title="Hello"}
3 setmetatable(MyWin, {__index = Window_Prototype})

  于是:MyWin中就可以访问x, y, width, height的内容了。(注:当表要索引一个值时如table[key], Lua会首先在table本身中查找key的值, 如果没有并且这个table存在一个带有__index属性的Metatable, 则Lua会按照__index所定义的函数逻辑查找)

  有了以上的基础,我们可以来说说所谓的Lua的面向对象。   

 1 Person={}
 2  
 3 function Person:new(p)
 4     local obj = p
 5     if (obj == nil) then
 6         obj = {name="ChenHao", age=37, handsome=true}
 7     end
 8     self.__index = self
 9     return setmetatable(obj, self)
10 end
11  
12 function Person:toString()
13     return self.name .." : ".. self.age .." : ".. (self.handsome and "handsome" or "ugly")
14 end  

  上面我们可以看到有一个new方法和一个toString的方法。其中:

  1)self 就是 Person,Person:new(p),相当于Person.new(self, p)

  2)new方法的self.__index = self 的意图是怕self被扩展后改写,所以,让其保持原样
  3)setmetatable这个函数返回的是第一个参数的值。

  于是:我们可以这样调用:   

1 me = Person:new()
2 print(me:toString())
3  
4 kf = Person:new{name="King's fucking", age=70, handsome=false}
5 print(kf:toString())

  继承如下,Lua和Javascript很相似,都是在Prototype的实例上改过来改过去的。   

 1 Student = Person:new()
 2  
 3 function Student:new()
 4     newObj = {year = 2013}
 5     self.__index = self
 6     return setmetatable(newObj, self)
 7 end
 8  
 9 function Student:toString()
10     return "Student : ".. self.year.." : " .. self.name
11 end   

  10. 其它Lua的标准库

  1) math库

1 -- 2.沟股定理
2 function sulcusSharesTheorem(x,y)
3     return math.sqrt(x^2 + y^2)
4 end
5 print("沟3股4,弦: "..tostring(sulcusSharesTheorem(3,4)))

  结果:

  2) string库 

1 -- string的格式化输出
2 --输出数学PI的3.14%形式
3 print(string.format("%.2f", math.pi) .. "%")
4 --输出数学PI的整数部分
5 print(string.format("%.0f", math.pi))

   结果: 

 1 -- 常见字符串操作
 2 s = "abcdefg"
 3 print("字符串长度: ",string.len(s))
 4 print("重复3次s的字符串",string.rep(s,3))
 5 print("创建8个a的字符串",string.rep("a",2^3))
 6 print("转大写",string.upper(s))
 7 print("转小写",string.lower(s))
 8 print(string.char(97))
 9 
10 i = 99
11 print(string.char(i,i+1,i+2))
12 print(string.byte("abc"))
13 print(string.byte("abc",2))
14 print(string.byte("abc",-1))

  结果:

  

  3) os库(clock,date,time)   

1 -- 通过函数os.clock()计算执行程序花费的时钟秒数
2 local x = os.clock()
3 local s = 0
4 for i = 1,100000000 do s = s + 1 end
5 
6 print(string.format("elapsed time: %.2f\n",os.clock() - x))

  结果:  

 1 -- 时间日期格式化
 2 print("当前时间毫秒值: ",os.time())
 3 --时间日期信息表 
 4 dateTime = os.date("*t",os.time())
 5 print("时间日期类型: ",type(dateTime))
 6 
 7 for key,value in pairs(dateTime) do
 8     if "day" == key then
 9         print(value .. "")
10     elseif "month" == key then
11         print(value .. "")
12     elseif "year" == key then
13         print(value .. "")
14     elseif "hour" == key then
15         print(value .. "")
16     elseif "min" == key then
17         print(value .. "")
18     elseif "sec" == key then
19         print(value .. "")
20     elseif "wday" == key then
21         print("这个星期第" .. value .. "")
22     elseif "yday" == key then
23         print("这一年第" .. value .. "")
24     elseif "isdst" == key then
25         print(value, " true if daylight saving")
26     end
27     --print(key,value)
28 end

  结果:

  参数说明:

  

 1 -- 其它处理方式
 2 print(os.date("%a,%A"))
 3 print(os.date("%b,%B"))
 4 print(os.date("%c"))
 5 print(os.date("%d"))
 6 print(os.date("%H"))
 7 print(os.date("%I"))
 8 print(os.date("%M"))
 9 print(os.date("%m"))
10 print(os.date("%p"))
11 print(os.date("%S"))
12 print(os.date("%w"))
13 print(os.date("%x"))
14 print(os.date("%X"))

  结果:

  4) io库   

  -- 输入一个数,error函数抛出非数字的错误信息.

1 print("enter a number: ")
2 m = io.read("*number")
3 if not m then error("invalid input") end
4 
5 print("enter another number: ")
6 n = assert(io.read("*number"),"invalid input")

  执行结果:

11. 加载文件与运行

  当我们需要加载与运行已有文件中的Lua代码时,可以用以下几种方式:

   (1) loadstring( str )  --- 加载字串

1 f = loadstring "a = 12; print('a=' .. a)"
2 f()  --> a=12

  loadstring()本是函数,由于函数是string,所以没有加括号。loadstring()执行完之后,只是加载解析,并没有执行。返回的是一个function类型。执行该函数便可以运行。相当于:

1 f = loadstring "function() a = 12; print('a='..a) end"

   (2) loadfile( file_name ) --- 加载文件

   这个函数相当于从文件里读出string,然后再调用loadstring(file_text)实现加载功能。

  (3) dofile( file_name )  --- 加载并执行文件

  相当于loadfile()之后,返回一个函数,再调用这个函数。

1 function dofile( file_name )
2     local f = assert(loadfile(file_name))
3     f()
4 end

  (4) require( file_name ) 

  这个函数是通过调用dofile()来实现的。不同的是,每次加载执行一个文件时,require()都会记录,避免重复加载。另外,如果给定的路径找不到文件,require()会到指定的路径下去找输到加载的文件。文件名称可以省去.lua后缀。

  我们可以直接使用require(“model_name”)来载入别的lua文件,载入的时候就直接执行那个文件了。比如,我们有一个hello.lua的文件:

1 print("Hello, World!")

  如果我们:require(“hello”),那么就直接输出Hello, World!了。

  注意:
  1)require函数,载入同样的lua文件时,只有第一次的时候会去执行,后面的相同的都不执行了。
  2)如果你要让每一次文件都会执行的话,你可以使用dofile(“hello”)函数
  3)如果你要玩载入后不执行,等你需要的时候执行时,你可以使用 loadfile()函数,如下所示:  

1 local hello = loadfile("hello")
2 ... ...
3 ... ...
4 hello()

  loadfile(“hello”)后,文件并不执行,我们把文件赋给一个变量hello,当hello()时,才真的执行。

    当然,更为标准的玩法如下所示。

  假设我们有一个文件叫mymod.lua,内容如下:

    文件名:mymod.lua

 1 local HaosModel = {}
 2  
 3 local function getname()
 4     return "Hao Chen"
 5 end
 6  
 7 function HaosModel.Greeting()
 8     print("Hello, My name is "..getname())
 9 end
10  
11 return HaosModel

  于是我们可以这样使用:

1 local hao_model = require("mymod")
2 hao_model.Greeting()

  其实,require干的事就如下:(所以你知道为什么我们的模块文件要写成那样了)   

1 local hao_model = (function ()
2   --mymod.lua文件的内容--
3 end)()

三. 习题小练

  1. 构造一个反向表,交换key-value的位置 

 1 --3.构造一个反向表,交换key-value的位置
 2 days = {"Sunday","Monday","Tuesday","Wednesday",
 3     "Thursday","Friday","Saturday"}
 4 
 5 --构造一个反向表
 6 revDays = {}
 7 for i,v in ipairs(days) do
 8     revDays[v] = i
 9 end
10 
11 --打印反向后表的key,value
12 for key,value in pairs(revDays) do
13     print(key,value)
14 end

  执行结果:

  2. pairs(泛型遍历集合和数组)与ipairs(遍历出带索引的数组)的区别

 1 -- pairs(泛型遍历集合和数组)与ipairs(遍历出带索引的数组)的区别
 2 
 3 a = {"aaa",a="哈哈", y=30, "ddd"}
 4 
 5 for k, v in pairs(a) do
 6   print(k, v)
 7 end
 8 
 9 print(a[1] .. " --------------- " .. a["y"])
10   
11 for i, v in ipairs(a) do
12   print(i, v)
13 end

  执行结果:

  3. 创建一个n行m列矩阵

 1 -- 6. 创建一个n行m列矩阵
 2 function createMatrix(N,M)
 3     local mt = {} --create the matrix
 4     for i = 1,N do
 5         mt[i] = {} --create a new row
 6         for j = 1,M do
 7             mt[i][j] = i * j
 8         end
 9     end
10     return mt
11 end
12 
13 --验证n行m列矩阵
14 local tab = createMatrix(2,3)
15 for i = 1,2 do
16     for j = 1,3 do
17         print(tab[i][j])
18     end
19 End

  执行结果:

  4. 以字母顺序打印出这些函数名

 1 -- 以字母顺序打印出这些函数名
 2 lines = {
 3     luaH_Set = 10,
 4     luaH_Get = 24,
 5     luaH_present = 48
 6 }
 7 
 8 temp = {}
 9 --将函数名放到一个数组内
10 for n in pairs(lines) do table.insert(temp, n) end
11 table.sort(temp)
12 
13 for i,n in ipairs(temp) do print(n) end
14 
15 print("------------------------")
16 
17 function pairsByKeys(t, f) --可选参数f指定排序方式
18     local a = {}
19     for n in pairs(t) do table.insert(a, n) end
20     table.sort(a, f)
21     local i = 0               -- iterator variable
22     local iter = function()   -- iterator function
23         i = i + 1
24         if a[i] == nil then return nil
25         else return a[i],t[a[i]]
26         end
27     end
28     return iter
29 end
30 
31 for name, line in pairsByKeys(lines) do
32     print(name, line)
33 end

  执行结果:

参考

  如果你还比较喜欢Lua的话,下面是几个在线文章你可以继续学习之:

    Lua官网 Lua官方网站

  book.luaer.cn lua在线lua学习教程

 

  由于本人对Lua面向对象等的使用和理解还不深刻,这里参考了博文 酷 壳 – CoolShell.cn,

  和 Lua学习总结 这里感谢这两位位博主!

  由于对于Lua与C/C++的交互部分也不熟悉,因此这里就不作过多陈述了.

  同时对此文感觉还是有点用的,欢迎给伦家点个攒,因为被认可也是一种幸福和动力~~.                                                   

                                     From: sunriselzz