Lua中你可能常用但了解不深的关键字

Require

原型

function require (name)
   if not package.loaded[name] then
      local loader = findloader(name)
      if loader == nil then
         error("unable to load module"..name)   
      end
      package.loaded[name] = true
      local res = loader(name)
      if res ~= nil then
        package.loaded[name] = res    
      end
   end
   return package.loaded[name]
end

可以看出来,如果一个模块已经加载过,将不会被再次加载

顺序

1.package.loaded

2.package.path

3.package.loadlib


module

它将我们的模块表加入到全局变量中,那么模块的主程序块就有一个独占的环境,这样访问同一模块的其他公共实体时,不需要限定它名称。

module ("aModule") 
-- 相当于
local name = "aModule"           -- 定义模块名  
local M = {}                     -- 定义用于返回的模块表  
_G[name] = M                     -- 将模块表加入到全局变量中  
package.loaded[name] = M    -- 将模块表加入到package.loaded中,防止多次加载  
setfenv(1,M)  -- 将模块表设置为函数的环境表,这使得模块中的所有操作是以在模块表中的,这样定义函数就直接定义在模块表中
-- 这也使得之前的环境中的任何东西将无法被使用,这里就包括了_G

在使用了module函数的脚本,使用require并不能返回一个table,而是一个bool值,这个值告诉你是否加载成功

require一个使用了module函数的脚本,结果会被存在_G的全局表里

package.seeall

解决了module 独立环境无法使用之前环境中的全局变量

module ("aModule",package.seeall) 
-- 相当于
local name = "aModule" 
local M = {}                            
_G[name] = M                     
package.loaded[name] = M    
setmetatable(M,{__index = _G}) 
setfenv(1,M)
static int ll_seeall (lua_State *L) {
  luaL_checktype(L, 1, LUA_TTABLE);
  if (!lua_getmetatable(L, 1)) {
    lua_createtable(L, 0, 1); /* create new metatable */
    lua_pushvalue(L, -1);
    lua_setmetatable(L, 1);
  }
  lua_pushvalue(L, LUA_GLOBALSINDEX);
  lua_setfield(L, -2, "__index");  /* mt.__index = _G */
  return 0;
}

setfenv

当我们在全局环境中定义变量时经常会有命名冲突,尤其是在使用一些库的时候,变量声明可能会发生覆盖,这时候就需要一个非全局的环境来解决这问题。

setfenv(f, table):设置一个函数的环境

(1)当第一个参数为一个函数时,表示设置该函数的环境

(2)当第一个参数为一个数字时,为1代表当前函数,2代表调用自己的函数,3代表调用自己的函数的函数,以此类推

所谓函数的环境,其实一个环境就是一个表,该函数被限定为只能访问该表中的域,或在函数体内自己定义的变量。

a = 10
newfenv = {_G = _G}
setfenv(1, newfenv)
_G.print(1)        -- 1
_G.print(_G.a)        -- 10
_G.print(a)        -- nil 注意此处是nil,新环境没有a域,但可以通过_G.a访问_G的a域
原创文章 28 获赞 30 访问量 2426

猜你喜欢

转载自blog.csdn.net/qq_28820675/article/details/105543718
今日推荐