【问题标题】:Explanation about “local foo = foo” idiom in Lua关于 Lua 中“local foo = foo”成语的解释
【发布时间】:2023-03-10 10:16:01
【问题描述】:

Roberto Ierusalimschy 在 Programming in Lua (3rd Ed.) 中指出

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)

给出相同的结果。所以我的解释似乎站不住脚。

【问题讨论】:

    标签: lua


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • @PierPaolo,因为更改只会在当前博客中生效。如果你不做local setfenv = setfenv,效果将在当前块之外可见,这在这种情况下是不可取的。
      【解决方案3】:

      包装一个全局:

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

      通过使用本地而不是在全局表中进行查找来减少开销(顺便说一句,这是一个本地):

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

      【讨论】:

        【解决方案4】:

        我认为你是无意的。

        local bar = math.log10(bar)

        在本质上与local bar = bar 基本相同,但我们声称该成语是local bar = a(bar) 的用处不大,因为我们可能希望以某种方式处理本地而不是先将其传递给函数——例如将其附加到某物上。

        这点是我们要引用本地的bar,就像你说的,不完全是怎么从全局到本地的转换。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-18
          • 1970-01-01
          • 2023-03-17
          • 1970-01-01
          相关资源
          最近更新 更多