Lua学习笔记六——package

时间:2023-01-16 17:40:32

lua和其他语言一样,也有模块/包的概念,稍微有点不同的是,默认先从环境变量LUA_PATH中搜索lua文件,如果搜索不到,则从LUA_CPATH中搜索C文件。

 

 

对于我来说,时而去改变环境变量,则显得麻烦,并且在另外的环境中部署时还要修改环境变量,则显得不人性化,因此,觉得如下方式增加搜索路径比较好:

 

[python]  view plain copy
  1. --将自定义包路径加入package的搜索路径中。也可以加到环境变量LUA_PATH中  
  2. local p = "自定义包路径的父目录"  
  3. local m_package_path = package.path  
  4. package.path = string.format("%s;%s?.lua;%s?/init.lua",  
  5.     m_package_path, p, p)  

 

 

自定义包文件及包加载示例,假如文件结构如下:

蓝色表示文件夹,紫色表示文件

----------test.lua

----------demopackage

---------------------init.lua

---------------------a.lua

 

这时候,demopackage就是一个包了, 模块demopackage的功能由init.lua文件提供,模块demopackage.a由a.lua文件提供,下面将在test.lua文件中调用demopackage包:

 

--init.lua文件 

 

 

[python]  view plain copy
  1. module(..., package.seeall)  
  2.   
  3.   
  4. function add(n1, n2)  
  5.     return n1 + n2  
  6. end  
  7.   
  8. function sub(n1, n2)  
  9.     return n1 - n2  
  10. end  
  11.   
  12. function div(n1, n2)  
  13.     if n2 ~= 0 then  
  14.         return n1 / n2  
  15.     else  
  16.         error("require n2 is not zero")  
  17.     end  
  18. end  
  19.   
  20. function mul(n1, n2)  
  21.     return n1 * n2  
  22. end  

 

 

--a.lua

[python]  view plain copy
  1. module(..., package.seeall)  
  2.   
  3. function p()  
  4.     print "module demopackage.a"  
  5. end  
  6.   
  7. function lstostring(ls)  
  8.     return "{" .. table.concat(ls, ", ") .. "}"  
  9. end  

 

上面的两个文件中,开头都有这么一行代码module(..., package.seeall),这是为了模块名以文件名命名,还有为了不污染全局变量_G,返回当前模块提供的函数等等。相当于:

 

--将模块名设置为文件名,且加载这个模块

local modname = ...

local M = {}

_G[modname] = M

package.loaded[modname] = M

 

--引入所需模块

local io = io

local print = print

 

setfenv(1, M)          --> 设置当前环境变量

 

--开始实现模块功能

function test()

    print("test")

end

 

……

 

 

调用demo文件

--test.lua

[python]  view plain copy
  1. --将自定义包路径加入package的搜索路径中。也可以加到环境变量LUA_PATH中  
  2. local p = "E:/dep/code/lua/"  
  3. local m_package_path = package.path  
  4. package.path = string.format("%s;%s?.lua;%s?/init.lua",  
  5.     m_package_path, p, p)  
  6.   
  7.   
  8. --print(package.path)       --> lua文件的搜索路径  
  9. --print(package.cpath)      --> lua c文件的搜索路径  
  10.   
  11.   
  12. require "demopackage"  
  13. require "demopackage.a"  
  14.   
  15.   
  16. print("--------package: demopackage --------------")  
  17. for i in pairs(demopackage) do  
  18.     print(i, demopackage[i])  
  19. end  
  20.   
  21. print("--------package: demopackage.a --------------")  
  22. for i in pairs(demopackage.a) do  
  23.     print(i, demopackage.a[i])  
  24. end  
  25.   
  26.   
  27. print("---------------demo print--------------")  
  28. print( demopackage.add(12) )  
  29. print( demopackage.a.lstostring({"first""second"}) )  
  30.   
  31. print( demopackage.a.p() )  

 

 

 lua中,用require来加载包,如果想重命名加载的包,可以如下操作:

local t = require "demopackage", 这时候,就可以用t调用demopackage中的功能了。

 

BTW,lua加载包时,不会加载包中所有的模块,这点是跟其他语言不一样的,这样做应该是为了提高运行速度吧。