如何理解Lua中的metatable?

时间:2016-06-06 09:18:43

标签: lua torch metatable

我使用过Python,但现在我因为Torch而学习Lua。 “metatable”这个词对我来说真的很难理解。例如,是一种特殊的表格吗?它如何改变表的行为?

2 个答案:

答案 0 :(得分:9)

metatable只是一个用于控制另一个表(或userdata)行为的表。表是metatable,因为它是使用作为元表。也就是说,成为一个" metatable"不是表的基本属性。没有" create_metatable"功能或任何东西。它只是我们用于控制其他表的表的名称。

指定对表(或userdata)的某些操作以首先检查表的metatable。如果表(或userdata)具有metatable,并且metatable在其中具有某个键/值对,则操作将使用该键/值对来执行该操作而不是正常逻辑。

每个可被metatable覆盖的操作都有一个与之关联的特定键名。因此,如果您尝试在表上执行添加,系统将在metatable中查找__add键以便访问它。

该对中的值通常(但不总是)是一个函数。这些功能通常被称为"元功能"。它所采用的参数及其返回值的含义由调用它的特定操作定义。一些操作允许值为表或其他内容。

在Lua中,使用setmetatable函数将metatable分配给表(但不是userdata)。从C开始,使用lua_setmetatable函数为表(或用户数据)分配元数据。

Metatable对于将C对象公开为userdata的C代码尤为重要。原始用户数据只是一个不透明的位块; Lua默认定义很少可以对它们执行的合法操作。但是通过为它们分配元数据,您可以通过元函数为用户数据提供更多功能。

答案 1 :(得分:-1)

你好

经过一段时间的阅读和理解后,我喜欢发布一个工作示例。这样,每个人都可以看到并感觉到它多么有用。该示例更改关联表的#运算符。因为我意识到#仅计算正确的未命名键。 #也忽略0和负数。这是一个工作示例,如何将其替换为对每张表进行正确计数的函数...

 # lua
Lua 5.3.5  Copyright (C) 1994-2018 Lua.org, PUC-Rio
> -- Defining a table with 3 key/value pairs
> my_table={[0]=0,[1]=1,['metatable']={}}
> #my_table
1
> -- # is counting wrong it counts only my_table[1]
> -- Now set the empty my_table.metatable to my_table
> setmetatable(my_table,my_table.metatable)
> -- So it can be accessed without getmetatable()
> -- Now replacing # for associated table my_table
> -- in my_table.metatable with the metafuncion __len
> my_table.metatable.__len=function(array) local incr=0 for _ in pairs(array) do incr=incr+1 end return incr end
> -- Let's test # ...
> #my_table
3
> -- Now # is usefull because it counts correct
> -- And my_table.metatable can be set as a metatable for other tables
> -- where # is counting wrong but needed to count the correct way
> #_G
0
> setmetatable(_G,my_table.metatable)
> #_G
45
> #package.loaded
0
> setmetatable(package.loaded,my_table.metatable)
> #package.loaded
12
> -- Like _G or package.loaded for example