我已经实现了自己的班级系统,但遇到了麻烦__tostring
;我怀疑其他元方法也会发生类似的问题,但我没有尝试过。
(简单绕道:每个类都有一个__classDict
属性,包含所有方法。它被用作类实例' __index
。同时,__classDict's__index
是超类' __classDict
,因此会自动查找超类中的方法。)
我想在所有情况下都有一个“默认的 tostring”行为。但它没有用:“tostring”行为没有通过子类正确“传播”。
我已经完成了这个测试来说明我的问题:
mt1 = {__tostring=function(x) return x.name or "no name" end }
mt2 = {}
setmetatable(mt2, {__index=mt1})
x = {name='x'}
y = {name='y'}
setmetatable(x, mt1)
setmetatable(y, mt2)
print(x) -- prints "x"
print(mt2.__tostring(y)) -- prints "y"
print(y) -- prints "table: 0x9e84c18" !!
我宁愿最后一行打印“y”。
Lua 的“to_String”行为必须使用等价于
rawget(instance.class.__classDict, '__tostring')
而不是做相当于
instance.class.__classDict.__tostring
我怀疑所有元方法都会发生同样的情况;rawget
- 使用等效操作。
我想我可以做的一件事是在我进行子类化时复制所有元方法(上面示例中的等价物会做mt2.__tostring = mt1.__tostring
),但这有点不雅。
有没有人为这种问题打过仗?你的解决方案在哪里?