zoukankan      html  css  js  c++  java
  • Lua的weak table

    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
    
  • 相关阅读:
    coalesce搭配nullif使用
    阿里云服务器数据备份到本地
    MSSQL 删除数据库表数据
    MSSQL 删除重复数据
    MSSQL 字段分组拼接
    MySql 字段分组拼接
    获取格式字符串第idx个值及实例
    针对字符串长度超过8000的处理
    【21】责任链模式
    【20】策略者模式(Strategy Pattern)
  • 原文地址:https://www.cnblogs.com/back-to-the-past/p/14916424.html
Copyright © 2011-2022 走看看