• Chapter 17_3 table的默认值


    对象属性

      有很多情况需要把有些属性绑定到某个对象,例如:函数与其名称、table的默认值、数组大小等...

    当对象是一个table时,可以通过适当的key将属性存储在这个table中。

    如果对象不是一个table,它就无法保存属性了。

    另外,即使是table,有时也不想将属性存储在原table中。可以使用外部table来关联它们,将对象作为key,对象的属性作为value。

    这个外部table可以保存任意对象的属性,Lua也允许将任何对象作为table的key。

    另外,存储在外部对象中的属性不会干扰其他对象,只要table本身是私有的,这些属性也会是私有的。

      然而,有一个缺陷,当用户将一个对象作为外部table的key时。就引用了它,Lua是无法回收一个作为table key的对象。

    如果这个外部table关联函数和函数名,那么这些函数就永远无法回收。

    可以用弱引用来解决这个问题。该情况使用的是弱引用key,当一个弱引用key没有其他引用时,Lua就回收它。

    table的默认值

      之前在table访问元方法一节最后提到过,用两种方法实现具有非nil默认值的table:一种是弱引用table,一种是备忘录。

    它们其实就是之前讲到的备忘录和对象属性的特殊应用。

    第一种方法:用一个弱引用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

    如果defaults没有弱引用key,它就会使所有具有默认值的table持久存在下去。

    第二种方法:对每种不同的默认值使用不同的元表,不过,只要有重复的默认值,就复用同样的元表。这是备忘录的典型应用:

    local metas = {}
    setmetatable(metas , {__mode = "v"})
    function setDefault(t, d )
        local mt = metas[d]
        if mt == nil then
            mt = {__index = function() return d end}
            metas[d] =  mt     --备忘录
        end
        setmetatable(t , mt)
    end

    这里用到了弱引用value,这样当metas中的元表在不使用时就可以被回收了。

    第一种的做法需要为每个table的默认值(defaults中的一个条目)使用内存。

    第二种的做法需要为每个不同的默认值使用一组内存(一个新table、一个新closure和metas中的一个条目)。

    如果程序上有上千个table和一些默认值,第二种是首选;但是只有很少的table共享几个公用的默认值,就选第一种。

    以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 》

  • 相关阅读:
    ToolbarLayout的使用
    设置NavigationView子布局Menu图片的颜色
    设置RecyclerView显示滚动条(这里演示垂直的滚动条,水平的道理一样)
    在使用ToolBar + AppBarLayout,实现上划隐藏Toolbar功能,遇到了一个坑。
    Android中设置Imageview的图片充满整个布局
    Android透明状态栏设置
    关于NavigationView中item的字体颜色和icon选中状态颜色
    dp、sp 、 px之间的相互转化的工具类
    今天使用JNI时,出现了一个错误:java.lang.UnsatisfiedLinkError : dlopen failed: library //dlopen打开失败
    kubernetes的几个概念
  • 原文地址:https://www.cnblogs.com/daiker/p/5886043.html
Copyright © 2020-2023  润新知