【问题标题】:Lua environments when calling function within setfenv function在 setfenv 函数中调用函数时的 Lua 环境
【发布时间】:2016-01-11 10:54:50
【问题描述】:

所以我有一个 Lua 脚本,我在其中设置函数的环境并定义我在环境中可用的其他函数。问题是,当我调用我在setfenv 上执行的函数时,它在环境中调用的任何函数都使用全局_G 环境来查找值,而不是我在调用初始函数时设置的环境。我已经复制了以下问题:

> function f() print(t) end
> t = 5
> f()
5
> env = {}
> env['print'] = print
> env['t'] = 7
> env['f'] = f
> setfenv(f, env)
> f()
7
> setfenv(f, _G)
> f()
5
> function g() f() end
> g()
5
> setfenv(g, env)
> g()
5

有没有办法让环境传播到所有调用,而不必对我要添加到env 的每个函数执行setfenv(基本上,这样示例中对g() 的最后一次调用将返回7 而不是5)?

使用 Lua 5.1。

【问题讨论】:

  • Lua 5.1 中的函数环境不是由函数调用继承的(您必须在调用该函数之前手动调用setfenv 才能解决您的问题)。新的环境系统(从 5.2 开始,使用 _ENV)使正确的继承变得容易。
  • 有没有办法在 5.1 中复制这种行为?

标签: lua lua-5.1


【解决方案1】:

你可以编写一个函数,让它在每次调用时自动改变自己的环境

-- This code works on Lua 5.1, 5.2, 5.3
local getfenv = getfenv or function() end
local setfenv = setfenv or getfenv

a = 1

function f(env)
   local _ENV = env or getfenv(2) or _ENV; setfenv(1, _ENV)
   print(a)
end

env = { a = 2, print = print }

-- inherit environment for this call
f()    --> 1
-- set special environment for this call
f(env) --> 2
f()    --> 1

如果您只使用 Lua 5.1 并希望始终继承环境,则只需 setfenv(1, getfenv(2))

【讨论】:

    猜你喜欢
    • 2020-05-02
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    • 2018-09-11
    • 2015-03-08
    • 1970-01-01
    • 2016-12-15
    • 2012-10-28
    相关资源
    最近更新 更多