【问题标题】:Lua: setfenv() vs. _ENVLua:setfenv() 与 _ENV
【发布时间】:2012-08-18 19:07:40
【问题描述】:

Lua 从 setfenv() 切换到 _ENV 有什么大不了的?

在各种“最新消息”来源中,这一举措被认为是 Lua 5.1 和 5.2 版本之间最重要的变化之一。

但是,PIL 和其他地方给出的示例可以精简为以下内容:

-- Lua 5.1                   -- Lua 5.2
function myfunc()            function myfunc()
    setfenv(1, {})               _ENV = {}
end                          end

到目前为止,我们在这里获得的是我们已经保存了五个击键。 (我相信情况与 C 方面没有太大区别。)此外,如果我做对了,setfenv() 既可以从函数外部也可以从函数内部使用,而 _ENV 只能从函数的内部。 (当然,当使用 C API 时,可以直接访问 upvalues。)从我写的内容来看,5.2 的方法似乎不太灵活。

罗伯托在他的The Novelties of Lua 5.2 中写道:

“作为语法糖,它比旧环境简单得多”

简单在哪里?我忽略了什么?

我相信这个主题值得更好地处理,它在 5.2 用户手册中给出。

【问题讨论】:

    标签: lua


    【解决方案1】:

    简单在哪里?

    这取决于你如何定义“简单”。

    在 Lua 5.1 中,环境是一个神奇而神秘的设置,不同于系统中的任何其他设置。它没有明确的位置,只能使用标准库功能进行设置。

    在 Lua 5.2 中,环境是一个变量,就像其他的一样。它有一个您可以使用的名称。所以它更简单,因为它更明显发生了什么。

    此外,在 Lua 5.1 中,函数的环境可以动态更改。

    在 Lua 5.2 中,除了直接上值操作之外,一旦一个函数有了一个环境,那就是它将永远拥有的环境。函数的环境是继承的,像普通的local 变量一样在词法范围内。所以如果你看你的代码,你可以很容易地看到一个函数所处的环境。如果在该函数的创建范围内没有local _ENV,那么环境应该是块的环境(由load 打电话)。

    【讨论】:

      【解决方案2】:

      据我所知,Lua 5.2 环境的主要缺陷是它们不能在外部设置——也就是说,你不能说setfenv(func, {})。在我看来,这是一个巨大的失败。它确实比 Lua 5.1 的环境更简单,但不是很好。

      【讨论】:

      • 确实如此。但是,能够在外部为 Lua 函数设置环境确实非常重要。
      • 您可以在外部使用 debug.setupvalue 进行设置。如果一个函数访问其环境,它将继承其父级的 _ENV 作为上值。这是 setfenv 和 getfenv 的替换:lua-users.org/lists/lua-l/2010-06/msg00313.html
      • 您不应将调试功能用于常规功能。
      • 在加载后更改函数的环境不是“常规功能”;它打破了函数封装的概念。所有设置_ENV都OK的情况都不需要调试库。
      • 我发现它是最有用的东西,在 Lua 5.1 中,它是常规功能。不是每个函数都应该被封装。
      猜你喜欢
      • 2012-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-26
      • 2011-04-16
      • 2020-04-14
      • 2012-05-17
      相关资源
      最近更新 更多