在Lua 5.1中为相同函数设置不同的环境。

我想在Lua 5.1(luajit)中将相同的函数设置为不同的环境:

f = function() print(a) end
b = setfenv(f, { a = 1, print = print })
c = setfenv(f, { a = 2, print = print })

我希望 b()c()输出不同的数字。

我通过基于string.dump创建新的函数 chunks,并将env绑定到它们上,来实现了一种方式,但是否有更好、更优雅的方法呢?或者,函数是否可以根据某些条件具有不同的upvalues?

function bind_env(f, env)
  return setfenv(loadstring(string.dump(f)), env)
end

谢谢!

点赞
用户869951
用户869951

一个函数的上值由其词法作用域确定:

function test(a, b)
   function func(x) -- 看到 x,a 和 b
       print(a*x+b)
   end
   return func
end

f12 = test(1, 2) -- x+2
f23 = test(2, 3) -- 2x+3

f12(4)
f23(4)

最后两行输出 6 和 11。严格来说,test(a,b) 为每个 a 和 b 返回一个不同的函数对象,但从概念上来说,它返回同一函数的不同闭包(相同的字节码序列)。因此,如果你有:

function func(a)
    return function() print(a) end
end

你可以为每个 a 定义不同的闭包:

b = func(1) -- a=1
c = func(2) -- a=2

但是注意 b==c 为 false,但这可能是件好事。

2014-09-02 03:41:28