为什么设置嵌套表的值会设置元表的表?

我正在学习lua,发现了一个有趣的元表:

local mt = {
  value = 0,
  nested = { value = 0 },
}
mt.__index = mt

local t1 = {}
setmetatable(t1, mt)

local t2 = {}
setmetatable(t2, mt)

print(t1.value)         -- 0
print(t1.nested.value)  -- 0
print(t2.value)         -- 0
print(t2.nested.value)  -- 0
print(mt.value)         -- 0
print(mt.nested.value)  -- 0

t1.value = 10
t1.nested.value = 20;

print(t1.value)         -- 10
print(t1.nested.value)  -- 20
print(t2.value)         -- 0
print(t2.nested.value)  -- 20 (?)
print(mt.value)         -- 0
print(mt.nested.value)  -- 20 (?)

请注意带有“(?)”的两个评论。

如果我理解正确,正在发生的是因为t1没有nested键,因此它返回mtnested表。因此,执行t1.nested.value = 20等效于在mt中设置值,从而影响使用它作为元表的所有表。

我有两个问题:

1.我的理解正确吗?如果不是,有人能解释一下这里发生了什么吗? 2.不管发生了什么,如何只设置特定表的nested表而不影响元表?

原文链接 https://stackoverflow.com/questions/69167394

点赞
stackoverflow用户10391157
stackoverflow用户10391157

是的,1)是正确的。

对于2),最简单的方法是在t1中创建一个新表,该表再次具有带有__index字段的元表。

t1.nested = setmetatable({}, {__index = t1.nested})

print(t1.nested.value)  -- 20
t1.nested.value = 30
print(t1.nested.value)  -- 30
print(mt.nested.value)  -- 20
2021-09-13 18:59:54