我有许多函数在字符串上运行,以从这些字符串中提取有趣的属性。许多这些函数调用的一个特定函数非常昂贵,并最终生成一个值表:
local function expensive(s)
local t = nil
return function()
if not t then
t = {}
-- some expensive operations with s which add items to t
end
return t
end
end
local function fn1(s)
local t = expensive(s)
-- some other fast operations using t and s
end
local function fn2(s)
local t = expensive(s)
-- some other fast operations using t and s
end
local s1, s2 = 'a', 'b'
fn1(s1) -- should create the 't' table for s1
fn1(s2) -- should create the 't' table for s2
fn2(s1) -- should not create the 't' table again for s1
fn1(s2) -- should also not create the 't' table again for s2
我怎样才能使昂贵的函数为每个字符串创建一次表,在任何一种情况下返回表?我宁愿没有将表暴露给全局环境。我认为这可能是通过巧妙地使用闭包来实现的,但我不太了解这个结构。
答案 0 :(得分:4)
local cache = {}
local function expensive(s)
local t = cache[s]
if not t then
t = {}
-- some expensive operations with s which add items to t
cache[s] = t
end
return t
end
答案 1 :(得分:2)
您可以使用“memoization”来缓存函数返回的值,具体取决于参数。您可以阅读a chapter on it in Programming in Lua并使用其中一个为您完成工作的记忆模块,例如memoize。
有关相关的有趣解决方案,请参阅此SO answer。
答案 2 :(得分:1)
Egor的回答将完成这项工作,但整个文件都可以访问cache
表。要隐藏它,您有几个选择。第一个是简单的do / end块。
local expensive
do
local cache = {}
expensive = function (s)
local t = cache[s]
if not t then
t = {}
-- some expensive operations with s which add items to t
cache[s] = t
end
return t
end
end
另一个是自动执行功能。
local expensive = (function ()
local cache = {}
return function (s)
local t = cache[s]
if not t then
t = {}
-- some expensive operations with s which add items to t
cache[s] = t
end
return t
end
end)()
自执行功能的优点是您只需要定义expensive
函数名称一次,但缺点是它比do / end块更难读。否则他们几乎是一样的。