Lua - 理解setmetatable

我尝试使用 Torch 7 构建一个 CNN。我对 Lua 很陌生。我尝试遵循这个链接。在下面的代码块中遇到了称为 setmetatable 的东西:

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

我明白第二个参数充当了表 train_set 的元表。

1)t是元表还是train_set的另一个名称?

2)每当针对__index使用函数时,解释器是否假定第一个参数( t)为表(或元表,取决于第一个问题的答案)?第二个参数是否总是keyindex

3)我的理解是,如果我使用train_set.data[1],它将调用__index。答案在这里说当key在表中不存在时,将调用__index。但是t.data[1]train_set.data[1]相同吗?如果是这样,解释器如何知道呢?

点赞
用户162054
用户162054

首先,两个重要的链接:

接下来是答案:

  1. 在元表中,__index 方法的第一个参数 t 指的是拥有元表的表,也就是 train_set。通过这个参数,可以在多个表之间重用同一个元表。

  2. __index 是元表中的一种特殊函数(详见metatable events),当元表中的一个字段被访问但不存在时会被调用。例如,如果 train_set 中不包含键 k,并且你 读取 train_set.k,那么它的元表中会调用 __index (train_set, "k")

  3. 从代码中可以推断出,你的示例中使用的模式类似于 local x = train_set [1],它将返回包含 { train_set.data[i], train_set.label[i] } 的表。

2017-03-31 07:21:25
用户2858170
用户2858170

在这里,我们有一个名为 train_set 的表。通过这个函数调用,我们设置它的元表为

{
 __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)

在那个元表里,我们实现了元方法 __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 时,它将总是使用索引的表作为第一个参数,索引作为第二个参数进行调用。

2017-03-31 07:46:32