lua 学习笔记 二

来源:互联网 发布:java 16进制中文 编辑:程序博客网 时间:2024/05/21 00:19
11.0
lua中的习惯一般是以1作为数组的起始索引,lua库和长度操作符都遵循这个约定。
对于稀疏矩阵,存在大量的“空洞(nil值)”,遍历矩阵的效率很低,通常使用pairs且只遍历非nil元素。访问顺序是无序的。P118
字符串缓冲问题可能导致对字符串的操作消耗大量的时间,通过使用table配合concat函数来解决。
当字符串中包含特殊字符,有可能导致lua程序无效,可以用%q来使用string.format函数来解决。


13.0 - 13.4
通过元表可以修改一个值的行为,使其在面对一个非预定义的操作时执行一个指定的操作。
__add元方法 可以定义相加行为。
使用setmetatable来设置或修改table元表。
任何table都可以作为任何值的元表,而一组相关的table也可以共享一个通用的元表,此元表描述了它们共同的行为。一个table也可以是自己
的元表,用于描述其特有行为。
lua代码中,只能设置table的元表,若要设置其他类型的值的元表,则需要通过C代码来完成,(防止过度使用某些特定于类型的元表,导致代码
无法复用)


算术类:__add,__mul,__sub,__div,__unm(相反数),__mod,__pow(乘幂)。__concat字段。


Lua查找元表的步骤:如果第一个值有元表,则用这个字段的元方法,若第一个值没有元表,则用第二个值的元表,若都没有元方法,则lua引发一个错误。
关系类:__eq(等于),__lt(小于),__le(小于等于)。其他3个关系操作符没有单独的元方法,lua会进行转换。
关系转换对“部分有序”(partial order)可能发生错误。如对NaN(not a number);
标准规定任何涉及NaN的比较都应返回false,这意味着NaN <= x 永远为假,但x <= NaN也为假。导致转换出现不合法。
关系类的元方法不能应用于混合的类型。对不同类型进行顺序比较,lua会引发一个错误,而等于比较永远不会引发错误,如果两个对象有不同的元方法,元方法都不调用,直接返回false。而是以普通行为处理。只有当两个比较对象共享一个元方法时,Lua才调用这个等于比较的元方法。
要使用户既不能看也不能修改集合的元表。需要用到字段__metatable.getmetatable返回该字段值,而setmetatable引发一个错误。P135
__index元方法修改查询table的行为。
__newindex元方法用于修改table的修改行为
调用rawset(t,k,v)就可以不涉及任何元方法而直接设置table t中与key k相关联的 value v。
跟踪table访问
#!/usr/local/bin/lua
do
t = {}
local _t = t
t = {}
local mt = {
__index = function (t,k)
print("access to element" .. tostring(k))
return _t[k]
-- body
end,
__newindex = function (t,k,v)
print("update of element" .. tostring(k) .. "to" .. tostring(v))
_t[k] = v
-- body
end
}
setmetatable(t,mt)


end
-- 存在无法通过pairs遍历table的问题。(可以重封装pairs函数)


将原table作为代理table的一个特殊字段。从而让同时需要监视的table公用一个元表。
#!/usr/local/bin/lua
do
local _t = {}
local mt = {
__index = function (t,k)
print("access to element" .. tostring(k))
return t[_t][k]
-- body
end,
__newindex = function (t,k,v)
print("update of element" .. tostring(k) .. "to" .. tostring(v))
t[_t][k] = v
-- body
end
}
function track(t)
local proxy = { }
proxy[_t] = t
setmetatable(proxy,mt)
return proxy
-- body
end
t = {"hello","world","heihei","hehe"}
s = {"lua","is","a","simple","language"}
t = track(t)
s = track(s)
end


14.0 - 14.3
lua将其所有的全局变量保存在一个常规的table中,这个table称为环境(environment)。
一,无需再为全局变量创造新的数据结构,简化了lua内部实现,二,环境和其他table一样操作。
lua将环境table自身保存在一个全局变量_G中。
可以通过访问_G中得全局变量来访问运行时动态生成的全局变量值,提高效率
value = _G[varname]
getfield()函数可以获取嵌套表中指定key的value。P144下划线写成了连字符。
过多的全局变量容易导致命名冲突和访问错误变量名,可以通过修改全局变量的元表来实现访问错误变量时的行为。
通过rawset可以绕过元表来完成新变量的声明


可以通过函数setfenv来改变一个函数的环境。函数的参数是一个函数或一个数字(指定栈层)和一个新的环境。(5.3该函数已经取消,改为_ENV,http://blog.codingnow.com/2015/01/lua_52_53.html) 
#!/usr/local/bin/lua
do
a = 1
_ENV = {g = _G}
g.print(a)
g.print(g.type(g))
g.print(g.a)
end


每个函数及某些closure都有一个继承的环境。


15.0 - 15.5
require函数加载模块。对已经加载的模块,函数不会再次加载,只会返回相应的值。
loadfile加载lua代码,loadlib加载C库;
package.loaded中存储了加载器的返回值。
在require中,如果一个模块名中包含了连字符,require就会用连字符后的内容来创建luaopen_*函数名。从而方便在测试中对各不同版本的模块进行加载而无需修改代码。
packag.seeall 等价于 setmetatable (M,{__index = _G})(继承方式)


lua支持具有层级性的模块名,可以用一个点来分隔名称中的层级。
require 子模块a.b并不会自动加载a。


16.0 - 
lua中的table就是一种对象,table与对象一样可以拥有状态,其次,table也与对象一样拥有一个独立于其值的标识(一个self),最后,table与对象一样具有独立于创建者和创建地的生命周期。
冒号的作用是在一个方法定义中添加一个额外的隐藏参数,以及在一个方法调用中添加一个额外的实参。
setmetatable(a,(__index = b)), a会在b中查找所有它没有的操作。可以将b视为a的基类。


lua中多重继承的实现,通过将__index字段设为一个函数,通过函数对多继承的基类对象进行搜索。(多重继承的性能不如单一继承)
双table实现私密性


function newAccount (initialBalance)
local self = {balance = initialBalance}
local withdraw = function(v)
self.balance = self.balance - v
end
local desposit = function (v)
self.balance = self.balance + v
end
local getBalance = function() return self.balance end
return {
withdraw =withdraw,
deposit = deposit,
getBalance = getBalance
}
end
当一个对象只有一个方法时,可以不用创建接口table,但需要将这个单独的方法作为对象表示来返回。即采用单一方法(single - method).采用了closure,虽然无法实现继承,但拥有完全的私密性。


弱引用table是一种用来告诉Lua一个引用不应该阻碍一个对象的回收的机制。是一种会被垃圾收集器忽视的对象引用。
一个table的弱引用类型通过其元表中的__mode字段来决定,k对应key,v对应value。完全若引用“kv”
#!/usr/local/bin/lua
do
a = {}
b = {__mode = "k"}
setmetatable(a,b)
key1 = {}
a[key] = 1
key2 = {}
a[key] = 2
print(a[key])
collectgarbage()
for k,v in pairs(a) do print(k,v) end
end
key1 和key2的值是不同的,为二个不同的空table得地址。
在lua中,字符串就是值,而非对象,因此,字符串和数字布尔类型一样,不会从若引用table中删除。































0 0
原创粉丝点击