标签: metatable

next()是否会寻找__pairs元方法?

一般来说,语法:

for k, v in pairs(t) do
   ....
end
Run Code Online (Sandbox Code Playgroud)

相当于:

for k, v in next, t do
    ....
end
Run Code Online (Sandbox Code Playgroud)

但如果t有一个__pairsmetamethod怎么办?标准next()功能会检查这个吗?如果没有,那么在迭代表时总是使用pairs并且从不next()直接调用是不是更好?

lua metatable meta-method

8
推荐指数
1
解决办法
321
查看次数

Lua Metatable不一致

我无法理解为什么__index这些示例之间的元方法行为存在差异:

A = { __index = A }   
function A:speak()
    print("I'm an A")
end
An_A = setmetatable({},A)
An_A:speak()
Run Code Online (Sandbox Code Playgroud)

会引发以下错误: lua: l.lua:8: attempt to call method 'speak' (a nil value)

同时

B = { __index = function(t,key)  return B[key] end }
function B:speak()
    print("I'm an B")
end
An_B = setmetatable({},B)
An_B:speak()
Run Code Online (Sandbox Code Playgroud)

将按预期执行,输出I'm an B.


在试图理解为什么会这样的情况下,我阅读了PiL的这一部分.它指出:

使用__index元方法进行继承是如此常见,以至于Lua提供了一种快捷方式.尽管有名称,但__index元方法不需要是一个函数:它可以是一个表,而不是.当它是一个函数时,Lua用表和缺席键作为参数来调用它.当它是一个表时,Lua重做该表中的访问权限.

我对此的理解是,在涉及"A"的代码段中,__index = A导致访问在表中完成A(根据上面引用的加速分段).如果是这种情况,我不明白为什么"speak"找不到与密钥相关的功能.为了尝试修复此问题,我决定在B代码段中实现函数方法,该方法返回与keyin 关联的值B,并且它有效.当然__index = …

lua metatable lua-table

6
推荐指数
1
解决办法
394
查看次数

什么是lua __pairs的实际实现?

有没有人知道lua 5.2的实际实现.metamethod __pairs?换句话说,我如何__pairs在metatable中实现metame方法,以便它与...完全相同pairs()

我需要覆盖__pairs并希望跳过我在表中添加的一些虚拟变量.

lua metatable lua-5.2 meta-method

6
推荐指数
1
解决办法
2817
查看次数

Lua,c ++和消失的元数据

背景

我和Watusimoto在Bitfighter游戏上合作.我们使用LuaWrapper的变体将我们的c ++对象与游戏中的Lua对象连接起来.我们还使用称为lua-vec的Lua变体来加速向量操作.

我们一直在努力解决一段时间没有找到错误的bug.将发生随机崩溃,表明腐败的元数据.有关Watusimoto的帖子,请参阅此处.我不确定这是因为一个腐败的metatable,并且看到了一些我想在这里问的非常奇怪的行为.

问题表现形式

作为一个例子,我们创建一个对象并将其添加到这样的级别:

t = TextItem.new()
t:setText("hello")
levelgen:addItem(t)
Run Code Online (Sandbox Code Playgroud)

但是,游戏有时会(并非总是)崩溃.出错:

attempt to call missing or unknown method 'addItem' (a nil value)
Run Code Online (Sandbox Code Playgroud)

使用上面提到的Watusimoto帖子中给出的建议,我已将最后一行更改为以下内容:

local ok, res = pcall(function() levelgen:addItem(t) end)

if not ok then
    local s = "Invalid levelgen value: "..tostring(levelgen).." "..type(levelgen).."\n"

    for k, v in pairs(getmetatable(levelgen)) do 
        s = s.."meta "..tostring(k).." "..tostring(v).."\n"
    end

    error(res..s)
end
Run Code Online (Sandbox Code Playgroud)

这打印出metatable,levelgen如果错误的话从它调用一个方法.

然而,这很疯狂,当它失败并打印出metatable时,metatable 正是应该如何(使用正确的addItem调用和所有内容).如果我levelgen在脚本加载时打印metatable ,并且在上面使用它时失败pcall,它们是相同的,每个调用和指向userdata的指针是相同的,应该是它.

好像metatable levelgen …

c++ lua metatable

5
推荐指数
1
解决办法
477
查看次数

我需要澄清Metatable .__ index

我之前问过为什么我的方法不是由Lua找到我的方法,并且被告知通过设置__index我的metatable,它会解决问题,所以我假设一个方法被调用时是通过metatable中的索引进行搜索,但我已经遇到了一个问题,现在我需要使用索引括号[]我的元表,因此__index被分配到从它里面的一张桌子返回索引,我该如何解决您在使用这两种方法的功能需求和使用索引括号

我写了一个指示问题的最小例子:

TestMetatable = {DataTable = {}}
TestMetatable.__index = TestMetatable

function TestMetatable.new()
    local Tmp = {}
    setmetatable(Tmp,TestMetatable)

    Tmp.DataTable = {1}

    return Tmp
end

function TestMetatable:TestMethod()
    print("Ran Successfully")
end

function TestMetatable.__index(self,index)
    return self.DataTable[index]
end

local Test = TestMetatable.new()

-- both functionalities are needed
print(Test[1])
Test:TestMethod()
Run Code Online (Sandbox Code Playgroud)

lua metatable

5
推荐指数
1
解决办法
6033
查看次数

Lua C API - 从堆栈上的表中获取元表

假设我们有一个传递给函数的表,它现在位于堆栈顶部,如下所示:

// -1 = table
Run Code Online (Sandbox Code Playgroud)

是否可以从堆栈中的表中获取元表?我可以简单地使用已知名称标识符来获取它,如下所示:

luaL_getmetatable(L, "Foo");
Run Code Online (Sandbox Code Playgroud)

但我想重新使用该函数并从堆栈中的表中获取元表.

可能有一种简单的方法可以做到这一点,但我似乎找不到这个功能.

c++ lua metatable

5
推荐指数
1
解决办法
1269
查看次数

在lua中有一种方法可以将upvalue绑定到userdata值而不是函数吗?

在以下示例中,将userdata创建一个类型的值,MyType并使用__tostring调用的元函数创建一个表LI_MyType__tostring.该代码创建了一个基于闭包的lua OOP.我对提供的示例的抱怨似乎只有一种方法可以userdata通过upvalues与方法调用相关联.除非我想跨实例共享相同的元表,否则这本身并不成问题.

在一个理想的世界 - 以及我希望用这个问题发掘的东西 - 有没有办法将upvalue与值(例如userdata)相关联,而不通过upvalue将它与函数调用相关联?我希望有一个技巧可以让我继续使用基于闭包的lua OOP 在实例之间共享相同的元数据.我不乐观,但我想我会问是否有人有建议或不明显的伎俩.

using FuncArray = std::vector<const ::luaL_Reg>;
static const FuncArray funcs = {
  { "__tostring", LI_MyType__tostring },
};

int LC_MyType_newInstance(lua_State* L) {
  auto userdata = static_cast<MyType*>(lua_newuserdata(L, sizeof(MyType)));
  new(userdata) MyType();

  // Create the metatable
  lua_createtable(L, 0, funcs.size());     // |userdata|table|
  lua_pushvalue(L, -2);                    // |userdata|table|userdata|
  luaL_setfuncs(L, funcs.data(), 1);       // |userdata|table|
  lua_setmetatable(L, -2);                 // |userdata|
  return 1;
}

int LI_MyType__tostring(lua_State* L) {
  // NOTE: …
Run Code Online (Sandbox Code Playgroud)

c++ lua metatable

5
推荐指数
1
解决办法
1110
查看次数

Lua表长度函数覆盖不起作用

如何#在Lua中更改表的长度operator(),手册建议__len在metatable中分配函数,然后将metatable分配给我想要覆盖的表,但是这不能按预期工作?我没有选择在C端覆盖它.

turtles = {1,2,3}
setmetatable(turtles, {__len = function(mytable) return 5 end})

print(#turtles)
--returns 3, should return 5
Run Code Online (Sandbox Code Playgroud)

lua metatable lua-table

5
推荐指数
1
解决办法
702
查看次数

什么是newproxy以及它如何有用?

昨天我和Lua搞混乱,偶然发现了'newproxy'功能.

http://wiki.roblox.com/index.php?title=Function_dump/Basic_functions#newproxy

我有点理解它,但我不确定它是如何有用的.我知道它会创建一个附加了元表的空白userdata对象(如果参数为true).

newproxy如何有用?这是我在搞乱它时所做的一个例子:

local proxy = newproxy(true)
local metatable = getmetatable(proxy)

metatable.__index = function(array, key) print(array, key) end

local y = proxy[100]

--[[
    OUTPUT:
        userdata: 0x443ad4b4 100
]]
Run Code Online (Sandbox Code Playgroud)

lua metatable

5
推荐指数
1
解决办法
3224
查看次数

Lua 字符串追加

所以我创建了一个所有字符串都可以使用的函数,它被称为append。

local strmt = getmetatable("")
function strmt.__index.append(self, str)
  self = self..str
  return self
end
Run Code Online (Sandbox Code Playgroud)

然后该函数的使用方式如下:

self = self:append("stuff")
Run Code Online (Sandbox Code Playgroud)

有没有办法创建一个函数来执行此操作:

local stuff = "hi "
stuff:append("bye")
print(stuff)
Run Code Online (Sandbox Code Playgroud)

并生产

hi bye
Run Code Online (Sandbox Code Playgroud)

lua function metatable

5
推荐指数
1
解决办法
5020
查看次数

标签 统计

lua ×10

metatable ×10

c++ ×3

lua-table ×2

meta-method ×2

function ×1

lua-5.2 ×1