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

时间:2015-02-12 23:37:15

标签: lua

Roberto Ierusalimschy在Lua(第3版)中的编程中声明

  

Lua中常见的习语是

     

local foo = foo

     

此代码创建一个本地代码   变量foo,并使用全局值初始化它   变量foo。 (本地foo仅在其后才可见   声明。)当块需要保留时,这个习惯用法很有用   foo的原始值,即使稍后某些其他功能发生变化   全球foo的价值;它还加快了对foo的访问速度。

有人可以更详细地解释一下并提供一个简单的例子吗?

目前,我能想到的唯一用途就是管理与全局变量具有相同名称的局部变量(在给定的块中),以便在块之后保持全局变量不变。 / p>

一个例子:

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)

给出相同的结果。所以我的解释似乎并不成立。

4 个答案:

答案 0 :(得分:3)

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

更深入:Why are local variables accessed faster than global variables in lua?

答案 1 :(得分:2)

包装全球:

do
  local setmetatable = setmetatable
  function _ENV.setmetatable(...)
    -- Do your thing
    return setmetatable(...)
  end
end

通过使用本地而不是在globals-table(这是一个本地顺便说一句)中进行查找来减少开销。:

local type = type
for k, v in next, bigtable do
  if type(v) == "string" then
    -- Do one thing
  else
    -- Do other thing
  end
end

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:2)

我认为你无意中分裂了头发。

local bar = math.log10(bar)

在精神上基本上与local bar = bar相同,但是我们声称成语是local bar = a(bar)没那么有用,因为我们可能希望以某种方式处理本地而不是传递它首先是一个函数 - 例如将它附加到某物上。

这一点是我们想要引用本地bar,就像你说的那样,不完全是如何完成从全局到本地的转换。