关于 Lua 中的“local foo = foo”习语的解释

在《Lua 程序设计》第3版中,Roberto Ierusalimschy 表示 Lua 中的一个常见用法是:

local foo = foo

这样的代码创建了一个局部变量 foo,并将全局变量 foo 的值初始化为它的值。 (仅在其声明之后局部 foo 可见。) 这个惯用法在块需要保留 foo 的原始值的情况下很有用,即使后来某个函数更改了全局 foo 的值,它也可以加速访问 foo

能否有人提供更详细的解释并提供一个简单的例子?

目前,我能想到的这种惯用法的唯一用途是管理与全局变量同名的局部变量(在给定块中),以便在块后全局变量保持不变。

举个例子:

foo = 10
do
   local foo = foo
   foo = math.log10(foo)
   print(foo)
end
print(foo)

这将输出:

1
10

但可以完全不使用这种惯用法来实现相同的功能:

bar = 10
do
   local bar = math.log10(bar)
   print(bar)
end
print(bar)

它会得到相同的结果。所以我的解释似乎并不正确。

点赞
用户3204551
用户3204551

将全局变量进行封装:

do
  local setmetatable = setmetatable
  function _ENV.setmetatable(...)
    -- 执行代码
    return setmetatable(...)
  end
end

通过使用本地变量来减少开销,而不是在全局表中查找(该表也是一个本地表):

local type = type
for k, v in next, bigtable do
  if type(v) == "string" then
    -- 执行一些操作
  else
    -- 执行其他操作
  end
end
2015-02-12 23:58:31
用户1442917
用户1442917

解释是正确的;我不确定为什么您不满意您的示例。为了给您一个真实的例子:

local setfenv = setfenv
if not setfenv then -- Lua 5.2+
  setfenv = function() ..... end
end

另一个原因是保留该值目前的状态,使得其他使用该值的函数(在文件或模块中)对该值有相同的期望。

2015-02-12 23:58:35
用户768535
用户768535

我看到这种方法更多用作优化技巧,而不是维护原始值的方法。在标准 Lua 解释器中,每次访问全局变量和模块都需要进行表查找。另一方面,局部变量在字节码编译时具有静态已知位置,可以放置在VM寄存器中。

更深入地说:为什么在Lua中访问局部变量比访问全局变量快?

2015-02-12 23:58:44
用户742467
用户742467

我认为你在无意中在拿些小事纠结。

local bar = math.log10(bar)

从本质上讲,这与local bar = bar是一样的,但是如果我们声称使用一个函数a(bar)是惯用语,那么它就不那么有用,因为我们可能希望以某种方式处理本地变量而不是先将它传递到函数中,例如附加到某些内容。

这个观点是,我们想要引用本地变量bar,正如你所说的那样,而不是确切地了解从全局变量转换为本地变量的过程。

2015-02-13 00:06:00