这是不可能完全实现的,因为修改local
的值(debug.setlocal
无法定义新的当地人)是不完美的。最好的办法是调整你的环境,因为污染全球范围并不是一个好主意,但这并非不平凡。
这实际上可以完成有点如果仔细做好。我有点说,因为总会有警告,你必须手动调整你的环境,无论你在哪个功能/块。在Lua 5.2+中,需要local _ENV = ...
。在Lua 5.1中,setfenv(1, ...)
可以做到这一点,而且在眼睛上可以说更容易。
以下是我们可以做的事情。我们首先定义一个返回克隆环境的函数。 clone
是一个浅表复制功能。
return function (env)
env = clone(env or _G)
return env
end
接下来,我们添加我们的自定义import
函数,直接修改我们的新的环境,而不是返回任何东西(如require
一样)。你可以在这里变得更好更复杂,实施不同的方式来决定将什么输入到环境中,以及如何实现。( '*',例如)
-- @module: import.lua
return function (env)
env = clone(env or _G)
function env.import (modname, ...)
local args = { ... }
local m = require(modname)
for _, name in next, args
env[name] = m[name]
end
end
return env
end
,我们可以为使用:
local _ENV = require('import')()
-- setfenv(1, require('import')())
import('module_name', 'a', 'b')
return a + b
在小规模,这是开销相当数量,只是为了避免:
local module_name = require('module_name')
local a, b = module_name.a, module_name.b
它可能证明更大的文件,许多进口更有用。导入通常以任何方式聚集在文档的顶部,所以额外的噪音并不是很差。如果您可以在某处将env
设置为全局值,则看起来更清晰。
local _ENV = env()
import('webserver', 'open', 'status', 'close')
import('database', 'connect', 'query', 'disconnect')
import('json', 'parse', 'stringify')
...
而且还可以用来创建沙箱,假设小心与重写import
功能不使用require
!
local my_env = env { print = print }
my_env.import('my_mod', 'foo', 'bar')
local chunk = loadfile('my_file.lua', 'bt', my_env)
'local my_module = require(“my_module”);本地a,b = my_module.a,my_module.b;返回a + b' –
这更像是'from my_module import a,b'。如果有(极端示例)500个我正在导入的东西呢?我宁愿不手动导入它们。 –