有没有一种方法可以获取一个类的槽位?

12

我有一个像这样的类

(defclass shape ()
 ((color :initform :black)
 (thickness :initform 1)
 (filledp :initform nil)
 (window :initform nil)))

如果我只知道这个类的实例,是否有一个common-lisp函数能够获取该类的这些插槽(slot)的列表?


1
密切相关:https://dev59.com/W5nga4cB1Zd3GeqPTA4i - coredump
好的,谢谢你们的回答。但我有另一个问题。我需要知道类中的每个方法,包括继承类中的方法。 (defclass point (shape) ((x :initform 0) (y :initform 0))) 有没有办法获取它? - Micky
请查看链接中的问题。 - coredump
但是我不能使用任何外部库。 - Micky
1个回答

21

许多通用Lisp实现支持CLOS 元对象协议,这为类、插槽和其他元对象提供了内省操作。

在LispWorks中,相应的函数可以直接在CL-USER包中访问。

CL-USER 139 > (defclass shape ()
                ((color :initform :black)
                 (thickness :initform 1)
                 (filledp :initform nil)
                 (window :initform nil)))
#<STANDARD-CLASS SHAPE 40202910E3>

CL-USER 140 > (mapcar #'slot-definition-name
                      (class-direct-slots (class-of (make-instance 'shape))))
(COLOR THICKNESS FILLEDP WINDOW)

函数 slot-definition-nameclass-direct-slots 是 CLOS 的元对象协议定义的,并在许多 Common Lisp 实现中得到支持 - 只是它们所在的包可能不同。例如,在 SBCL 中,您可能会在包 SB-MOP 中找到它们。

从一个类中,我们可以获得直接slot列表。 直接 slot 是为该类直接定义且未继承的 slot。 如果您想获取所有 slot 的列表,则使用函数 class-slots

Slot 在此处表示我们获得一个slot定义对象,该对象描述了该slot。 要获取slot的名称,您必须使用函数 slot-definition-name 从slot定义对象中检索名称。


1
@Micky 请参考 https://github.com/pcostanza/closer-mop。你也可以使用 (apropos 'slot-definition-name) 来查找这些函数在你的实现中定义在哪些包中。 - coredump
1
@coredump 谢谢,这帮助我弄清楚了如何在sbcl上运行它。 - Pascal
2
(mapcar #'sb-mop:slot-definition-name (sb-mop:class-direct-slots (class-of (make-instance 'shape)))) - Pascal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接