在7周内完成7种语言的Lua练习并遇到问题。
挑战是重载+运算符以便能够连接表(就像它们是数组一样)。
{ 1, 2, 3 } + { 4, 5, 6 } -- { 1, 2, 3, 4, 5, 6 }
所以我尝试使用__add
metamethod并创建了一个metatable来托管它。
local mt = {
__add = function(lhs, rhs)
return concatenate(lhs, rhs)
done
}
我错误地尝试在全局表上设置此metatable,但这显然不会传播到所有其他表。
为了尝试将其添加到所有创建的表中,我在_G
上创建了一个单独的元表,它将使用__newindex
元方法,然后设置每个__newindex
激活的原始元表。
setmetatable(_G, {
__newindex = function(array, index)
setmetatable(array, mt)
end
})
但是,这没有用:
a1 = { 1, 2, 3 }
a2 = { 4, 5, 6 }
a1 + a2
导致以下错误:attempt to perform arithmetic on global 'a1' (a nil value)
所以我把一个print语句放到全局metatable中,看它是否实际被调用:
setmetatable(_G, {
__newindex = function(array, index)
print('new table ' .. index)
setmetatable(array, mt)
end
})
这只会打印出要创建的第一个表:
a1 = { 1, 2, 3 }
a2 = { 4, 5, 6 }
a3 = { 4, 5, 6 }
a4 = { 4, 5, 6 }
结果:
new table a1
我希望我不小心覆盖某些内容,因为当我删除对setmetatable
setmetatable(_G, {
__newindex = function(array, index)
print('new table ' .. index)
--setmetatable(array, mt)
end
})
按预期打印所有条目。
答案 0 :(得分:3)
setmetatable(_G, {
__newindex = function(array, index)
print('new table ' .. index)
setmetatable(array, mt)
end
})
当您执行a1 = { 1, 2, 3 }
时,__newindex
即array
,而_G
为index
,setmetatable(array, mt)
为' a1' 。然后调用_G
将更改setmetatable
的元表,撤消原始setmetatable(_G, {
__newindex = function(array, index)
setmetatable(array[index], mt)
end
})
调用的效果。
你可能想要更像的东西:
__newindex
但是还有另一个问题,因为现在不再发生作业的原始效果。而是调用a1
,因此array[index] = value
仍为零值。
您可以在__newindex
功能中尝试__newindex
,但这会再次调用相同的rawset
。相反,请使用setmetatable(_G, {
__newindex = function(array, index, value)
rawset(array, index, value)
setmetatable(array[index], mt)
end
})
:
__newindex
请注意b = 1
需要3个参数。
现在,当您将非表格分配给像{{1}}这样的全局<?p>时会发生什么