這是不可能完全實現的,因爲修改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個我正在導入的東西呢?我寧願不手動導入它們。 –