我有这段代码:
function createRect(x, y, w, h)
local rect = {
type = "rect",
x = x,
y = y,
w = w,
h = h,
translate = function(rect, vector)
assert(vector.type == "vector2d")
local rect = shapes.createRect(rect.x + vector.x, rect.y + vector.y, rect.w, rect.h)
end,
}
return rect
end
translate = function(rect, vector)
assert(vector.type == "vector2d")
local rect = shapes.createRect(rect.x + vector.x, rect.y + vector.y, rect.w, rect.h)
end
local o = createRect(2,3,4,5)
local q = createRect(2,3,4,5)
print(o.translate, q.translate, translate)
这是一些非常简单的代码,用于测试Lua中的测试工厂函数,非常让人联想到JS模块模式。在谈论工厂功能时,人们通常会抱怨的是内存占用。
由于o
和q
刚刚分配,因此我们假设它们具有不同的translate()
函数。
但事实证明我错了:
function: 0x7fcdbe600d50 function: 0x7fcdbe600d50 function: 0x7fcdbe600d90
这是为什么?怎么会这样呢?我假设o.translate
和q.translate
是不同的功能,但它们是相同的......
答案 0 :(得分:5)
这怎么可能呢?我假设
o.translate
和q.translate
是不同的功能,但它们是相同的......
通常你是对的,但是Lua 5.2引入了一个优化,如果满足某些条件,可以缓存匿名函数。具体来说,如果它引用的值在构造之间没有变化,那么该匿名函数的第一个创建实例将被重用。
在repl.it,Lua 5.1中运行您的示例,将其显示为一个可能的输出:
function: 0xb81f30 function: 0xb81f00 function: 0xb82ca0
但是在melpon.org/wandbox下运行它,Lua 5.2+,显示:
function: 0x14f0650 function: 0x14f0650 function: 0x14efb40
在您的示例中,createRect
为每个调用创建并返回不同的rect
表,但由于此优化,字段rect.translate
被分配了与lua值相同的匿名函数。
另见