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]
一样吗?如果是这样,口译员怎么知道的?
首先,两个重要的链接:
- metatables in Programming in Lua;
- metatable events in the Lua wiki.
现在答案:
t
,meta__index
方法的第一个参数table,指的是的table有元table,这里train_set
。此参数允许对多个 table 重复使用相同的元 table。
__index
是 metatables 中的一个 special 函数(查看 metatable events),即每当 metatabled table 中的字段被访问但丢失时调用。例如,如果 train_set
不包含密钥 k
而您 读取 train_set.k
,则会调用 __index (train_set, "k")
它的元table.
根据我可以从代码中推断出的内容,您的示例中的使用模式 看起来像 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 作为第一个参数并使用索引作为第二个参数来调用。
我正在尝试使用 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]
一样吗?如果是这样,口译员怎么知道的?
首先,两个重要的链接:
- metatables in Programming in Lua;
- metatable events in the Lua wiki.
现在答案:
t
,meta__index
方法的第一个参数table,指的是的table有元table,这里train_set
。此参数允许对多个 table 重复使用相同的元 table。__index
是 metatables 中的一个 special 函数(查看 metatable events),即每当 metatabled table 中的字段被访问但丢失时调用。例如,如果train_set
不包含密钥k
而您 读取train_set.k
,则会调用__index (train_set, "k")
它的元table.根据我可以从代码中推断出的内容,您的示例中的使用模式 看起来像
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 作为第一个参数并使用索引作为第二个参数来调用。