【问题标题】:how to extend lua metatables with (something like) __index如何使用(类似于)__index 扩展 lua 元表
【发布时间】:2020-11-10 18:39:10
【问题描述】:

以下会话显示了我正在尝试的内容。我一定在某处误读了一些文档(我认为),当表没有为该键提供项目时,元表中的 __index 项目提供了默认值。关键是它不适用于元表本身,但我不知道为什么不这样做。文档中的什么地方对此进行了解释,在这种情况下我该怎么办?

谢谢!

> a = {}
> b = {}
> setmetatable(a,b)
table: 0000000002631ae0
> c = { __tostring = function(x) return "X" end }
> setmetatable(b,{ __index=c })
table: 0000000002631560
>
> print(a)
table: 0000000002631ae0
> -- I was expecting: X
> print(getmetatable(a).__tostring)
function: 0000000002633840
> print(tostring(a))
table: 0000000002631ae0
> -- Again, expecting X
> print(getmetatable(a).__tostring(a))
X
>

这是另一个例子。

> a = {}
> b = {}
> setmetatable(a,b)
table: 0000000002631fe0
> c = { __add = function(x,y) return "X" end }
> setmetatable(b,{ __index=c })
table: 00000000026316a0
>
> print(a+a)
stdin:1: attempt to perform arithmetic on a table value (global 'a')
stack traceback:
        stdin:1: in main chunk
        [C]: in ?
>

所以这个问题不是特定于 print 和 tostring。当然,在实际情况下,我希望有很多不同的对象共享很多元表值,而不必每次都复制所有内容......

【问题讨论】:

    标签: lua


    【解决方案1】:

    这是因为__indextbl.var 之类的索引操作有关。 Lua 不使用__index 来获取其他元方法(如__tostring)。

    您使用的是print,它直接从元表中调用__tostring,这里没有使用__index

    __index:索引访问操作table[key]

    了解更多:https://www.lua.org/manual/5.4/manual.html#2.4

    解决方案是将元表cb 合并。

    setmetatable(b,{ __tostring = c.__tostring })
    print(b) -- X
    

    【讨论】:

    • 我不知道 tbl.var 是在哪里描述的。但它并不特定于 print 和 __tostring。我添加了另一个示例...
    • @SadieKaye 好的,稍微改述一下,Lua 不使用 __index 来获取其他元方法。这会影响 __tostring、__add、__sub、__mul、__mode、__pairs 等(所有这些)
    • 好的,所以问题是......这是在哪里记录的,我该怎么办?
    • @SadieKaye 它没有具体记录,但它提到了何时调用 __index。 lua.org/manual/5.4/manual.html#2.4 > __index:索引访问操作“table[key]”
    • @SadieKaye:记录在案here。 “Lua 使用原始访问查询元表中的元方法(请参阅 rawget)。”
    猜你喜欢
    • 2017-02-01
    • 1970-01-01
    • 2016-11-21
    • 1970-01-01
    • 2018-09-12
    • 2020-10-31
    • 1970-01-01
    • 2018-11-23
    • 1970-01-01
    相关资源
    最近更新 更多