给定内容为1的变量,我知道它至少是五种类型的成员:
1 (let* ((fred 1))
2 (princ (typep fred 'bit)) (terpri)
3 (princ (typep fred 'integer)) (terpri)
4 (princ (typep fred 'fixnum)) (terpri)
5 (princ (typep fred 'rational)) (terpri)
6 (princ (typep fred t)) (terpri))
T
T
T
T
T
这里有两个问题。
给定具有任意内容的变量,如何确定其超类型路径?
我在哪里可以找到文档中的答案?
答案 0 :(得分:12)
您询问的是类型,而不是类。
您不能期望对您的问题有一个好的答案,因为您的号码1
所属的类型远远超过您真正关心的类型。
如,
(typep 1 '(integer -6 42))
==> T
如果您将注意力限制在Standardized Atomic Type Specifiers,则可以使用类似
的内容(defconstant *Standardized-Atomic-Type-Specifiers* ...) ; see Figure 4-2
(sort (remove-if-not (lambda (type) (typep 1 type))
*Standardized-Atomic-Type-Specifiers*)
#'subtypep)
==> (BIT FIXNUM UNSIGNED-BYTE SIGNED-BYTE INTEGER RATIONAL REAL NUMBER ATOM T)
现在,如果您愿意将自己的兴趣限制在类,那么情况会变得更易于管理。
首先,CLOS支持multiple inheritance,因此“超类路径”不是先验唯一定义的。
但是,已定义以确定method precedence order,此“路径”称为class precedence list。它由标准MOP函数compute-class-precedence-list
计算:
(compute-class-precedence-list (class-of 1))
==> (#<BUILT-IN-CLASS INTEGER> #<BUILT-IN-CLASS RATIONAL> #<BUILT-IN-CLASS REAL>
#<BUILT-IN-CLASS NUMBER> #<BUILT-IN-CLASS T>)
存在于大多数Common Lisp实现中(使用apropos
或find-all-symbols
来查找从中导出的包)。
您可以使用class-name
来获取类的名称而不是它们的元对象:
(mapcar #'class-name (compute-class-precedence-list (class-of 1)))
==> (INTEGER RATIONAL REAL NUMBER T)
请注意,bit
,fixnum
,unsigned-byte
,signed-byte
,atom
不在此列表中,因为它们未命名标准classes ,只是types。
答案 1 :(得分:2)
这不容易,IIRC。
我会以某种方式使用CLOS:
CL-USER 34 > (loop for c = (class-of 1)
then (first (class-direct-superclasses c))
collect (class-name c)
until (eq c (find-class t)))
(FIXNUM INTEGER RATIONAL REAL NUMBER T)
请注意,您需要CLOS实施提供的CLASS-DIRECT-SUPERCLASSES
。