Class 支持";“递归对象”;在卢阿
我是lua的新手,在课堂作业中遇到以下问题: 我们目前扩展lua以支持对象和继承。其语法是Class 支持";“递归对象”;在卢阿,class,lua,Class,Lua,我是lua的新手,在课堂作业中遇到以下问题: 我们目前扩展lua以支持对象和继承。其语法是 Class{'MyClass', attribute1 = String, attribute2 = Number } Class{'MySubClass', MyClass, attribute3 = Number } 这个很好用。真正的问题在于下一个任务:我们应该支持“递归类型”,这意味着类似于 Class{'MyClass', attribute = MyClass}
Class{'MyClass',
attribute1 = String,
attribute2 = Number
}
Class{'MySubClass', MyClass,
attribute3 = Number
}
这个很好用。真正的问题在于下一个任务:我们应该支持“递归类型”,这意味着类似于
Class{'MyClass', attribute = MyClass}
应生成一个与类具有相同类型字段的类。当调用此“类构造函数”时,变量MyClass
为nil
,这就是参数表没有条目属性的原因。如何访问此属性
我的第一个想法是使用某种nil
-表,每当使用未设置的键调用全局\uu索引时都会返回该表。此nil
-表的行为应类似于正常的nil
,但可以在“类构造函数”中进行检查。这种方法的问题是比较,比如nil==unknown
。这应该返回true
,但是由于nil
表的\uu eq
元方法从未被调用,我们无法返回true
有没有其他我目前忽略的方法?任何暗示都将不胜感激
提前谢谢
编辑:
这里是“测试文件”的相关部分。在类中对代码进行评级的测试是另一个测试,稍后发布
three = 3
print( three == 3 , "Should be true")
print( unknown == nil , "Should be true" )
Class{'AClass', name = String, ref = AClass}
function AClass:write()
print("AClass:write(), name of AClass:", self.name)
end
aclass = AClass:create("A. Class")
aclass:write()
由于MyClass
只是全局表(\u G
)中的一个查找,您可能会弄乱它的元表的\u索引
,以返回一个新定义的MyClass对象(稍后需要用详细信息填充)
然而,虽然可行,但这种实施是可行的
- 非常不安全,因为您可能会得到一个未定义的类(或者更糟的是,您可能会无意中创建一个无限查找循环。相信我,我已经去过了)
- 调试非常困难,因为对不存在的变量的每个
\u G
查找现在都将返回一个新创建的类对象,而不是nil(通过要求类名以大写字符开头,可以在一定程度上减少此问题)
如果您使用这种方法,请确保同时覆盖\uuu newindex
以字符串形式提供参数如何
Class{'MyClass', attribute = 'MyClass'}
在类的实现中检测字符串
,并在创建类后使用\u G[string]
对其进行处理
或者,使用函数延迟查找:
Class{'MyClass', attribute = function() return MyClass end}
是应该支持这个调用,还是有其他语法(隐式或显式)。因为如果没有你所指的那种黑客(这是可能的,但丑陋和昂贵),我不知道这怎么可能。不幸的是,它必须是这种语法。我有一个“testfile”,它不应该被更改,并且需要给定的语法。任务的这一部分(第一部分是实现继承)也被标记为非常困难。这就是为什么我认为一定有某种黑客参与。另一个(可怕的)选项-如果您得到nil
,请使用debug.backtrace
获取当前源位置,并以文本形式读入源文件,以查找变量查找的内容。主要问题是,在像{'MyClass',attribute=MyClass}
这样构造表时,正在对'rvalues'进行完全计算。如果发生这种情况时没有定义MyClass
,那么Class
看到的只是{'MyClass',attribute=nil}
,这与{'MyClass'}
是无法区分的。如果允许您将语法改为类似的内容Class'MyClass'{attribute=MyClass}
这将简化实现。如果我正确理解这一点,这将无法解决nil==unknown
的问题,或者会吗?但我喜欢大写惯例的想法。这可能对我的导师的检查有用。我不知道这种“递归类型”在支持所有nil
检查时应该如何工作。我很好奇他们的解决方案是什么。谢谢不,这种方法不会修复nil==unknown
——也不应该。无论何时从获取MyClass
,都会创建一个占位符。在创建类时,首先检查占位符是否已经存在并填充它,否则直接创建类对象。