首页 文章

如何在普通的lisp中获取类的所有实例?

提问于
浏览
0

想象一下我有一节课:

(defclass person () ())

然后我做了一些实例:

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

How can I get either the objects themselves or the symbol names they were assigned to?

我希望能够说出 (find-instances 'person) 之类的内容,并获得类似 (anna lisa) 或至少 (#<PERSON {100700E793}> #<PERSON {100700E793}>) 的内容 .

我搜索的内容相当于红宝石中的each_object .

我非常希望能够在没有外部库的情况下完成它 .

2 回答

  • 2

    据我所知,目前还没有便携式解决方案 . 如果您正在使用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>)
    

    其他Common Lisp实现可能存在类似的解决方案 . 请注意,您必须初步预测遍历可能找到的实例数 . 原因是,(如Rainer Joswig所说),回调函数应避免消耗 . 为了实现这一点,该实现预先分配缓冲区,并且最多收集许多实例 .

  • 6

    在Common Lisp中没有内置的东西 .

    Recording instances

    为了查找类的所有实例,通常会使类在实例创建时记录实例 . 可以想象出各种机制 . 有时人们仍然希望实例被垃圾收集 - 然后需要某种非标准的弱数据结构来实现 . 我希望,有一些库可以为CLOS实例实现类似的功能 .

    Iterating over symbols of a package

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

相关问题