A weak table is a table whose elements are weak references. A weak reference is ignored by the garbage collector. In other words, if the only references to an object are weak references, then the garbage collector will collect this object.
A weak table can have weak keys, weak values, or both. A table with weak keys allows the collection of its keys, but prevents the collection of its values. A table with both weak keys and weak values allows the collection of both keys and values. In any case, if either the key or the value is collected, the whole pair is removed from the table. The weakness of a table is controlled by the __mode field of its metatable. If the __mode field is a string containing the character 'k', the keys in the table are weak. If __mode contains 'v', the values in the table are weak.
After you use a table as a metatable, you should not change the value of its __mode field. Otherwise, the weak behavior of the tables controlled by this metatable is undefined.
在lua中,像table,userdata,function这些类型的值都是引用传递,通过引用计数来判断是否收掉对象,而弱引用(weak reference)会被垃圾回收器忽略.weak table就是它的元素是弱引用的,一个元素(键值对)可能键是弱引用,也可能值是弱引用的,也可能都是弱引用, 这个特性是通过弱表的metatable的__mode的值来设置的,特别有意思的是,当弱表中一个键值对,它的键或值关联(引用/指向)的那个对象被垃圾回收器回收的时候,这个键值对会从弱表中被自动删除掉.这是个很重要的特点.
那么弱表到底有什么用呢? 在lua的wiki中有一篇使用userdata的例子 ,其中就很巧妙的用到了弱表,原文地址
http://lua-users.org/wiki/CppBindingWithLunar
这篇文章介绍了如何通过userdata绑定c++对象到脚本中
fulluserdata能够设置metatable,也就能模拟出对象的效果出来,对一个C++的类的对象实例来说,push到脚本中,一般是创建了一个userdata,文章中用弱表避免了同一个对象实例(指针) push到脚本中,多次创建userdata的问题.
换句话来说,如果C++对象的生存周期是靠lua的垃圾回收来控制的话(userdata被回收时,调用元表的__gc方法,__gc方法中析构c++对象),一个C++对象只能有一个唯一的userdata. 在userdata的metatable中创建一个值是弱引用的弱表,用C++对象指针做键,每次push c++对象的时候,就去用指针值查弱表,如果有,就push那个userdata,没有就创建, 同时,当userdata是被弱引用的,当被垃圾回收掉的时候,弱表中它所在的键值对自动被销毁了.