11

我对结构的理解是它有存储数据的槽,有一个类型,有make-X和槽访问器函数,并且可以通过一个方法专门化(因为它有一个类型)。

我对一个类的理解是它具有所有相同和多重继承。这个问题的最佳答案表明结构可以具有单一继承,并且 CLOS 的初始实现比结构“慢得多”。

根据人们如何谈论 CLOS 和结构,我认为肯定还有其他一些差异,但是我的琐碎谷歌搜索没有结果。所以我问:CLOS和结构之间有什么实际区别?

4

2 回答 2

23

结构

结构更原始。它们提供了在编程语言中通常被称为记录的东西。它们是在上课前发明的。1984 年的 CLtL1(第一本描述 Common Lisp 的书)已经有了结构,后来又添加了一个称为 CLOS 的标准对象系统。结构提供

  • 简洁的定义宏DEFSTRUCT
  • 单继承
  • 快速插槽访问
  • 定义插槽的 reader 和 setf 访问权限
  • 定义类型谓词
  • 定义一个构造函数
  • 定义一个复制函数
  • 打印的表示:可以读取和打印结构
  • 以上函数可能是内联的

有用的补充:

  • 除结构类型外,DEFSTRUCT 还可以定义基于列表和向量的结构表示

限制:

  • 更改结构类型后,结构实例不会更新
  • 如果结构类型发生更改,最好重新编译并重新运行更改的代码。也许重新启动程序。重新定义结构的效果在标准 Common Lisp 中是未定义的。
  • 很少自省:可移植的 Common Lisp 不会以简单的方式告诉我结构的超级/子结构。可移植的 Common Lisp 不会告诉我结构的插槽。
  • 默认情况下不通过插槽名称访问插槽

扩展

  • 一些实现在一些 CLOS 函数中提供了更多的运行时自省和一点点集成

CLOS 课程

CLOS是在 80 年代中后期基于两个较早的对象系统(Flavors 和 LOOPS)发明的。它提供:

  • 定义宏DEFCLASS
  • 多重继承
  • 用于创建、初始化等的协议。
  • CLOS 对象可以在运行时根据类更改(新插槽、重新定义的插槽、删除的插槽、更改的继承......)进行更改和更新
  • CLOS 对象可以更改它们的类并在运行时更新
  • 可以通过插槽名称访问

限制:

  • 没有默认打印机/阅读器
  • DEFCLASS定义不是很简洁

扩展

  • 通过添加特定于实现的功能更快地访问插槽
  • 元对象协议提供了额外的功能和灵活性:内省和反射。有时只提供部分 MOP。
  • 用户提供的扩展可用,特别是对于支持 MOP 的实现

通用 Lisp

在某些情况下,Common Lisp 标准并没有说明应该如何实现功能:结构、类,甚至可能是其他东西。示例是流和条件。如果 Common Lisp 实现使用 CLOS,这通常是一个好兆头(增加灵活性)。

于 2015-12-12T23:25:49.717 回答
4

defstruct在幕后为您做更多的工作,例如:

  1. 自动定义插槽访问器
  2. 定义可读print-object方法

此外,结构槽访问速度更快(尽管差异可能无关紧要)。

底线是,除非您需要 MOPish 功能,否则您可以使用defsrtuct.

于 2015-12-12T23:04:47.437 回答