Common lisp 如何在公共lisp中获取类的所有实例?

Common lisp 如何在公共lisp中获取类的所有实例?,common-lisp,clos,Common Lisp,Clos,假设我有一门课: (defclass person () ()) 然后我举了一些例子: (setf anna (make-instance 'person)) (setf lisa (make-instance 'person)) 如何获取对象本身或分配给它们的符号名称? 我想说一些像(查找实例的人),然后得到一些像(安娜·丽莎),或者至少是(##) 我正在搜索的是ruby中的等价物 我非常希望能够在没有外部库的情况下完成这项工作。据我所知,没有可移植的解决方案。如果你正在工

假设我有一门课:

(defclass person () ())
然后我举了一些例子:

(setf anna (make-instance 'person))    
(setf lisa (make-instance 'person))    
如何获取对象本身或分配给它们的符号名称?

我想说一些像
(查找实例的人)
,然后得到一些像
(安娜·丽莎)
,或者至少是
(##)

我正在搜索的是ruby中的等价物


我非常希望能够在没有外部库的情况下完成这项工作。

据我所知,没有可移植的解决方案。如果你正在工作,那么你可以做你想要的

(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>)
(defclassfoo())
(defvar*x*(使实例为“foo”)
(定义变量*y*(列表(使实例为'foo'))
(定义查找实例(n类)
(let((缓冲区(使数组n:填充指针0:初始元素nil)))
(ccl:映射堆对象(λ(x)
(当(和(类型P x类)(<(填充指针缓冲区)n))
(setf(aref缓冲区(填充指针缓冲区))x)
(incf(填充指针缓冲区‘‘‘)’)
缓冲区)
(查找实例2'foo)
==> (# #)

对于其他常见的Lisp实现,可能存在类似的解决方案。请注意,您必须对遍历可能会找到多少实例有一个初步的预感。原因是(正如Rainer Joswig所指出的),回调函数应该避免考虑。为了实现这一点,这个实现预先分配一个缓冲区,最多收集那么多实例。

据我所知,没有可移植的解决方案。如果你正在工作,那么你可以做你想要的

(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>)
(defclassfoo())
(defvar*x*(使实例为“foo”)
(定义变量*y*(列表(使实例为'foo'))
(定义查找实例(n类)
(let((缓冲区(使数组n:填充指针0:初始元素nil)))
(ccl:映射堆对象(λ(x)
(当(和(类型P x类)(<(填充指针缓冲区)n))
(setf(aref缓冲区(填充指针缓冲区))x)
(incf(填充指针缓冲区‘‘‘)’)
缓冲区)
(查找实例2'foo)
==> (# #)

对于其他常见的Lisp实现,可能存在类似的解决方案。请注意,您必须对遍历可能会找到多少实例有一个初步的预感。原因是(正如Rainer Joswig所指出的),回调函数应该避免考虑。为了实现这一点,这个实现预先分配一个缓冲区,最多收集那么多实例。

在Common Lisp中没有内置的

录制实例

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

迭代一个包的符号


如果您想知道某些或所有包的哪些符号具有CLOS实例作为值,您可以对它们进行迭代(
DO-symbols
DO-all-symbols
,…),并检查它们是否具有符号值,以及该符号值是否是某个类的实例。

在Common Lisp中没有类似的内置代码

录制实例

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

迭代一个包的符号


如果您想知道某些或所有包的哪些符号具有CLOS实例作为值,可以对它们进行迭代(
DO-symbols
DO-all-symbols
,…)并检查是否有符号值,以及该符号值是否是某个类的实例。

您在这里试图实现什么?TBH这更像是一项调试任务,而不是试图实现某种功能。我正在尝试获取
hunchentoot
*acceptor*
实例,以便停止正在运行的服务器。然而,
hunchentoot:*acceptor*
给了我一个错误,因为我必须在请求的上下文中请求接受方。然而,能够获得一个类的实例似乎很方便,我想我将来也可以使用它,用于调试、检查等。好吧,任何解决方案都将依赖于实现。对于CCL,请参见下面我的答案。我在SBCL手册中找不到类似的内容,而“lispworks堆行走”的谷歌搜索也没有产生任何结果。@RainerJoswig这只是一个例子。我编辑了它。这是一个老问题:你想在这里实现什么?TBH这更像是一个调试任务,而不是试图实现一些东西。我正在尝试获取
hunchentoot
*acceptor*
实例,以便停止正在运行的服务器。然而,
hunchentoot:*acceptor*
给了我一个错误,因为我必须在请求的上下文中请求接受方。然而,能够获得一个类的实例似乎很方便,我想我将来也可以使用它,用于调试、检查等。好吧,任何解决方案都将依赖于实现。对于CCL,请参见下面我的答案。我在SBCL手册中找不到类似的内容,而“lispworks堆行走”的谷歌搜索也没有产生任何结果。@RainerJoswig这只是一个例子。这是一个老问题:文档中说函数应该避免分配内存。因此,考虑到大量对象,会导致GC、mi