Lua: 创建模块系统
我想创建一个具有不同文件夹中几个模块的程序。主程序将确定需要加载哪个模块并加载它。此外,它还将加载一些核心功能。
我创建了这种逻辑的原型,它工作得很好。但是由于我是 Lua 的新手,我不确定实现这种逻辑的正确方式。
目前,我的文件结构如下所示:

aoc(主程序):
aoc = {}
aoc_base_path = debug.getinfo(1).source:match("@(.*)/.*$") -- 基本路径到我的程序
if not aoc_base_path then
aoc_base_path = ''
else
aoc_base_path = aoc_base_path..'/'
end
local aoc_base_arg={...}
dofile(aoc_base_path.."core/core")
local module = assert(loadfile(aoc_base_path.."modules/"..aoc_base_arg[1].."/module"))
local arg = table.copy(aoc_base_arg) -- 这是我的自定义函数(我不提供列表,它只是复制一个表到另一个表)
table.remove(arg,1)
module(arg,aoc) -- 将除第一项之外的所有参数传递给模块
core/core(核心函数加载器):
dofile (aoc_base_path..'core/move')
core/move:
local function move(direction, refuel, dig, attack)
-- 一些本地函数中的逻辑(不被模块覆盖)
end
function aoc.move()
-- 全局函数(如果需要,模块的逻辑可以更改)
return move()
end
modules/mine/module(模块):
local arg={...} -- 我在 aoc 主程序中传递了2个参数
arg = arg[1]
local aoc = arg[2]
aoc.move()
现在
lua> aoc mine
或
lua> path/to/aoc mine
都可以正常工作。但是,有人能指出我是否做错了什么吗?
编辑: 更改获取aoc_base_path的逻辑
可以使用 Lua 的内置模块功能和 require 来实现。通过适当设置 package.loaders,可以将标准系统配置为从任何位置和以任何方式加载模块。具体说,可以从特定目录、直接从 HTTP,或根据 RFC 1149 由鸽子传递 - 它都能做到。
为了保持你的目录结构基本相同,但利用lua包系统,你可以采用以下方法:
在你的基本路径中,有一个名为aoc.lua的文件:
local aoc = {}
local module = ...
local dir = module:gsub("%.","%/"):sub(1,-4)
package.path = dir.."?.lua;"..package.path
package.path = dir.."?/init.lua;"..package.path
package.path = dir.."modules/?.lua;"..package.path
return aoc
在/core中有一个名为init.lua的文件,require需要包含的核心包
require"core.move"
然后你的核心包会像这样:
local function move(direction, refuel, dig, attack)
-- some logic in local function (to not be overwriten in module)
end
require"aoc".move = move
在/modules中,你可以更简单地为每个模块创建一个lua文件,因此/modules/mine.lua看起来像:
local aoc = require"aoc"
aoc.move()
然后,在lua提示符下,你会写:
lua> require"path.to.aoc"
lua> require"core" -- load up the core modules
lua> require"mine" -- load mine
##编辑
如果您想保持完全相同的风格,请将aoc.lua更改为只是return {},并添加一个名为aoc的文件,如下所示:
local dir = debug.getinfo(1).source:match("@(.*)/.*$") -- base path to my program
if not dir then dir = ''
else dir = dir..'/'
end
package.path = dir.."?.lua;"..package.path
package.path = dir.."?/init.lua;"..package.path
package.path = dir.."modules/?.lua;"..package.path
require"core"
for _,mod in ipairs{...} do
require(mod)
end
我建议这种方法的优点是,所有的混乱都在一个文件中,即aoc,在这种情况下,其余的文件结构使用相当标准的lua包约定。
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
你可以简化 aoc:
aoc = {} aoc_base_path = debug.getinfo(1).source:match("@(.*/)") or '' dofile(aoc_base_path.."core/core") local module = assert(loadfile(aoc_base_path.."modules/".. ... .."/module")) module({select(2,...)},aoc)你可以将 aoc 简化为以下步骤:
aoc = {} dofile("core/core") local module = assert(loadfile("modules/".. ... .."/module")) module({select(2,...)},aoc)