zoukankan      html  css  js  c++  java
  • lua中的弱表理解

    • 为什么要引入弱表?

        我们都知道,lua具有自动内存管理,我们只管创建对象,无需删除对象,对于不再需要的对象只需要简单置为nil,

    lua会自动删除那些被认为是垃圾的数据;问题就在于,什么对象才是垃圾对象呢?有时候,程序员很清楚的知道某个对象

    是垃圾,而lua却无法发现;

    比如下面的例子:

    t = {};

    --
    使用一个table作为tkey
    key1 = {name = "key1"};
    t[key1] = 1;
    key1 = nil;

    --
    又使用一个table作为tkey
    key2 = {name = "key2"};
    t[key2] = 1;
    key2 = nil;

    for key, value in pairs(t) do
        print(key.name .. ":" .. value);
    end
    --
    强制进行一次垃圾收集
    collectgarbage();

    for key, value in pairs(t) do
        print(key.name .. ":" .. value);
    end

    执行结果如下:

    代码首先创建了一个空表t,接着创建了一个表key1,然后将key1作为t的键,赋值为1,最后将key1置nil;

    key2表也是一样的操作;

    接着程序执行了一次collectgarbage()强制进行一次垃圾回收,此时key1和key2表都被置nil,但是并没有被强制回收,

    换句话说,虽然key1本身为nil,但是他先前指向的内容并没有被删除,因为这个内容被保存在了t中;

    那么,如果我们希望在将key1置为nil时,他指向的内容就被清空,不管t中是否引用了这个内容,该怎么做?

    我们来看如下的代码:

    t = {};
    --
    t设置一个元表,增加__mode元方法,赋值为"k"
    setmetatable(t, {__mode = "k"});

    --
    使用一个table作为tkey
    key1 = {name = "key1"};
    t[key1] = 1;
    key1 = nil;

    --
    又使用一个table作为tkey
    key2 = {name = "key2"};
    t[key2] = 1;
    key2 = nil;

    for key, value in pairs(t) do
        print(key.name .. ":" .. value);
    end
    --
    强制进行一次垃圾收集
    collectgarbage();

    for key, value in pairs(t) do
        print(key.name .. ":" .. value);
    end

    以上代码在创建了表t后,立即将t设置为元表,元表里面有一个__mode字段,值为"k",通过运行结果,我们知道

    在执行collectgarbage()之前,能够输出t中的元素,但是执行垃圾回收之后,就不能再次输出t中的元素的,这是因为

    将表设置为元表后,通过__mode = "k"将其指定为对键的弱引用,也就是说,一旦表中的某个键被垃圾回收,t中会删除

    这个键对应的元素;

    • 三种形式的弱引用

      lua中提供了以下三种形式的弱引用:

    (1)key值弱引用,也就是刚刚上面提到的那种形式的弱引用,只要其他地方没有对key值得引用,那么table自身

    的这个字段也会被删除,设置方法:setmetatable(t, {__mode = "k"});

    (2)value值弱引用,类似的,只要其他地方没有对value值得引用,table的这个value所在的字段也会被删除,

    设置方法:setmetatable(t, {__mode = "v"});

    (3)key和value弱引用,规则一样,只要key或者value中一个在其他地方没有引用,table中对应的字段就被

    删除,设置方法:setmetatable(t, {__mode = "kv"});

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    MongoDB数据类型
    Redis数据类型
    RHEL7 CentOS7 检查查看精简指令
    Linux命令:查看登录用户
    JavaScript错误之:Uncaught ReferenceError: $ is not defined
    Linux下因为系统编码问题造成乱码的解决办法
    Linux系统下的程序开发之:命名规范
    优化php代码
    Git工具:Widows下的使用(提交到Github)
    MongoDB
  • 原文地址:https://www.cnblogs.com/skiing886/p/7762235.html
Copyright © 2011-2022 走看看