数据类型:符号vs枚举?

时间:2014-08-06 21:49:32

标签: c types enums lisp symbols

我想知道symbolenumerated类型之间的差异和关系是什么?

我在阅读符号类型

的第一个链接时生成了我的问题
  

在最简单的实现中,它们(符号类型)是   基本上命名为整数(例如C中的枚举类型)。

我按照第二个链接阅读有关枚举类型的内容,但无法弄清楚它们的差异和关系。

例如,它们似乎同时存在于Common Lisp herehere中,但我的问题不仅限于CL,两篇维基百科文章也没有。

感谢。

2 个答案:

答案 0 :(得分:4)

假设我们有几种文字样式:boldìtalicthinregular。现在我们有一个绘制一些文本的函数:

(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表达式等。