我想知道symbol和enumerated类型之间的差异和关系是什么?
我在阅读符号类型
的第一个链接时生成了我的问题在最简单的实现中,它们(符号类型)是 基本上命名为整数(例如C中的枚举类型)。
我按照第二个链接阅读有关枚举类型的内容,但无法弄清楚它们的差异和关系。
例如,它们似乎同时存在于Common Lisp here和here中,但我的问题不仅限于CL,两篇维基百科文章也没有。
感谢。
答案 0 :(得分:4)
假设我们有几种文字样式:bold
,ìtalic
,thin
,regular
。现在我们有一个绘制一些文本的函数:
(defun draw-text-string (text style stream)
...)
整数枚举
我们如何传递样式信息?我们可以将它们编码为数字:
(defconstant +regular+ 0)
(defconstant +thin+ 1)
(defconstant +bold+ 2)
(defconstant +italic+ 3)
我们可以将它们编码为位:
(defconstant +regular+ #b0001) ; 1
(defconstant +thin+ #b0010) ; 2
(defconstant +bold+ #b0100) ; 4
(defconstant +italic+ #b1000) ; 8
通常,枚举类型会在类型声明后面隐藏这些映射。
当我们调用绘图函数时,我们以某种方式传递这些数字:
(draw-text-string "hello" +thin+ *standard-output*)
我们本来可以写的:
(draw-text-string "hello" 1 *standard-output*)
如果我们有位编码,我们也可以传递一个集合:
(draw-text-string "hello" (logxor +thin+ +italic+) *standard-output*)
(draw-text-string "hello" 10 *standard-output*)
优点是编码非常紧凑。如果我们调试程序,在Lisp中我们会看到数字。在静态类型语言中,调试器可以访问类型信息,并可以将值显示为名称。
这种枚举通常不在Lisp中完成 - 只有当需要与外部例程接口时,通常遵循C约定。
枚举值为符号
在Lisp中,人们也可以将符号用于此目的。作为单个符号或符号列表。这里符号本身就是值,它们不用作变量。
(draw-text-string "hello" 'thin *standard-output*)
(draw-text-string "hello" '(thin italic) *standard-output*)
在Common Lisp中,我们经常使用自我评估的关键字符号。然后我们不需要考虑包(名称空间)。
(draw-text-string "hello" :thin *standard-output*)
(draw-text-string "hello" '(:thin :italic) *standard-output*)
两者的优点是我们传递命名对象(符号),这在Lisp系统的调试过程中更容易理解。缺点是我们现在可以传递符号列表,这些符号的效率略低于数字或位向量。
运行时类型检查通常通过MEMBER类型完成。
答案 1 :(得分:1)
符号可以用于枚举类型的目的,但符号实际上并不是枚举类型,除非您考虑所有可能符号的集合(并且,假设符号可以无限长,则存在无限符号)可能的符号数)是一个枚举。
符号的优点以及它与枚举类似的主要方式是符号被实现。因此,如果您在一个源文件中编写'foo
而在另一个源文件中编写'foo
,则它们都会评估为相同的符号(它们将具有相同的对象标识)。这使得它们非常适合用作散列键,case
表达式等。