Common Lisp 中 struct 和 class 的区别
Difference between struct and class in Common Lisp
我对结构的理解是它有存储数据的槽,有类型,有 make-X
和槽访问函数,并且可以通过方法专门化(因为它有类型).
我对class的理解是它具有相同的多重继承。 this question 的最佳答案指出结构可以具有单一继承,并且 CLOS 的初始实现比结构 "much slower"。
根据人们谈论 CLOS 和结构的方式,我认为肯定还有一些其他差异,但我的琐碎 google 搜索毫无结果。所以我问:CLOS 和结构之间的实际区别是什么?
defstruct
在幕后为您做更多工作,例如:
- 自动定义插槽访问器
- 定义可读
print-object
方法
此外,结构槽访问速度更快(尽管差异可能无关紧要)。
底线是,除非您需要 MOPish 功能,否则您可以不用 defsrtuct
。
结构
Structures更原始。它们提供在编程语言中通常称为 record 的内容。它们是在 classes 之前发明的。 1984 年的 CLtL1(第一本描述 Common Lisp 的书)已经有了结构,后来又增加了一个称为 CLOS 的标准对象系统。结构提供
- 简洁的定义宏
DEFSTRUCT
- 单继承
- 快速插槽访问
- 定义 reader 和 setf 插槽访问权限
- 定义类型谓词
- 定义构造函数
- 定义一个复制函数
- 打印表示:可以读取和打印结构
- 以上函数可能是内联的
有用的补充:
- 除了结构类型之外,DEFSTRUCT 还可以定义基于列表和向量的结构表示
限制:
- 更改结构类型后,结构实例不会更新
- 如果更改了结构类型,最好重新编译并重新运行更改的代码。也许重新启动程序。重新定义结构的效果在标准 Common Lisp 中未定义。
- 很少自省:可移植的 Common Lisp 没有以简单的方式告诉我 super/sub-strucures 结构。可移植的 Common Lisp 没有告诉我结构的插槽。
- 默认情况下不通过插槽名称访问插槽
扩展程序
- 一些实现提供了更多的运行时间自省和一些 CLOS 函数中的一些集成
CLOS classes
CLOS 是在 mid/late 80 年代基于两个早期的对象系统(Flavors 和 LOOPS)发明的。它提供:
- 一个定义宏
DEFCLASS
- 多重继承
- 用于创建、初始化等的协议
- CLOS 对象可以在 运行 时间根据 class 变化进行更改和更新(新插槽、重新定义的插槽、删除的插槽、更改的继承......)
- CLOS 对象可以更改其 class 并在 运行 时间更新
- 可以通过插槽名称访问
限制:
- 无默认值printer/reader
DEFCLASS
定义不是很简洁
扩展
- 通过添加特定于实现的功能来加快插槽访问速度
- 元对象协议提供了额外的功能和灵活性:内省和反射。有时只提供部分 MOP。
- 用户提供的扩展可用,特别是对于支持 MOP 的实现
Common Lisp
在某些情况下,Common Lisp 标准并未说明应如何实现功能:结构、classes,甚至可能是其他东西。示例是流和条件。如果 Common Lisp 实现对这些使用 CLOS,这通常是一个好兆头(为了增加灵活性)。
我对结构的理解是它有存储数据的槽,有类型,有 make-X
和槽访问函数,并且可以通过方法专门化(因为它有类型).
我对class的理解是它具有相同的多重继承。 this question 的最佳答案指出结构可以具有单一继承,并且 CLOS 的初始实现比结构 "much slower"。
根据人们谈论 CLOS 和结构的方式,我认为肯定还有一些其他差异,但我的琐碎 google 搜索毫无结果。所以我问:CLOS 和结构之间的实际区别是什么?
defstruct
在幕后为您做更多工作,例如:
- 自动定义插槽访问器
- 定义可读
print-object
方法
此外,结构槽访问速度更快(尽管差异可能无关紧要)。
底线是,除非您需要 MOPish 功能,否则您可以不用 defsrtuct
。
结构
Structures更原始。它们提供在编程语言中通常称为 record 的内容。它们是在 classes 之前发明的。 1984 年的 CLtL1(第一本描述 Common Lisp 的书)已经有了结构,后来又增加了一个称为 CLOS 的标准对象系统。结构提供
- 简洁的定义宏
DEFSTRUCT
- 单继承
- 快速插槽访问
- 定义 reader 和 setf 插槽访问权限
- 定义类型谓词
- 定义构造函数
- 定义一个复制函数
- 打印表示:可以读取和打印结构
- 以上函数可能是内联的
有用的补充:
- 除了结构类型之外,DEFSTRUCT 还可以定义基于列表和向量的结构表示
限制:
- 更改结构类型后,结构实例不会更新
- 如果更改了结构类型,最好重新编译并重新运行更改的代码。也许重新启动程序。重新定义结构的效果在标准 Common Lisp 中未定义。
- 很少自省:可移植的 Common Lisp 没有以简单的方式告诉我 super/sub-strucures 结构。可移植的 Common Lisp 没有告诉我结构的插槽。
- 默认情况下不通过插槽名称访问插槽
扩展程序
- 一些实现提供了更多的运行时间自省和一些 CLOS 函数中的一些集成
CLOS classes
CLOS 是在 mid/late 80 年代基于两个早期的对象系统(Flavors 和 LOOPS)发明的。它提供:
- 一个定义宏
DEFCLASS
- 多重继承
- 用于创建、初始化等的协议
- CLOS 对象可以在 运行 时间根据 class 变化进行更改和更新(新插槽、重新定义的插槽、删除的插槽、更改的继承......)
- CLOS 对象可以更改其 class 并在 运行 时间更新
- 可以通过插槽名称访问
限制:
- 无默认值printer/reader
DEFCLASS
定义不是很简洁
扩展
- 通过添加特定于实现的功能来加快插槽访问速度
- 元对象协议提供了额外的功能和灵活性:内省和反射。有时只提供部分 MOP。
- 用户提供的扩展可用,特别是对于支持 MOP 的实现
Common Lisp
在某些情况下,Common Lisp 标准并未说明应如何实现功能:结构、classes,甚至可能是其他东西。示例是流和条件。如果 Common Lisp 实现对这些使用 CLOS,这通常是一个好兆头(为了增加灵活性)。