通过_ENV模拟c++中的'using namespace'

如果我有一个文件'foo.lua':

local foo = {}
foo.add = function(a, b) return a+b end
foo.sub = function(a, b) return a-b end
foo.multiply = function(a, b) return a*b end
return foo

并且在'bar.lua'中我大量使用来自'foo.lua'的代码,我不喜欢一直输入'foo.add()',而是更喜欢在'bar.lua'中只写'add()'。我可以添加以下代码:

local foo = require('foo')
local add, sub, multiply = foo.add, foo.sub, foo.multiply

但是当您包含许多文件中的多个值时,这将开始变得麻烦。在c++中有一种解决方法:

#include <iostream>
using namespace std

在lua中,我认为你可以这样来模拟这个功能:

local foo = require('foo')
setmetatable(_ENV,{__index = foo})

从我所知道的,它尊重作用域,所以像下面的代码都可以正常使用:

实际上,下面的代码不起作用。我通过lua repl运行代码时,当我在lua文件中编写下面的代码片段时,它不能产生期望的结果。

f = function() -- 返回 2
    setmetatable(_ENV,{__index = foo})
    return add(1, 1)
end
add(11) -- 返回 2

我后悔做这件事的原因是什么?(除了适用于“using namespace”的原因)

点赞
用户107090
用户107090

改变全局环境对其他库不是一种礼貌的行为。

尝试反过来实现:

do
  local _ENV = setmetatable(foo, {index = _ENV})
  print(add(1, 1))
end

请注意,add将在foo中解析,而print将在原始的_ENV中解析。

2017-11-13 00:09:05