书本下载地址 http://download.csdn.net/detail/myy2012/5349646
本部分下载地址 http://download.csdn.net/detail/myy2012/5396343
lua程序设计第二版 读书笔记(1-4章)
第一章 开始
第二章 类型与值
第三章 表达式
第四章 语句
http://blog.csdn.net/myy2012/article/details/8900424
lua程序设计第二版 读书笔记(5-8章)
第五章 函数
第六章 深入函数
第七章 迭代器与泛型for
第八章 编译执行与错误
http://blog.csdn.net/myy2012/article/details/8906466
lua程序设计第二版 读书笔记(9-10章)
第九章 协同程序
第十章 完整的实例
http://blog.csdn.net/myy2012/article/details/8911206
lua程序设计第二版 读书笔记(11-14章)
第十一章 数据结构
第十二章 数据文件与持久性
第十三章 元表metatable与元方法meatmethod
第十四章 环境
http://blog.csdn.net/myy2012/article/details/8914457
lua程序设计第二版 读书笔记(15-17章)
第十五章 模块与包
第十六章 面向对象编程
第十七章 弱引用 table
http://blog.csdn.net/myy2012/article/details/8921632
lua程序设计第二版 读书笔记(18-21章)
第十八章 数学库
第十九章 table库
第二十章 字符串库
第二十一章 IO库
http://blog.csdn.net/myy2012/article/details/8925895
lua程序设计第二版 读书笔记(22-23章)
第二十二章 操作系统库
第二十三章 调试库
http://blog.csdn.net/myy2012/article/details/8930181
Lua从5.1 版开始,为模块和包定义了一系列的规则。这些规则不需要语言引入额外的技能,我们可以使用早已熟知的table、函数、元表和环境来实现这些规则。
使用table来实现模块的优点在于,可以像操作普通table那样来操作模块,并且能利用Lua现有的功能来实现各种额外功能。
例如:一个用户要调用一个模块中的函数
方法1:
require “mod”
mod.foo()
方法2:
require “mod”
local f= mod.foo
方法3:
local m = require “mod”
m.foo()
15.1 require 函数
对于require 而已,一个模块就是一段定义了一些值的代码。
要加载一个模块,只需要简单地调用require “<模块名>”。 该调用会返回一个由模块函数组成的table,并且还会定义一个包含该table的全局变量。
package.path:保存加载外部模块(lua中"模块"和"文件"这两个概念的分界比较含糊,因为这个值在不同的时刻会扮演不同的角色)的搜索 路径,这种路径是"模板式的路径",它里面会包含可替代符号"?",这个符号会被替换,然后lua查找这个文件是否存在,如果存在就会调用其中特定的接口。
15.2 编写模块的基本方法
在Lua中创建一个模块最简单的方法是:创建一个table,并将所有需要导出的函数放入其中,最后返回这个table。
这种“表模块”的使用方法不像真正模块。我们必须在每个函数前面加上模块名。我们可以改善这个问题,模块名作为局部名,然后将它赋值给全局名作为最终模块名:
local M = {}
complex = M -- 模块名
M.i = {r=0, i=1}
function M.new (r, i)
return {r=r, i=i}
end
function M.add (c1, c2)
return M.new(c1.r + c2.r, c1.i + c2.i)
end
15.3 使用环境
函数环境:让模块的主程序有一个独占的环境,这样不仅它的所有函数都可共享这个table,而且它的所有全局变量也都记录在这个table中。
模块所要做的就是将这个table赋予模块名和package.loaded 。例如:
local modname=...
local M={}
_G[modname]=M
package.loaded[modname]=M
setmetatable(M, {__index=_G})
setfenv(1, M)
一种更正规的方法就是将那些需要用到的函数或模块声明为局部变量:
--模块设置
local modname=...
local M={}
_G[modname]=M
package.loaded[modname]=M
--导入段:(声明这个模块从外界所需的所有东西)
local sqrt = math.sqrt
local io=io
--这句之后就不再需要外部访问了
setfenv(1,M)
15.4 module 函数
在文件开头加入语句:module(..., package.seeall) 既可使一个文件变成模块。
在这个开头有了这句调用后,后续所有的代码都可以像普通的Lua代码那样编写了,不需要限定模块名和外部名字,同样也不需要返回模块table。
A. table与对象一样可以拥有状态
B. table与对象一样拥有一个独立于其值的标识(self)
C. table与对象一样具有独立于创建者和创建地的生命周期
指定一项操作所作用的“接受者”。因此需要一个额外的参数来表示该接受者。例如:
function Account.withdraw(self, v)
self.balance = self.balance -v
end
此时当调用该方法时,必须指定其作用的对象
a1= account
a1 = nil
a1.withdraw(a1, 100.0) -- 不会报错
使用self参数是所有面向对象语言的一个核心。Lua只需使用冒号,就能隐藏该参数。例如:
function Account:withdraw(v)
self.balance = self.balance - v
end
调用时: a:withdraw(100.0)
16.1 类
Lua没有类的概念(但是可以模拟),每个对象只能自定义行为和形态。
如果有两个对象a和b,要让b作为a的一个原型,只需输入如下语句:
setmetatable(a, {__index = b})
在此之后,a就会在b中查找所有它没有的操作。
--新对象a从对象Account那里继承了deposit函数
16.2继承
若想从这个类派生出一个子类SpecialAccount, 则先需要创建一个空的类,从基类继承所有的操作: SpecialAccount = Account:new()
s=specialAccount:new{limit=1000.0}
SpecialAccount从Account继承了new(就像继承其他方法一样),不过这次new在执行时,它的self参数表示为specialAccount。因此s的元表为specialAccount,specialAccount中字段__index的值也是specialAccount。 s-->specialAccount-->Account
Lua在s中找不到deposit域;所以到SpecialAccount 中找;还是找不到,所以又去Account中找。
16.3 多重继承
用一个函数作为__index的元字段。例如:若在一个table的元表中,__index字段为一个函数,那么只要Lua在原来的table中找不到一个key,就会调用这个函数。(基于这点,就可以让__index函数在其他地方查找缺失的key)
NamedAccount = createClass(Account2, Named)
account3 = NamedAccount:new{name = "Paul"}
print(account3:getname()) --> Paul
16.4 私密性
通过2个table来表示一个对象,一个table用来保存对象的状态;另一个用于对象的操作(接口)。然后通过接口来进行对象的访问,而表示状态的table则保存在closure中。
16.5 单一方法(single-method)做法
通常,垃圾收集器不会回收一个可访问table中作为key或者value的对象(key和value都是强引用, 他们会阻止对其所引用对象的回收)。
而在一个弱引用table中,key和value是可以被回收的。
A. 具有弱引用key的table
B. 具有弱引用value的table
C. 同时具有两种弱引用的table
一个table的弱引用类型是通过其元表的__mode字段来决定的:如果这个串包含字母’k’,则表的keys 是弱引用;如果这个串包含字母’v’,则表的values 是弱引用。
第二句key={}会覆盖第一个key={}。当收集器运行时,由于没有其他地方在引用第一个key,因此第一个可以就被回收了,并且table中相应条目也被删除了。
17.1 备忘录(memoize)函数
一种常用的编程技巧是用空间换时间。你能够给一些函数加速,通过memoizing 它们的结果。当什么时侯,你再以相同的参数调用这个函数,它能重用那个结果。
用户可以使用等号运行符比较颜色,因为有一样颜色的color 实际上是同一个表。
17.2 对象属性
很多情况需要把有些属性绑定到某个对象(例如函数与其名称、table的默认值、数组的大小)。
用对象作为表的key,用对象的属性作为表的value。
17.3 回顾table的默认值
第二部分完