ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Lua的weak table

2021-06-21 23:32:26  阅读:186  来源: 互联网

标签:__ mt weak Lua gc table local


Lua的table为table的key和value提供了一种weak的机制,即如果当前的key或/和value不再被除此table以外的任意对象引用时,将被标记为可被lua的垃圾回收器回收的对象。使用weak table,需要设置table的metatable的__mode属性,可以设置为"k","v","kv",分别表示对key还是value进行weak处理。例如:

local t = {}
local mt = { __mode = "kv" }
setmetatable(t, mt)

local x = {}
local y = {}
t[x] = 1
t[1] = y
x = nil
y = nil

collectgarbage()

for k, v in pairs(t) do
    print(k, v)
end

运行后,我们发现t变成了一张空表。不过需要注意这里手动调了一下lua的gc回收,不然可能因为还没触发gc,导致t还是有值的。

另外,weak table的key和value只对object有效,像string和number这样的类型是无法生效的。例如:

local t = {}
local mt = { __mode = "kv" }
setmetatable(t, mt)

local x = "x"
local y = "y"

t[x] = 1
t[1] = y
x = nil
y = nil

collectgarbage()

for k, v in pairs(t) do
    print(k, v)
end

运行之后table还是原来的样子。

lua 5.2 后引入了 ephemeron table 这个特性,这是为了防止循环引用导致无法回收weak table中的key和value设置的。例如:

local t = {}
local mt = { __mode = "kv" }
setmetatable(t, mt)

local x = {}
local y = {}

x.ref = y
y.ref = x

t[x] = 1
t[1] = y

x = nil
y = nil

collectgarbage()

for k, v in pairs(t) do
    print(k, v)
end

从代码可以看出,虽然外界没有地方再去引用table x和table y了,但是这两个table实际上是相互引用的。ephemeron table就是为了解决这个问题而存在的。即,只有weak table的key和value拥有外部的强引用,才不会被回收。这里可以参考云风的这篇博客

有时候,我们希望对象在被gc的时候能够额外做一些事情,这里lua提供了__gc元方法:

local t = {}
t.val = 1
local mt = { __gc = function(t) print("gc val ", t.val) end }
setmetatable(t, mt)

collectgarbage()

for k, v in pairs(t) do
    print(k, v)
end

标签:__,mt,weak,Lua,gc,table,local
来源: https://www.cnblogs.com/back-to-the-past/p/14916424.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有