在Lua中使用元表
我正在尝试在Lua脚本中实现对象表示法。 这是我通过C API成功完成的内容:
我创建了一个新的全局表“Test”作为类,并在其中添加了一个字段“new”,指向一个用C编写的函数, 即我可以在Lua代码中执行这个代码:“local obj = Test.new()”(它调用函数“new”)
“new” C函数创建并返回一个新表,并将函数注册到表中作为字段(例如“add”、“count” ...) 即我可以执行这个功能:“obj:add(“迈克”)”和“obj:count()”(obj作为第一个参数使用“:”符号传递)
两个问题:
1)一切都按照预期运行,但我想知道的是:在我的情况下使用元表的好处是什么? 我发现到处都可以使用元表来帮助我实现所尝试的内容,但我不明白它们在哪里有用? 将字段添加到表中作为方法不正确吗? 如果将它们添加为我的表元表,元表如何帮助我?
2)实际上,我正在尝试在Lua中复制C ++的行为。 例如,当我在C ++中写入此内容:“Test \ * obj = new Test();” 我期望C ++和测试构造函数为我返回Test实例的指针。 这正是我想让Lua为我做的事情。
问题在于,在这种情况下,我使用一个表,作为“new”返回的表,但不是指针,因此我可以稍后使用Lua(使用其字段)调用方法,就像标准的C ++对象一样(使用operator ->)。
为了能够在C函数中检索我的类的实际指针,我在“new”返回的表中添加了一个字段“ptr”(轻量级用户值)。如果没有它,我只能在我的C函数中操纵Lua表,仅此而已(因此无法在实际指针上调用更多方法)。
我的第二个问题是,这是正确的方法吗? 你有更好的想法,在没有这个“ptr”字段的情况下如何能够在任何地方操纵我的指针?
谢谢,尼古拉斯。
原文链接 https://stackoverflow.com/questions/8174579
主要原因是你能够得到__index
元方法。如果没有它,每个实例对象都必须拥有与其相关联的所有函数:这会使表变得很大,并且使用大量内存。
local methods = {
foo = function() return "foo" end ;
bar = function() return "bar" end ;
bob = function() return "bob" end ;
hen = function() return "hen" end ;
}
因此,你可以选择
function new_no_mt()
local t = {}
for k, v in pairs (methods) do
t[k] = v
end
return t
end
或者
local mt = { __index = methods }
function new_mt ()
return setmetatable ({} , mt)
end
还有其他好处;
- 定义运算符;
- 通过比较元表进行简单的类型比较。
- 在元表中更改方法会更改所有对象的方法,但仅更改一个对象的方法只更改该对象的方法。
否则,你所要做的听起来就像是userdata的完美应用场合。当你有__index
元方法时userdata才能被索引(没有表来放置方法)。
- 如何在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 模式将字符串(嵌套数组)转换为真正的数组?
在我的情况下使用元表的优势是什么?
有以下几个优势:
Test.new = function() end
我刚刚破坏了你创建全局
Test
对象的能力。如果你使用元表来保护Test
对象,我就要花费更多的精力才能做到。另外:
local myTest = Test()
如果没有元表的话,你不能这样做(重载
__call
元方法)。使用元表比调用Test.new
更符合 Lua 语法。还有:
local testAdd = Test() + Test()
运算符重载。如果没有元表,你不可能做到这一点。
另外:
这里有个建议:不要这样做。
不同的语言有不同的用途。你应该按照 Lua 的方式处理事情,而不是按照 C++ 的方式。我可以理解希望提供某些 C++ 机制(例如重载等)的想法,但你不应该只是因为 C++ 使用
new
就使用它。此外,有很多库可以帮助你完成这项工作。SWIG 和 Luabind 就是其中两个大型的库。