为什么虽然不是原型但还是一样table

Why is it the same table even though it is not a prototype

我有这个代码:

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 模块模式。人们在谈论工厂功能时通常抱怨的是内存占用。 因为 oq 只是分配,当然它们具有不同的 translate() 功能,我假设。 然而我被证明是错误的:

function: 0x7fcdbe600d50        function: 0x7fcdbe600d50        function: 0x7fcdbe600d90 

这是为什么?这怎么可能?我假设 o.translateq.translate 是不同的函数,但是它们是相同的...

How can this even be? I assumed to be o.translate and q.translate to be different functions, however they are the same...

通常您是正确的,但是 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 为每个调用创建和 returns 一个不同的 rect table,但字段 rect.translate 被分配了相同的匿名由于此优化,函数作为 lua 值。

另见