Lua - 理解setmetatable

时间:2017-03-30 21:19:41

标签: lua lua-table torch metatable

我正在尝试使用CNN构建Torch 7。我对Lua很新。我试图遵循这个link。我在以下代码块中遇到了一个名为setmetatable的东西:

setmetatable(train_set, 
{
  __index = function(t, i) 
    return {t.data[i], t.label[i]}
  end
});

我理解第二个参数充当表train_set的元表。

1)t是metatable还是t只是train_set的另一个名字?

2)每当对__index使用函数时,解释器是否假设第一个参数(t)是一个表(或者是metatable,取决于第一个问题的答案)?并且第二个参数始终是keyindex

3)我的理解是,如果我使用train_set.data[1],它将调用__index。答案here表示在表中不存在__index时调用key。但t.data[1]train_set.data[1]相同吗?如果是这样,口译员如何知道?

2 个答案:

答案 0 :(得分:4)

setmetatable(train_set, 
{
  __index = function(t, i) 
    return {t.data[i], t.label[i]}
  end
})

这里有一些名为train_set的表。通过此函数调用,我们将其metatable设置为

 {
  __index = function(t, i) 
      return {t.data[i], t.label[i]}
  end
 }

这是一个匿名表。如果这对你来说很难读,你也可以写:

local my_metatable = {
  __index = function(t, i) 
     return {t.data[i], t.label[i]}
  end
}
setmetatable(train_set, my_metatable)

在metatable中我们实现了metamethod __index。通过这样做,我们告诉Lua当有人索引train_set中不存在的字段时该怎么做。

因此,当我们要求Lua向我们提供train_set[4]中存储的值并且train_set[4]nil时,Lua将检查是否已实施__index。如果是这样,它会调用__index(train_set, 4)并给你返回值或以其他方式返回nil 因此解释器知道t.data [1]与train_set.data [1]相同,因为他是将train_set放入__index的人。

因此,当您实现__index时,将始终使用索引表作为第一个参数并将索引作为第二个参数进行调用。

答案 1 :(得分:2)

首先,有两个重要的链接:

现在回答:

  1. <?php namespace FalkRoeder\MyExt\Service; /** * FileCollectionService */ class FileCollectionService extends \SKYFILLERS\SfFilecollectionGallery\Service\FileCollectionService { /** * @return array */ public function methodToOverwrite() { ... } } 是metatable中t方法的第一个参数,是指 metatable的表格,此处为__index。此参数允许为多个表重用相同的元表。

  2. train_set是metatables中的特殊函数(查看metatable events),只要访问metatabled表中的字段但缺少该函数,就会调用该函数。例如,如果__index不包含密钥train_set且您读取 k,则会在其元表中调用train_set.k

  3. 根据我可以从代码中推断,您的示例中的使用模式 看起来像__index (train_set, "k"),它将返回包含local x = train_set [1]的表。