0

我在 Lua 中有一个对表进行操作的函数,向表中重复添加条目:

function DoStuff()
    local table = {};

    for i = 1, 1000 do
        local name, value = GetSomething(i);

        if (CheckSomething(name, value))
           table[name] = value
        end;
    end;
end;

我知道这很快;Lua 有一个很好的哈希表算法。但现在我需要拆分我的部分功能,所以我可以对其进行单元测试:

function DoStuff()
    local table = {};

    for i = 1, 1000 do
        local name, value = GetSomething(i);

        --split out checking so it's testable
        table = ParseTheThing(table, name, value); 
    end;
end;

我知道Lua 不支持通过引用传递参数,相反,如果我需要向 my 添加一个项目table,Lua 将制作一个副本,我必须返回该副本:

--Core checking function
function ParseTheThing(table, name, value)
   if (CheckSomething(name, value))
      table[name] = value
   end;

   return table;
end;

所以在我看来,每次我调用CheckSomethingLua 都会创建另一个表,需要进行垃圾收集。

或者可能不是。也许 Lua确实支持通过引用传递参数,我可以简单地调用:

ParseTheThing(table, name, value); 

--Core checking function
function ParseTheThing(table, name, value)
   if (CheckSomething(name, value))
      table[name] = value
   end;
end;

如果我像我所做的那样重构我的代码,Lua 的垃圾收集器会被迫做更多的工作吗?


备注

  • 不要将问题中使用的简化示例与我要问的问题混淆。
  • 我没有任何方法可以测量内存使用情况或集合数量,所以我无法尝试
4

1 回答 1

5

我知道 Lua 不支持通过引用传递参数

“通过引用”一词被重载,引起了很多混乱(尤其是在Java 世界中,我看到人们拒绝承认其中一个含义甚至存在)。

通过引用传递可能意味着:

  1. 传递对象在内存中的位置,而不是对象本身。这就是C 中“通过引用传递”的意思。从这个意义上说,Java确实通过引用传递,Lua 对于它的许多类型(用户数据、表等)也是如此。

  2. 变量的别名,这样对别名的任何修改都会反映在原始变量中。这不仅仅是简单地不传递价值。如果变量包含对象的位置,您可以通过别名分配不同的位置。您不能对 #1 执行此操作,其中您传递对object的引用,而不是变量。这些类型的引用在 C#、C++ 等中受支持,但 C 或 Lua 不支持。

更简单地说:

  1. 传值:调用函数中的对象是被调用函数接收到的对象的副本。
  2. 通过引用传递^1:调用函数中的对象可以被被调用函数修改。
  3. 通过引用传递^2:调用函数中的变量可以被被调用函数修改。

相反,如果我需要在我的表中添加一个项目

只需传递表格——传递的是引用,而不是副本。

于 2012-09-21T23:05:24.320 回答