支持"递归对象"在卢安

时间:2015-06-02 13:22:17

标签: class lua

我对lua相当新,并且在课堂作业中遇到以下问题:

我们目前扩展lua以支持对象和继承。语法是

Class{'MyClass', 
    attribute1 = String,
    attribute2 = Number
}

Class{'MySubClass', MyClass,
    attribute3 = Number
}

这完全没问题。真正的问题在于下一个任务:我们应该支持"递归类型",这意味着像

这样的调用
Class{'MyClass', attribute = MyClass}

应该生成一个类,该类具有与该类相同类型的字段。当这个"类构造函数"被称为变量MyClass的是nil,这就是参数表没有条目attribute的原因。如何访问此属性?

我的第一个想法是使用某种nil - 表,每次使用未设置的密钥调用全局__index时都会返回该表。此nil - 表应该与普通nil一样,但可以在"类构造函数"中检查。这种方法的问题是像nil == unknown这样的比较。这应该返回true,但由于__eq - 表的nil元方法从未被调用,我们无法返回true

我目前忽略了另一种方法吗?任何提示都非常感谢。

提前致谢。

编辑: 这里是" testfile"的相关部分。代码在课堂上评级的测试是另一个测试,稍后会发布。

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()

2 个答案:

答案 0 :(得分:3)

由于MyClass只是全局表(_G)中的查找,因此可以混淆其metatable的__index以返回新定义的MyClass对象(稍后您需要填写详细信息)。

然而,虽然可行,但这样的实现是

  • 非常不安全,因为你可能最终得到一个未定义的类(或者更糟糕的是,你可能最终无意中创建了一个无限的查找循环。相信我,我一直在那里)
  • 非常难以调试,因为对现有变量的每个_G查找现在将返回一个新创建的类对象而不是nil(通过要求类名以大写字符开头,可以稍微减少此问题)

如果你走这条路线,一定要覆盖__newindex

答案 1 :(得分:3)

如何以字符串形式提供参数?

Class{'MyClass', attribute = 'MyClass'}

检测Class实施中的字符串,并在创建类

后用_G[string] 处理它们

或者,使用函数来延迟查找:

Class{'MyClass', attribute = function() return MyClass end}