如何在公共lisp中获得类的所有实例

  • 本文关键字:实例 lisp common-lisp clos
  • 更新时间 :
  • 英文 :


假设我有一个类:

(defclass person () ())

然后我创建了一些实例:

(setf anna (make-instance 'person))    
(setf lisa (make-instance 'person))    

如何获得对象本身或它们被分配给的符号名称?

我希望能够说出类似(find-instances 'person)的东西,然后得到类似(anna lisa)或至少(#<PERSON {100700E793}> #<PERSON {100700E793}>)的东西。

我要找的是ruby中each_object的等价物。

Common Lisp中没有这样的内置功能。

<<p> 记录实例/strong>

为了找到一个类的所有实例,通常会让类在实例创建时记录实例。我们可以想象不同的机制。有时仍然希望对实例进行垃圾收集——那么就需要某种非标准的数据结构来实现这一点。我希望有一些库可以为CLOS实例实现类似的东西。

遍历包的符号

如果您想知道某些或所有包的哪些符号具有CLOS实例作为值,您可以遍历它们(DO-SYMBOLS, DO-ALL-SYMBOLS,…)并检查是否有符号值以及该符号值是否为某个类的实例。

据我所知,没有可移植的解决方案。如果您正在使用CCL,那么map-heap-objects可能会做您正在寻找的

(defclass foo () ())
(defvar *x* (make-instance 'foo))
(defvar *y* (list (make-instance 'foo)))
(defun find-instances (n class)
  (let ((buffer (make-array n :fill-pointer 0 :initial-element nil)))
    (ccl:map-heap-objects (lambda (x)
                            (when (and (typep x class) (< (fill-pointer buffer) n))
                              (setf (aref buffer (fill-pointer buffer)) x)
                              (incf (fill-pointer buffer)))))
     buffer))
(find-instances 2 'foo)
==> (#<FOO #x30200126F40D> #<FOO #x30200126634D>)
类似的解决方案可能存在于其他公共Lisp实现中。注意,您必须对遍历可能找到多少实例有一个初步的预感。原因是(正如Rainer Joswig所指出的)回调函数应该避免混淆。为了实现这一点,这个实现预先分配一个缓冲区,并最多收集那么多个实例。

相关内容

  • 没有找到相关文章

最新更新