lua学习笔记之二(C/C++程序员的Lua快速入门[进阶话题])
来源:互联网 发布:少数民族流动人口数据 编辑:程序博客网 时间:2024/05/20 23:39
进阶话题
1.函数闭包
1.1 实例代码
function createCountdownTimer(second)local ms = second * 1000 --ms为countDown的Upvaluelocal function countDown()ms = ms -1return msendreturn countDownendlocal timer1 = createCountdownTimer(1) for i = 1, 3 doprint(timer1()) end
输出结果:
999
998
997
1.2 关于函数闭包描述
- Upvalue
一个函数所使用的定义在它的函数体之外的局部变量(external local variable)称为这个函数的upvalue。 在前面的代码中,函数countDown使用的定义在函数createCountdownTimer 中的局部变量ms就是countDown的upvalue,但ms对createCountdownTimer而 言只是一个局部变量,不是upvalue。 Upvalue是Lua不同于C/C++的特有属性,需要结合代码仔细体会。
- 函数闭包
- Lua函数闭包与C函数的比较
Lua函数闭包使函数具有保持它自己的状态的能力,从这个意义上说,可以 与带静态局部变量的C函数相类比。但二者有显著的不同:对Lua来说,函数 是一种基本数据类型——代表一种(可执行)对象,可以有自己的状态;但 是对带静态局部变量的C函数来说,它并不是C的一种数据类型,更不会产生 什么对象实例,它只是一个静态地址的符号名称。
2. 基于对象的实现方式
2.2 实例代码
local function create(name ,id )local data = {name = name ,id = id} --data为obj.SetName,obj.GetName,obj.SetId,obj.GetId的Upvaluelocal obj = {} --把需要隐藏的成员放在一张表里,把该表作为成员函数的upvalue。function obj.SetName(name)data.name = name endfunction obj.GetName() return data.nameendfunction obj.SetId(id)data.id = id endfunction obj.GetId() return data.idendreturn objend
输出结果:
mycreate's id:1mycreate's name:Sam
mycreate's id:1mycreate's name:Lucy
2.2 有关对象实现的描述
实现方式: 把需要隐藏的成员放在一张表里,把该表作为成员函数的upvalue。
局限性: 基于对象的实现不涉及继承及多态。但另一方面,脚本编程是否需要继承和多态要视情况而定。
3.元表
3.1 实例代码(1):
local t = {}local m = {a = "and",b = "Li Lei", c = "Han Meimei"}setmetatable(t,{__index = m}) --表{ __index=m }作为表t的元表for k,v in pairs(t) do --穷举表tprint("有值吗?")print(k,"=>",v)endprint("-------------")print(t.b, t.a, t.c)
输出结果:
-------------
Li LeiandHan Meimei
3.2 实例代码(2):
local function add(t1,t2)--‘#’运算符取表长度assert(#t1 == #t2)local length = #t1for i = 1,length dot1[i] = t1[i] + t2[i]endreturn t1end--setmetatable返回被设置的表t1 = setmetatable({1,2,3},{__add = add})t2 = setmetatable({10,20,30},{__add = add})for k,v in pairs(t1) doprint(k,"=>",v)endfor k,v in pairs(t2) doprint(k,"=>",v)endprint("---------两元表相加--------------")t1 = t1 + t2for i = 1 ,#t1 doprint(t1[i])end
1 => 1
2 => 2
3 => 3
1 => 10
2 => 20
3 => 30
---------两元表相加--------------
11
22
33
3.3 有关元表的描述:
定义 :
元表本身只是一个普通的表,通过特定的方法(比如setmetatable)设置到某个对象上,进而影响这个对象的行为;一个对象有哪些行为受到元表影响以及这些行为按照何种方式受到影响是受Lua语言约束的。比如在前面的代码里,两个表对象的加法运算,如果没有元表的干预,就是一种错误;但是Lua规定了元表可以“重载”对象的加法运算符,因此若把定义了加法运算的元表设置到那两个表上,它们就可以做加法了。元表是Lua最关键的概念之一,内容也很丰富,请参考Lua文档了解详情。
元表与C++虚表的比较:
如果把表比作对象,元表就是可以改变对象行为的“元”对象。在某种程度上,元表可以与C++的虚表做一类比。但二者还是迥然不同的:元表可以动态的改变,C++虚表是静态不变的;元表可以影响表(以及其他类型的对象)的很多方面的行为,虚表主要是为了定位对象的虚方法(最多再带上一点点RTTI)。
4. 基于原型的继承*
4.1 实例代码
local Robot = { name = "Sam", id = 001 }function Robot:New(extension)local t = setmetatable(extension or { }, self) self.__index = selfreturn tendfunction Robot:SetName(name)self.name = name endfunction Robot:GetName() return self.nameendfunction Robot:SetId(id)self.id = id endfunction Robot:GetId() return self.idendrobot = Robot:New()print("robot's name:", robot:GetName()) print("robot's id:", robot:GetId()) print("-----------------")local FootballRobot = Robot:New({position = "right back"})function FootballRobot:SetPosition(p) self.position = pendfunction FootballRobot:GetPosition()return self.position endfr = FootballRobot:New()print("fr's position:", fr:GetPosition()) print("fr's name:", fr:GetName()) print("fr's id:", fr:GetId()) print("-----------------")fr:SetName("Bob")print("fr's name:", fr:GetName()) print("robot's name:", robot:GetName())
输出结果:
robot's name:Sam
robot's id:1
-----------------
fr's position:right back
fr's name:Sam
fr's id:1
-----------------
fr's name:Bob
robot's name:Sam
4.2 相关描述:
prototype模式一个对象既是一个普通的对象,同时也可以作为创建其他对象的原型的对象(即类对象,class object);动态的改变原型对象的属性就可以动态的影响所有基于此原型的对象;另外,基于一个原型被创建出来的对象可以重载任何属于这个原型对象的方法、属性而不影响原型对象;同时,基于原型被创建出来的对象还可以作为原型来创建其他对象。
5.包
5.1 实例代码:
hello.lua
local pack = require "mypack" --导入包[注:包的名字与定义包的文件的名字相同(除去文件名后缀,在前面的代码中,就是“mypack”)]print(ver or "No ver defined!")print(pack.ver)pack.aFunInMyPack()print(aFunInMyPack or "No aFunInMyPack defined!")aFuncFromMyPack()
mypack.lua
module(..., package.seeall) --定义包ver = "0.1 alpha"function aFunInMyPack() print("Hello!")end_G.aFuncFromMyPack = aFunInMyPack
输出结果:
No ver defined!
0.1 alpha
Hello!
No aFunInMyPack defined!
Hello!
- 定义
- 实现方式
一般在一个Lua文件内以module函数开始定义一个包。module同时定义了一个新的包的函数环境,以使在此包中定义的全局变量都在这个环境中,而非使用包的函数的环境中。理解这一点非常关键。以前面的代码为例, “module(..., package.seeall)”的意思是定义一个包,包的名字与定义包的文件的名字相同(除去文件名后缀,在前面的代码中,就是“mypack”),并且在包的函数环境里可以访问使用包的函数环境(比如,包的实现使用了print,这个变量没有在包里定义,而是定义在使用包的外部环境中)。
- 使用方式
一般用require函数来导入一个包,要导入的包必须被置于包路径(packagepath)上。包路径可以通过package.path或者环境变量来设定。一般来说,当前工作路径总是在包路径中。
- 其他
参考文献《C/C++程序员的Lua快速入门》
- lua学习笔记之二(C/C++程序员的Lua快速入门[进阶话题])
- lua学习笔记之三(C/C++程序员的Lua快速入门[高阶话题])
- lua学习笔记之一(C/C++程序员的Lua快速入门[初阶话题])
- C/C++程序员的Lua快速入门
- Lua学习笔记二之C中调用Lua
- lua入门之二:c/c++ 调用lua及多个函数返回值的获取
- lua入门之二:c/c++ 调用lua及多个函数返回值的获取
- Lua入门之二:C/C++ 调用Lua及多个函数返回值的获取
- Lua学习笔记三之从Lua中调用C
- lua源码学习(二)lua的lapi.c实现
- Lua学习笔记二--在Lua中使用自己的C函数
- Lua学习笔记二--在Lua中使用自己的C函数收藏
- Lua学习笔记--C调用Lua
- Lua学习笔记--Lua调用C初探
- c++Primer学习笔记之二:c++快速入门_1
- 通过例子学习Lua(5) ---- Lua与C交互入门
- Lua 入门学习笔记
- Lua学习笔记:Lua 中的C Api 概述
- android 自定义控件--(圆盘形菜单控件)
- PCB走线3W与20H原则
- VS2010在调试时产生断点错位怎么解决
- java Class.forName("") .newInstance();
- Shell编程基础 part 1/2
- lua学习笔记之二(C/C++程序员的Lua快速入门[进阶话题])
- oracle收购Mysql后,Mysql的安装配置方法
- 逆向思维求解质数
- assert实例
- Ubuntu出错笔记_安装出错提示
- SAP-ABAP中强大的循环控制
- 3.通过进入单用户模式解决linux中的rc.local修改后无法启动的问题
- 10.Linux用户基础
- 智能指针