• 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
    
  • 相关阅读:
    JavaScript 与 Java 是两种完全不同的语言,无论在概念还是设计上。
    JavaScript 是脚本语言
    java String去除两端的空格和空字符
    response.sendRedirect 的功能是地址重定向(页面跳转)
    Java中“|”和“||”用法的区别
    如何居中div?
    DIV居中的几种方法
    table 中的tr 行点击 变换颜色背景
    Html-浅谈如何正确给table加边框
    背景图以拉伸方式(不重复)填充背景
  • 原文地址:https://www.cnblogs.com/back-to-the-past/p/14916424.html
Copyright © 2020-2023  润新知