声明Lua函数并使用正确的名称引用

以下是三个不同的 Lua 脚本,它们在函数作用域方面的区别是什么?这会如何影响需要在其他 Lua 脚本中 require 'calculator' 的需要?在 LuaState.getGlobal(function_name) 中如何引用?它的正确函数名称是什么?此外,对于这些声明方式的优缺点有什么评论。

A) Calculator.lua

function foo(n)
   return n+1;
end

B) Calculator.lua

calc= {}
function calc.foo(n)
  return n+1;
end

C) Calculator.lua

function foo(n)
   return n+1;
end
function calculator()
   calc = {}
   calc.foo=foo
   return calc
end

原文链接 https://stackoverflow.com/questions/8622737

点赞
stackoverflow用户734069
stackoverflow用户734069

我不知道你对这些脚本的“范围”是什么意思。这些脚本的确切作用取决于它们如何被执行。你可以给它们提供不同的环境,从而改变它们所认为的“全局变量”。

因此,我将根据以下假设解释每个脚本的作用,即您正在使用dofiledostring或类似方法将它们加载到全局环境中。

A)

这将创建一个单一全局变量foo,它是一个函数。

B)

这将创建一个单一全局变量calc,它是一个表格。该表格具有一个条目,键为foo,其值为一个函数。

C)

这将创建两个全局变量。foo是一个函数。calculator也是一个函数。每次调用calculator都会导致全局变量calc被覆盖。calc的新值是一个表格,它具有一个条目,键为foo,它的值是存储在全局变量foo中的原始值的副本。

很难说方法C的“优点”,因为它毫无意义。它创建了两个函数,而不是一个函数,而且第二个函数会不断创建新的表格。

B只是A的“命名空间”范围版本。通常情况下,Lua模块的期望是在包含它们时创建一些表格,以包含该模块中的所有函数,以避免与现有全局状态发生名称冲突。在这方面,B可能更好。但它主要取决于这个脚本将用于什么。

个人而言,对于简单的shell脚本和实用程序脚本,我不会费心去正确地设置模块范围。当我制作一个适当的模块时,我通常使用module Lua函数。

2011-12-24 05:28:59
stackoverflow用户221509
stackoverflow用户221509

不完全是一个答案,但这里是关于语义的注释——在 Lua 中,你不是“声明”一个函数,而是“创建”它。函数会在 function(...) ... end 被执行的时候变得可用。它的可用性取决于你把它存储在哪里。

你必须记住:

function myfun(foo)
    print('foo')
end

只是语法糖,等价于:

myfun = function(foo)
    print('foo')
end

如果你不特别做些什么,myfun 变成了一个全局变量,存储在全局状态中(通过 _G 访问)。如果你在实际调用 function myfun() end 之前说了 local myfun,那么这个函数(实际上是一个 闭包)将存储在局部变量中,只对局部变量的范围可用。

如果你使用 require,它只会找到文件并且加载一次。它不会像隐藏全局变量等那样对模块做任何有意义的处理。因此,如果你在你的模块 Calculator.lua 中写了 function foo() end,那么调用 require 'Calculator' 将在全局 foo 中创建一个函数,你可以使用 LuaState.getGlobal("foo") 访问它。如果你创建了一组函数的表(步骤 B),则必须分两步进行:

L.getGlobal("calc")   -- 将全局变量 "calc"(一个表)推入栈
L.getField(-1, "foo") -- 从表中获取 "foo" 字段
2011-12-24 13:44:59