Lua vs. XML用于数据存储
许多人已经接受 XML 作为一种存储数据的方式。它的优点和缺点通常是众所周知的,我当然不想在这里讨论它们。然而,在我正在使用 C++ 编写的项目中,我也在使用 Lua。我非常惊讶 Lua 能够如此好地用于存储和处理数据。然而,至少在游戏编程领域,人们对 Lua 的这个方面认识较少。
我知道 XML 在像通过互联网发送数据、在需要考虑安全问题的地方(例如使用从网上下载的数据,或加载用户可编辑的配置文件),以及在不同语言的程序读取相同数据的情况下具有优势。
然而,一旦我学会了如何使用 Lua(尤其是有 luabind 支持的情况下)轻松处理数据,我开始想知道在我们已经使用 Lua 的情况下,是否有任何理由使用 XML 存储游戏数据呢?
暴雪虽然使用 Lua 脚本化 UI,但仍将布局存储在 XML 中。原因是否与 UI 相关?
使用 Lua 作为数据存储语言的缺点是什么?
原文链接 https://stackoverflow.com/questions/1972722
如果lua脚本是用户可访问的,则必须强制执行您用于数据规范的lua子集,否则您拥有的不仅是数据语言,而且是安全漏洞。强制执行这样的子集的问题并不是微不足道的。
您是否了解json?那可能更适合您的需求。
这里有两个实现: http://json.luaforge.net/
和这里 http://www.chipmunkav.com/downloads/Json.lua
如果json不够强大,另一个选择是YAML,这是JSON的超集,但是我无法告诉您Lua中是否有任何体面的实现。
我认为最大的劣势是它比其他工具更难操作数据。如果直接将数据存储在 Lua 中,则需要编写 Lua 解析器才能自动操作该数据,而每个环境都有 XML 解析器和生成器。这不仅仅是针对其他语言的工具的问题;如果要为编辑配置的 GUI 编写工具,您是否有工具可以以不影响版本控制系统中合并的方式解析,修改和编写配置数据?对于可能同时编辑配置的许多人的大型项目,这可能很重要。
话虽如此,这个想法也导致了 JSON,它是 JavaScript 的子集,用作数据格式。但是当前有很多支持 JSON 的工具,而可能支持 Lua 语法的工具较少。
当您的代码作为配置时,偶尔会出现另一个问题,即人们开始编写生成配置的代码或向配置文件添加抽象。然后,任何想要自定义您的程序的用户可能会感到困惑,不得不学习如何编程和整个编程语言,而不是相对简单的配置语言。
如果不考虑安全性,那就考虑纪律性。如果一份数据文件中提供了完整的 LUA 范围,那么向数据文件中添加逻辑或行为的可能性仍然存在。拥有既是数据又是行为实体的情况可能会让大型项目的管理变得复杂:例如,假设您构建了一个游戏引擎和一个完整的游戏。现在,您想删除所有特定的内容,重用游戏引擎制作新游戏。如果内容/数据与行为被安全地分隔开来,那么这是相当简单的。如果在某个时候您决定将函数作为数据存储来解决问题,那么就会有一些奇怪的事情发生。
您可能能够在团队内部执行此类纪律性,但用户可能会利用这种可能性。那么就会出现一些问题。在将来某个时间,您决定更改数据格式,那些用户扩展程序就无法移植,因为它们包括非数据的 Lua!
在大规模上操作此类实体更加困难。
还有其他一些问题,这些问题来自于没有正确地分离关注点。如果您允许数据和代码混合在一起,它们可能仍然都能正常工作,但是纠缠在一起的程度越高,理解起来就越困难。
Lua 是用于存储数据的重要选择。它方便快捷,并且可以根据需求轻松转换为其他格式。(转换性假设你的数据可以用其他格式表达,如果你的数据可以表示为 XML 格式,那么它也可以被转换。)
使用 Lua 作为数据存储语言的缺点是什么?
我意识到有 两个缺点,其重要性取决于您的应用:
如果您的 Lua 表包含循环引用,例如,
t1.next == t2
和t2.prev = t1
,那么将 Lua 结构写入磁盘的过程将变得麻烦,并且生成的 Lua 容易阅读性较差,与简单的return <list of big expressions here>
相比。(我从未遇到过这种情况,如果您的数据可以用 XML 表示,那么您就不会遇到这个问题。)如果您有大量的数据,例如您正在编写整个 Inform 7 手册的倒排索引,那么您可能会遇到 Lua 中出现在块中的不同常量数的限制。然后,您必须将其拆分为多个块或函数,或者采用其他解决方案。这个问题曾经困扰过我,而且非常麻烦。我想写一个通用的解决方案,但我不确定完全理解了限制,并且我还没有解决它。
如果您的数据中有少于 100,000 个数字和字符串字面量,您就不必担心这个问题。
这可能不是你期望的答案,但它可能会帮助你作出决定。
暴雪公司(魔兽世界)使用 XML 来定义 UI。这有点类似于 C# 中的 XAML,只是弱化了很多,并且大多数插件只使用 XML 来启动插件,然后在 Lua 代码中构建 UI。
此外,WoW 实际上将插件“已保存变量”存储在 .lua 文件中。
在我看来,这并不是非常重要的。选择一些你喜欢的,对于那些打算扩展你的引擎的人来说易于使用的东西。
XML 的好处是已经有了很多测试、编写和解析 XML 的工具和代码,这意味着它可以节省你一些时间。例如,XML Schema 对于验证用户编写的文件非常有用(安全只是副作用,好处是如果它通过了你的模式,那么数据很可能是 100% 安全并且可以直接插入你的引擎中),而且已经有了一些验证器供你使用。
但是,有些用户害怕 XML 文件(尽管它们非常易读,也许过于易读了),他们更喜欢一些“更简单”的东西。如果只是用于存储(而不是配置),那么大多数情况下都不会有人编辑这些文件。XML 还会比 Lua var dump 占用更多的空间(除非你有很多数据,否则这应该无关紧要)。
我认为你不会做错。暴雪公司正在使用 Lua 进行存储,我相当喜欢它的工作方式。
感谢大家的回答!为了方便将来的参考,我将总结一下要点。
与使用 XML 存储数据相比,Lua 存储数据的缺点
- 安全性问题,尤其是在接收来自未知来源的数据时的传输和存储
- 便携性和其他工具对数据的易访问性
- 已有工具(如 XML 模式验证器)的可用性较差
- 对数据解析的支持较少
- 循环引用的问题
- 约束力较弱,难以强制执行正确的规则、用法和设计
与使用 XML 存储数据相比,Lua 存储数据的优点
- 使用一种单一语言进行脚本和数据的处理(无需分离文件,无需特殊加载)
- 由于使用单一语言,代码和依赖项更少
- 更具有可读性,并且更加详细(或者说人类更易读懂)
- 更为灵活、可扩展(毕竟它是一种编程语言)
- 数据被“执行”,且在需要时可以访问,因为它位于虚拟机中
- 占用空间更少,特别是如果编译为字节码的话
如果我在第一个列表中漏掉了什么,请指出来!
我做过几个项目,使用 Lua 作为数据存储/配置语言
在决定使用它时的关键因素是“我们是否已经在该项目中使用了 Lua?”
另一件事是,它可以在任何可以编译 Lua 解释器的地方运行。在所有平台上都是相同的-没有特殊的 xml 库
JSON 是一个很好的替代品。
现在我唯一使用 XML 的方式是使用带注释的代码生成序列化器,例如 .NET xml 或 JAXB。
记住 Lua 虚拟机和语言非常灵活。您可以使用函数环境来实现任何形式的安全性,然后使用策略来避免运行“恶意”代码。只需从您使用loadstring()加载数据的环境中消除 EVERYTHING,您的“数据”唯一会造成危险的是运行循环并烧毁 CPU。
另一个要记住的是,您始终可以将 Lua 表格转换为 XML,反之亦然,尽管元素和属性映射到 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中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
我通常会避免使用 XML,因为它比较冗长。大部分时间,我会使用 CSV 或 SQLite 来存储数据。我使用脚本语言,比如 Lua、Python 或 Scheme,来为用户提供扩展软件的接口。