我正在尝试学习 Lua 中的元表,我遇到了以下示例:-
local my_metatable = {}
local my_tab = {}
setmetatable(my_tab, my_metatable)
-- Set the __index metamethod:
my_metatable.__index = function (tab, key)
print("Hello, " .. key)
return "cruel world"
end
-- Trigger the __index metamethod:
print("Goodbye, " .. my_tab["world"])
结果是:-
Hello, world
Goodbye, cruel world
我的问题是 - 变量
tab
在 my_metatable.__index = function (tab, key)
中做什么。我可以将其更改为任何内容,并且不会以任何方式影响程序。
谢谢!
;^) 扎洛金
向
tab
参数传递表本身的参数。
例如,给定您的代码
my_tab["world"]
,参数 tab
和 key
将分别传递参数 my_tab
和 "world"
。因为您没有在 __index
函数中使用该表,所以它不会影响任何内容。
这是它可能用途的基本示例。让我们考虑一个特殊的数组表,它的作用类似于数组,但有一些附加信息:
Array = {
length = 0,
array = {}
}
mt = {
__index = function(tab, index)
return tab.array[index]
end
}
setmetatable(t, mt)
--now when Array[3] is written, what will actually be returned is Array.array[3]
print(Array[3]) --will actually print Array.array[3]
这实际上并不是实现此功能的最佳方法,但希望这能让您了解为什么存在
tab
参数以及 __index
的用途。
我的问题是 - 变量
在tab
中做什么my_metatable.__index = function (tab, key)
如果您在元方法外部打印表格,然后在元方法内部打印选项卡参数,那么选项卡参数就是它本身的表,您将发现它们具有相同的表地址(将其视为Python中的self或C++中的)
我可以将其更改为任何内容,并且不会以任何方式影响程序。
这是错误的,我们可以更改参数,它将影响表(检查上面的代码):
local my_metatable = {}
local my_tab = {}
setmetatable(my_tab, my_metatable)
my_metatable.__index = function(tab, key)
print("Hello, " .. key)
print(tab)
setmetatable(tab, {})
end
print("1", my_tab)
print("2", my_tab.blan)
print("3", my_tab.blan)
解释:
print("1", my_tab)
这将打印
my_tab
的内存地址(参考)。
print("2", my_tab.blan)
访问
my_tab.blan
会触发 __index
元方法:
my_tab
的内存地址。my_tab
的元表设置为空表 {}
。由于
__index
元方法将 my_tab
的元表更改为 {}
,因此带有 __index
元方法的原始元表现已消失。 __index
函数不返回任何值,因此打印的值为nil
。
print("3", my_tab.blan)
现在,
my_tab
不再具有带有__index
元方法的元表,因为它在上一步中被空表{}
覆盖。再次访问 my_tab.blan
将返回 nil
,因为 blan
未在 my_tab
中定义,并且没有 __index
元方法来处理它。
以下是代码的汇总输出:
1 table: 0x<address> -- address of `my_tab`
Hello, blan -- from the `__index` metamethod
table: 0x<address> -- address of `my_tab` (printed from within the `__index` metamethod)
2 nil -- `my_tab.blan` after `__index` is removed
3 nil -- `my_tab.blan` again