一、Lua模块与包

从开发人员的角度来看,一个模块就是一个程序库,具体的引用可以通过require来加载。然后便得到一个变量,表示一个table类型。这个table有点像一个命名空间,其内容就是模块中导出的所有东西,例如函数or常量等等。一个标准的模块还应是require返回这个table

1、require函数


要加载一个模块,只需简单调用require "模块名"。此调用会返回一个由模块函数组成的table,并且还会定义一个包含该table的全局变量。


  • 使用格式如下

local m = require('module') 

 

  m.func() 

 
• 伪代码解析require函数

  function require(name) 

 

  if not package.loaded[name] then 

 

  local loader = findloader(name) 

 

  if loader == nil then 

 

  error("cannot 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


a、首先,先判断该模块是否已经载入,如已载入则直接返回模块结果,如无则往下执行


b、调用findloader函数,调用模块。如无法调用则显示终止程序运行,相反则往下执行


c、设置该模块已经载入标志,并初始化模块


2、require例子


2.1、假设test目录中有两个文件,分别是test.lua和m.lua.其中m.lua为模块文件,test.lua是使用模块文件。代码如下:


    • m.lua
    
      local module = {} 
    
     
    
      module.constant = "这是一个常量2" 
    
     
    
      function module.fun1() 
    
     
    
      print("module.fun1") 
    
     
    
      end 
    
     
    
      return module 
    
     
    • test.lua
    
      local m = require('m') 
    
     
    
      m.fun1() 
    
     
    
      print(m.constant)


    • 运行结果



    lua程序打包exe lua package.load_lua程序打包exe



    从上述结果,可以知道,一旦执行require,包含模块后。模块的所有东西都会被引用。那么有没有什么方式,让模块只公开必须的函数or变量,而不必都被引用


    2.2、沿用上面例子

    • m.lua
    
      local module = {} 
    
     
    
      module.constant = "这是一个常量2" 
    
     
    
      function fun2() 
    
     
    
      print('func2') 
    
     
    
      end 
    
     
    
      function module.fun1() 
    
     
    
      print("module.fun1") 
    
     
    
      end 
    
     
    
      return module 
    
     
    • test.lua
    
      local m = require('m') 
    
     
    
      print(m.constant) 
    
     
    
      m.func2()


    • 运行结果


    lua程序打包exe lua package.load_lua模块与包_02


    从错误提示中可以知道,当模块文件中的函数,没有显式地加上模块名时,是无法被外部应用的。因此从这个角度来看,避免了一些函数不公开。此操作也是适用于模块中的变量等


    2.3、注意事项


    • 模块名与文件名保持一致
    • 根据模块名查找对应文件则从当前目录找起

    3、包


    包可以理解为存放多个模块的目录


    3.1、例子


    • 测试目录

    lua程序打包exe lua package.load_lua_03


    • m1.lua代码

    local m1 = {} 
    
     
    
      function m1.sayHello() 
    
     
    
      print("hello") 
    
     
    
      end 
    
     
    
      return m1 
    
     
    • m2.lua代码
    
      local m2 = {} 
    
     
    
      function m2.sayWorld() 
    
     
    
      print("world") 
    
     
    
      end 
    
     
    
      return m2 
    
      
    • test.lua
    
      local m1 = require('m.m1') 
    
     
    
      local m2 = require('m.m2') 
    
     
    
      m1.sayHello() 
    
     
    
      m2.sayWorld()


    • 运行结果


    lua程序打包exe lua package.load_lua程序打包exe_04