lua程序设计(4)

2013-03-05 00:38

lua程序设计(4)

by snoopyxdy

at 2013-03-04 16:38:48

original http://snoopyxdy.blog.163.com/blog/static/601174402013127102147934

1、table的key是无顺序的,无法保证paris顺序

2、lua逐步读取大字符串的方法:
local t ={}
for line in io.lines() do 
 t[#t+1]  = line
end
 t[#t+1]  = ""
local s = table.concat(t, '\n')

以上代码速度是直接字符串拼接的数倍

3、string.format 字符串格式化
a = 'a "problem" \\string'
print(string.format("%q",a))    -- "a \"problem\" \\string"

4、让一个table使用默认字段
window = {}
window.prototype  = {x=0, y=0, width=100, height=100}
window.mt = {}
function window.new(o)
setmetatable(o, window.mt)
return o
end
window.mt.__index = function(table, key)
return window.prototype[key]
end
 -- 这里也可以写为
-- window.mt.__index = window.prototype

w = window.new{x=10, y=20}
print(w.width)

5、更简单的默认值table
function setDefault(t ,d)
local mt = { __index = function() return d end}
setmetatable(t, mt)
end

tab = {x=10, y=20}
print(tab.x, tab.z)
setDefault(tab, 0)
print(tab.x, tab.z)

输出结果:
10 nil
10 0

6、设定只读table
function readOnly (t)
local proxy={}
local mt = {
__index = t,
__newindex = function (t, k, v)
error("attempt to update a read-only table", 2)
end
}
setmetatable(proxy,mt)
return proxy
end

local days = readOnly{1,2,3,4,5,6,7}
print(days[1])
days[2] = 0   --error
print(days[2])

7、全局环境lua使用_G这个table
for n in pairs(_G) do
print(n)
end

8、setfenv方法改变函数运行环境
setfenv 的第一个参数,1表示改变当前函数的运行环境,2表示修改调用该函数的函数运行环境,依次类推,可以为3,4,5等
a=1
setfenv(1, {})
print(a)  -- error改变了全局环境,导致代码出错了

9、lua的require模块函数,是不是似曾相识?对node中也是这样的
lua程序设计(4) - snoopyxdy - snoopyxdy的博客
 
先判断table缓存中是否有改模块,如果有则去package.loaded中返回,如果没有则去fidloader中拿模块。所以lua的模块加载和node是一样的,模块大小写敏感

10、moudle函数
moudle(..., seeall)
让模块可以访问全局变量

11、弱引用kv
    lua里用弱引用table(weak table)来实现这个机制
    3种弱引用table
        1.具有弱引用key的table
        2.具有弱引用value的table
        3.同时具有弱引用key和弱引用value的table
    无论是哪种类型的弱引用table,只要有一个key或value被回收了
    那么他们所在的整个条目都会从table中删除
    table的弱引用类型通过其元表中的__mode字段来决定,这个字段是一个字符串
       1.__mode字段中如果包含"k"则是key的弱引用
       2.__mode字段中如果包含"v"则是value的弱引用
       3.__mode字段中包含"k"和"v"则是key、value的弱引用
            a={}
            b={__mode="k"}
            setmetatable(a,b)    --table a的key就是弱引用
            key={}               --创建第一个key 
            a[key]=1
            key={}               --创建第二个key
            a[key]=2
            collectgarbage()     --强制进行一次垃圾收集 
            for k,v in pairs(a) do print(v) end
            --> 2
    第二次key={}会覆盖第一个key,这时再没有对第一个key的引用了,所以会回收
    第二个key由于还被变量key引用,所以不会回收
    lua只会回收用弱引用table中的对象
    如果key是number、boolean、string则不会回收,所以上例中用table来当key
    可以使用弱引用table来实现缓存等机制,热数据不会被回收,不用的数据自动释放

对于弱引用v来说,下面这段代码可以说明问题
lua程序设计(4) - snoopyxdy - snoopyxdy的博客