Weak表是一种用来告诉Lua一个引用不应该防止对象被回收的机制。
一个weak引用是指一个不被Lua认为是垃圾的对象的引用。
一个对象所有的引用指向都是weak,对象将被收集,而那些weak引用将会被删除。
表的weak性由他的metatable的__mode域来指定的。key和value只要有任何一个被回收,整个key-value都将消失。

  1. a, b = {}, {}
  2. setmetatable(a, b)
  3. b.__mode = "k" -- a是一个keyweak引用的weak
  4. key = {} -- lua不会自动回收全局变量,只能显示的key=nil删除。
  5. a[key] = 1
  6. key = {}
  7. a[key] = 2 -- 被覆盖的key将被回收。也就是第一个key:1键值对将消失。
  8. a[{}] = 1 -- 将别回收
  9. a[1] = 2 -- 数值型的key不会被回收。
  10. a["a"] = 2 -- string型的key不会被回收。
  11. collectgarbage() -- forces a garbage collection cycle

记忆函数

常见的,我们用一个table来缓存数据,但是如果缓存的数据过了段时间在外部没有被使用了(引用),我们可以把这部分缓存给清理掉。weak表的特性就可以很好的满足。

  1. ------------------缓存编译的chunk块------------------
  2. local results = {}
  3. setmetatable(results, {__mode = \"v\"})
  4. function mem_loadstring (s)
  5. if results[s] then
  6. return results[s]
  7. else
  8. local res = loadstring(s)
  9. results[s] = res
  10. return res
  11. end
  12. end
  13. ------------------缓存RGB色值------------------
  14. local results = {}
  15. setmetatable(results, {__mode = \"v\"}) -- make values weak
  16. function createRGB (r, g, b)
  17. local key = r .. \"-\" .. g .. \"-\" .. b
  18. if results[key] then return results[key]
  19. else
  20. local newcolor = {red = r, green = g, blue = b}
  21. results[key] = newcolor
  22. return newcolor
  23. end
  24. end

带默认值的表

它们都有相似的复杂性和相似的性能。第一种方法需要在每个默认值的tables中添加一些文字(一个默认的入口)。第二种方法需要在每个不同的默认值加入一些文字(一个新的表,一个新的闭包,metas中新增入口)。所以,如果你的程序有数千个tables,而这些表只有很少数带有不同默认值的,第二种方法显然更优秀。另一方面,如果只有很少的tables可以共享相同的默认vaules,那么你还是用第一种方法吧。

  1. -- 一个weak table保存所有对象的默认值,key是弱引用
  2. -- key:对象,value:默认值
  3. --defaults = {
  4. -- [object] = default --object weak
  5. --}
  6. local defaults = {}
  7. setmetatable(defaults, {__mode = \"k\"})
  8. local mt = {__index = function (t) return defaults[t] end}
  9. function setDefault (t, d)
  10. defaults[t] = d
  11. setmetatable(t, mt)
  12. end
  13. --metas = {
  14. -- [default] : metatable --metatable weak
  15. -- }
  16. local metas = {}
  17. setmetatable(metas, {__mode = \"v\"})
  18. function setDefault (t, d)
  19. local mt = metas[d]
  20. if mt == nil then
  21. mt = {__index = function () return d end}
  22. metas[d] = mt -- memoize
  23. end
  24. setmetatable(t, mt)
  25. end