支持在Lua中的“递归对象”

我对 Lua 还比较新,对课程作业有以下问题:

我们当前扩展 Lua 以支持对象和继承。语法如下:

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

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

这工作得非常好。真正的问题在于下一个任务:我们应该支持“递归类型”,这意味着像

Class{'MyClass', attribute = MyClass}

的调用应该返回一个具有与类相同类型的字段的类。当调用这个“类构造函数”时,变量 MyClassnil,因此参数表没有 attribute。如何访问这个属性呢?

我的第一个想法是使用一种“nil-表”,每次用未设置的关键字调用全局 __index 时都会返回。这个“nil-表”应该表现得像正常的 nil,但可以在“类构造函数”中进行检查。这种方法的问题是像 nil == unknown 这样的比较。这应该返回 true,但由于 nil 表的 __eq 元方法从未被调用,我们无法返回 true

我当前有什么其他方法吗?任何提示都将不胜感激。

提前致谢。

编辑: 这是“测试文件”的相关部分。代码的评级测试是另一个测试,稍后发布。

three = 3
print( three  == 3 , "应该是true")
print( unknown == nil , "应该是true" )

Class{'AClass', name = String, ref = AClass}
function AClass:write()
    print("AClass:write(),AClass 的名称:", self.name)
end

aclass = AClass:create("A. Class")
aclass:write()
点赞
用户2765603
用户2765603

由于MyClass只是全局表(_G)中的一个查找,你_可以_通过改变其元表的__index来返回一个新定义的MyClass对象(稍后您需要填充其细节)。

然而,尽管可行,这样的实现方式是:

  • 非常不安全的,因为你可能最终得到一个未定义的类(或者更糟糕的是,你可能会意外创建一个无限的查找循环。相信我,我已经经历过了)
  • 非常难调试,因为每个非存在变量的_G查找现在都会返回一个新创建的类对象,而不是nil(通过要求类名以大写字母开头,可以在一定程度上减少这个问题)

如果你选择这样做,一定要同时覆盖__newindex

2015-06-02 13:28:41
用户102441
用户102441

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

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

在创建类之后,检测内部实现的字符串,并使用 _G[string] 处理它们。

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

Class{'MyClass', attribute = function() return MyClass end}
2015-06-02 16:34:39