关于“;本地foo=foo”;Lua中的成语

关于“;本地foo=foo”;Lua中的成语,lua,Lua,Roberto Ierusalimschy在《Lua编程》(第三版)中指出 Lua中的一个常见习语是 localfoo=foo 此代码创建一个本地 变量,foo,并使用全局 变量foo。(本地foo仅在其 声明。)当块需要保留时,这个习惯用法很有用 foo的原始值,即使以后某些其他函数发生更改 全局foo的值;它还加快了对foo的访问 有人能更详细地解释一下并提供一个简单的例子吗? 目前,我能想到的这个习惯用法的唯一用途是管理与全局变量同名的局部变量(在给定块中),这样全局变量在块后保持不变 例

Roberto Ierusalimschy在《Lua编程》(第三版)中指出

Lua中的一个常见习语是

localfoo=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)
这给出了同样的结果。因此,我的解释似乎不成立。

包装全球:

do
  local setmetatable = setmetatable
  function _ENV.setmetatable(...)
    -- Do your thing
    return setmetatable(...)
  end
end
通过使用本地表而不是在全局表(这是一个本地btw)中进行查找来减少开销:


解释是正确的;我不知道你为什么对你的例子不满意。给你一个真实的例子:

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

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

我发现这更多地被用作优化技术,而不是保留原始值的方法。使用标准Lua解释器,每个全局变量访问和模块访问都需要查表。另一方面,局部变量在字节码编译时具有静态已知的位置,可以放在VM寄存器中


更深入地说:

我认为你是在无意中挑拨离间

localbar=math.log10(bar)

本质上与
localbar=bar
的精神相同,但我们认为该成语是
localbar=a(bar)
,没有什么用处,因为我们可能希望以某种方式处理局部,而不是先将其传递给函数,例如,将其附加到某个东西上


这一点是,正如您所说,我们希望参考的是本地
,而不是从全局到本地的转换方式。

@PierPaolo,因为更改只会在当前博客中生效。如果不执行
local setfenv=setfenv
,则效果将在当前块之外可见,这在这种情况下是不可取的。
local setfenv = setfenv
if not setfenv then -- Lua 5.2+
  setfenv = function() ..... end
end