Lua程序设计(五十九)

回顾具有默认值的表

如何实现具有非nil默认值的表。我们将要看到的两种实现这个默认值的技术是对偶表示和记忆这两种通用技术的特例。

第一种解决方案中,我们使用一个弱引用表来映射每一个表和它的默认值:

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[t]来表示t.default.如果表defaults没有弱引用的键,那么具有默认值的表就会永远存在下去。

第二种解决方法中,我们对不同的默认值使用了不同的元表,在遇到重复的默认值时会复用相同的元表。这是记忆技术的一种典型应用:

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

在这种情况下,我们使用弱引用的值是的不再被使用的元表能够被回收。

第一种实现需要为每个具有默认值的表(表defaults中的一个元素)分配几个字节的内存, 而第二种实现则需要为每个不同的默认值分配若干内存(一个新表,一个新闭包和表metas中的一个元素。)因此,如果应用中上千个具有少量不同默认的值,那么第二种实现更为适合,不过如果只有少量默认共享的值,那么就应该选择第一种实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值