【发布时间】:2012-03-01 04:54:21
【问题描述】:
一直在看一些Lua源码,经常在文件开头看到这样的东西:
local setmetatable, getmetatable, etc.. = setmetatable, getmetatable, etc..
他们是否只将函数本地化以让 Lua 在经常使用时更快地访问它们?
【问题讨论】:
一直在看一些Lua源码,经常在文件开头看到这样的东西:
local setmetatable, getmetatable, etc.. = setmetatable, getmetatable, etc..
他们是否只将函数本地化以让 Lua 在经常使用时更快地访问它们?
【问题讨论】:
本地数据在堆栈中,因此它们确实可以更快地访问它们。但是,我严重怀疑 setmetatable 的函数调用时间实际上对于某些程序来说是一个重大问题。
以下是可能的解释:
防止污染全球环境。模块的现代 Lua 约定是不让它们直接将自己注册到全局表中。他们应该建立一个本地函数表并返回它们。因此,访问它们的唯一方法是使用局部变量。这迫使许多事情:
一个模块不能意外覆盖另一个模块的功能。
如果模块不小心这样做了,模块返回的表中的原始函数仍然可以访问。只有使用local modname = require "modname",您才能保证准确且仅获得该模块公开的内容。
包含其他模块的模块不能相互干扰。您从require 返回的表始终是模块存储的内容。
阅读“local 变量的访问速度更快”的人过早地进行了优化,然后决定让一切都变得local。
一般来说,这是一种很好的做法。好吧,除非是因为 #2。
【讨论】:
除了尼可波拉斯的回答,我想补充第三点:
如果函数已从沙箱中排除,并且代码是从沙箱中加载的,则它将无法工作。但是如果先加载代码,沙箱就可以调用加载的代码,并能够从沙箱中排除setmetatable等。
【讨论】:
我这样做是因为它可以让我看到我的每个模块使用的功能
此外,它还可以保护您免受他人在全球环境中更改功能的影响。 这是一个免费的(过早的)优化是一个奖励。
【讨论】:
另一个微妙的好处:它清楚地记录了模块导入了哪些变量(函数、模块)。如果你使用 module 语句,它会强制执行这样的声明,因为全局环境被替换(所以全局变量不可用)。
【讨论】: