Lua - 理解 setmetatable

Lua - understanding setmetatable

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

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

我知道第二个参数充当 table train_set 的元 table。

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

2) 每当函数用于 __index 时,解释器是否假定第一个参数 (t) 是 table(或 metatable,取决于第一个问题的答案)?第二个参数总是 key 还是 index?

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

首先,两个重要的链接:

现在答案:

  1. t,meta__index方法的第一个参数table,指的是的table有元table,这里train_set。此参数允许对多个 table 重复使用相同的元 table。

  2. __index 是 metatables 中的一个 special 函数(查看 metatable events),即每当 metatabled table 中的字段被访问但丢失时调用。例如,如果 train_set 不包含密钥 k 而您 读取 train_set.k,则会调用 __index (train_set, "k")它的元table.

  3. 根据我可以从代码中推断出的内容,您的示例中的使用模式 看起来像 local x = train_set [1] 将 return table 包含 { train_set.data[i], train_set.label[i] }.

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

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

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

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

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

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

所以当我们要求 Lua 给我们存储在 train_set[4] 中的值时,例如 train_set[4]nil,Lua 将去检查是否__index 已实施。如果是这样,它会调用 __index(train_set, 4) 并给你它的 return 值,否则 return nil 所以解释器知道 t.data[1] 与 train_set.data[1] 相同,因为他是将 train_set 放入 __index 的人。

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