Lua程序设计(六十)

瞬表 (Ephemeron Table)

有一种棘手的情况是,一个具有弱引用键的表中的值又引用了对应的键。

这种情况比看上去的更加常见。一个典型的示例是常量函数工厂( constant-function factory)。 这种工厂的参数是一个对象,返回值则是一个被调用时返回传入对象的函数:

function factory (o)
	return ( function () return o end)
end

这种工厂是实现记忆的一种很好的手段,可以避免在闭包已经存在时又创建新的闭包。

do
	local mem = {}
	setmetatable(mem, {__mode = "k"})
	function factory (o)
		local res = mem[o]
		if not res then
			res = (function () return o end)
			mem[o] = res
		end
		return res
	end
end	

需要注意的是,表mem中有一个与对象关联的值(常量函数)回指了它自己的键(对象本身)。虽然表中的键时弱引用的,但是表中的值却不是弱引用的。从一个弱引用表的标准理解看,记忆表中并没有任何东西会被移除。由于值不是弱引用的,所以对于每一个函数来说都存在一个强引用。每一个函数都指向其对应的对象,因而对于每一个键来说都存在一个强引用。因此,即使有弱引用的键,这些对象也不会被回收。

大多数人希望一个表中的值只能通过对应的键来访问。

Lua语言通过瞬表的概念来解决上述问题。在Lua语言中,一个具有弱引用键和强引用值的表是一个瞬表。在一个瞬表中,一个键的可访问性控制着对应值的可访问性。更确切地说,考虑瞬表中的一个元素(k,v),指向v的引用只有当存在某些指向k的其他外部引用存在时才是强引用,否则,即使v(直接或间接地)引用了k, 垃圾收集器最终还是回收集k并把元素从表中移除。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值