Lua weak表

之前写过一篇博客专门介绍了weak表:Lua弱引用表-CSDN博客,这两天阅读了《programming in lua》后有了些新的体会,在这里只做一些之前没有了解的补充内容。

定义

Lua 自动进行内存的管理。程序只能创建对象(表,函数等),而没有执行删除对象的函数,相反,Lua会自动删除那些失效的对象。垃圾收集器只能在确认对象失效之后才会进行收集;它是不会知道你对垃圾的定义的。类似于任何在全局变量中声明的对象,都不是 Lua 认为的垃圾,即使你的程序中根本没有用到他们。Lua weak表就是为这而诞生的:

Weak 表是一种用来告诉Lua一个引用不应该防止对象被回收的机制。一个weak引用是指一个不被Lua认为是垃圾的对象的引用。如果一个对象所有的引用指向都是weak,对象将被收集,而那些weak引用将会被删除。Lua通过weak tables来实现weak引用:一个 weak tables 是指所有引用都是weak的table。这意味着,如果一个对象只存在于 weak tables 中,Lua 将会最终将它收集。

表的弱引用性通过其__mode来定义。 表有keys和values,所以weak也分key weak和value weak。如若key是weak属性的,则__mode = "k";如若value是weak属性的,则__mode = "v";如若两者都是,则__mode = "kv"。如下示例所示:

a = {}
setmetatable(a, {__mode = "k"})
key = {} -- creates first key 
a[key] = 1
key = {} -- creates second key 
a[key] = 2
collectgarbage() -- forces a garbage collection cycle 
for k, v in pairs(a) do print(v) end
--> 2 

记忆函数

上篇博客有讲,这里不作过多介绍,简要概括就是可以维护一个weak table存储数据信息,其他地方需要用到时缓存并返回相应信息,下一次垃圾回收会自动清理在这个weak table外再也没有用到的table里的数据信息。

关联对象属性

其实就是维护一个weak table,以对象为key,返回对象的属性信息作为value。与记忆函数不同的是,记忆函数的value是weak的,而关联对象属性的weak table的key是weak的。

weak table的应用

在书里提到访问table域默认值的方法,都分别用到关联对象属性和记忆函数:

local defaults = {} 
setmetatable(defaults, {__mode = "k"})
local mt = {__index = function (t) return defaults[t] end}
function setDefault (t, d)
    defaults[t] = d
    setmetatable(t, mt)
end

local a = {1,2}
setDefault(a,4)
print(a[3]) --4
local metas = {} 
setmetatable(metas, {__mode = "v"})
function setDefault (t, d)
    if metas[d] == nil then
        metas[d] = {__index = function () return d end}
    end
    setmetatable(t,metas[d])
end

local a = {1,2}
setDefault(a,4)
print(a[3]) --4

前者和后者相比,后者更适用于多个table同时有多个相同的默认值的情况,前者更适用于多个不同默认值的情况。但是两者对默认值的垃圾回收均可在原table回收之后进行。

你可能感兴趣的:(lua,开发语言)