Common Lisp中struct和class的区别

时间:2015-12-12 20:52:30

标签: class struct common-lisp clos

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

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

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

2 个答案:

答案 0 :(得分:14)

<强>结构

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

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

有用的补充:

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

限制:

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

扩展

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

CLOS课程

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

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

限制:

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

扩展

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

Common Lisp

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

答案 1 :(得分:2)

defstruct在幕后为你做了更多工作,例如:

  1. 自动定义插槽访问者
  2. 定义了可读的print-object方法
  3. 此外,结构插槽访问速度更快(尽管差异可能无关紧要)。

    最重要的是,除非您需要MOPish功能,否则您可以使用defsrtuct