【问题标题】:In Lua, is there a difference between local functions declared with and without the "local" keyword?在 Lua 中,使用和不使用“local”关键字声明的本地函数之间有区别吗?
【发布时间】:2018-06-26 21:13:06
【问题描述】:

前言:据我所知,网站上的文档并没有真正说明这一点,而且我什至没有找到其他人这个问题,所以我很漂亮确定这两种形式是相同的,但我想知道是否有人知道确定

鉴于此 Lua 代码:

function f()
    function a() ... end
    local function b() ... end
    ...
end

a()b() 之间在功能上有什么区别吗?我说的是性能、访问权限、注意事项等等。最后,它们在运行时是否具有完全相同的底层表示?

我怀疑没有任何区别,但我不确定确定,这让我很烦恼。我知道a()作用域 到封闭函数f(),但我不确定这是否真的使它成为一个局部变量,就事物如何在引擎盖下运行而言。有了b(),我可以确定。

我们从官方文档中知道,我上面对b() 的定义是语法糖:

    local b
    b = function() ... end

我很想相信,即使 my 定义中没有 local 关键字,a() 的最终脱糖定义也将完全遵循该格式,包括 @ 987654331@ 部分。

我只是觉得我无法假设这个。

【问题讨论】:

  • 澄清几点:1)函数是值;只有变量是局部的或全局的。 2) 函数有一个定义表达式(或等效语句),它在执行时创建一个函数值,而不是一个声明。 3) f 或 a 可以是本地的,除非您在编译的块中显示了整个代码。 4) a 不在封闭块的范围内。

标签: lua scope


【解决方案1】:

您的代码块中的function a() end 在函数运行时分配全局a*,而b 仍然是函数的本地。

也许这段代码会更好地说明事情:

function f()
    function a() end
    local function b() end
end
print(a, b) -- nil, nil
f()
print(a, b) -- function: 0xdeadbeef, nil

所以为了避免污染全局环境,还是应该在函数内部使用local


* 除非您在 f 之上的某个其他范围内声明了本地 a,在这种情况下,a 将保留其范围。

【讨论】:

  • a 可能不是全局的。这可能是一个升值。
  • 啊,哇,假设太强了,以至于我什至没有想到在函数运行时是否设置了全局。从全局空间调用 a() 甚至会保留任何赋予 f() 并在 a() 中使用的上值,因为 course 确实如此。干杯,这肯定回答了这个问题,很高兴看到行为实际上是一致的。 :)
  • @EgorSkriptunoff - 啊,你的意思是如果'a'已经存在于封闭函数中?我想这是真的。好点子。
【解决方案2】:

这不是您问题的完整答案,但 Lua 引擎盖下最容易理解的外观是 Lua 的创建者编写的 here。有一些关于局部变量的讨论,但我认为它不能完全回答你的问题。关于“外部本地人”与显式声明的本地人的部分提供了丰富的信息。

编辑: 还有here。我将不得不再次阅读这篇文章,看看它是否回答了你的问题。如果你打败了我,请分享你学到的东西!

【讨论】:

    【解决方案3】:

    就性能而言,局部函数比全局函数快。在大型代码库中,常见的lua 优化技巧是在本地引用中“缓存”全局定义的函数并使用后者。在代码中:

    --file_A.lua
    function performAnExpensiveComputation()
    ...
    end
    

    在你真正想要使用这个函数的文件中:

    --file_B.lua
    require "file_A.lua"
    
    local performAnExpensiveComputation = performAnExpensiveComputation 
    
    local result = performAnExpensiveComputation() --You are now using the locally referenced function
    

    这只是用于optimizelua 变量的技术的一种变体。

    【讨论】:

    • 这真的没有回答我问的问题。
    • 如果您认为我的回答没有帮助,我会收回它。但是,关于性能,我的帖子回答了您在标题中描述的内容“使用和不使用“local”关键字声明的本地函数之间是否有区别?”
    • 这适用于变量,无论它们在任何特定时间持有的值类型如何。
    • @TomBlodget - 我意识到您的回答是善意的,并且 确实 讨论了如果两个定义不同时会出现的差异之一。但是,我的问题的主旨是关于这两个定义是否会有所不同,因为局部函数一开始就隐含地是局部的。正如接受的答案中所述,它们确实有所不同,但简单地告诉我本地函数和全局函数在性能方面的不同是一个更简单的问题的答案,即在本地变量中缓存函数是否值得,我相信这个问题已经在 SE 上被问过很多次了。
    • @AikenDrum 您似乎误认为我是答案作者。但是,针对您的附带观点,您似乎正在从另一种编程语言中导入“本地函数”的概念。 “本地函数是隐式本地的”是不正确的。同样,函数是值。只有变量可以是局部变量,唯一隐含的局部变量是参数。
    猜你喜欢
    • 2010-09-14
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多