为什么要将全局的Lua函数转换为局部函数?

我一直在看一些 Lua 源代码,我经常在文件开头看到像这样的东西:

local setmetatable, getmetatable, etc.. = setmetatable, getmetatable, etc..

它们只是将函数变为局部函数让 Lua 在经常使用时更快地访问它们吗?

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

点赞
stackoverflow用户734069
stackoverflow用户734069

本地数据保存在栈中,因此访问速度更快。但是,我认为setmetatable函数调用时间对于某些程序来说并不是一个重要问题。

以下是可能的解释:

  1. 防止全局环境的污染。现代 Lua 模块的约定是不直接将它们注册到全局表中。它们应该建立一个包含函数的本地表并返回它们。因此,唯一访问它们的方法是使用本地变量。这就强制执行了以下一些事项:

    1. 一个模块不能意外地覆盖另一个模块的函数。

    2. 如果一个模块意外地这样做,模块返回的原始函数仍将可用。唯一的方法是使用 local modname = require "modname",您才可以保证得到模块暴露的确切和唯一的东西。

    3. 包含其他模块的模块不能相互干扰。require 返回的表始终是模块存储的内容。

  2. 有人读了“ local变量访问更快”,然后决定将所有东西都声明为 local 而进行的过早优化。

总的来说,这是一个很好的实践。除非是因为第2点。

2012-02-08 17:52:54
stackoverflow用户282536
stackoverflow用户282536

我这么做是因为它允许我看到每个模块使用的函数

另外,它可以保护你免受他人更改全局环境中的函数。

这是一个免费(过早的)优化,是一个额外的好处。

2012-02-08 18:24:20
stackoverflow用户596285
stackoverflow用户596285

除了Nicol Bolas的答案,我还想补充第三点:

  • 加载完成后,它可以使你的代码在一个沙盒环境中运行。

如果函数已经被排除在沙盒之外,且代码从沙盒内部加载,则它将无法正常工作。但如果代码先被加载,沙盒就可以调用已加载的代码并从沙盒中排除setmetatable等函数。

2012-02-09 01:17:38
stackoverflow用户798374
stackoverflow用户798374

另一个微妙的好处:它清楚地记录了该模块导入了哪些变量(函数,模块)。如果您正在使用module语句,则可以强制进行这种声明,因为全局环境将被替换(因此全局变量不可用)。

2012-08-28 12:07:56