lua 元表 - __index 函数中的第一个参数

问题描述 投票:0回答:2

我正在尝试学习 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)
中做什么。我可以将其更改为任何内容,并且不会以任何方式影响程序。

谢谢!

;^) 扎洛金

lua metatable
2个回答
0
投票

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
的用途。


0
投票

我的问题是 - 变量

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
元方法:

  • 它打印出“Hello, blan”。
  • 它打印
    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
© www.soinside.com 2019 - 2024. All rights reserved.