如何在普通的 lisp 中获取 class 的所有实例?
How to get all instances of a class in common lisp?
假设我有一个 class:
(defclass person () ())
然后我举一些例子:
(setf anna (make-instance 'person))
(setf lisa (make-instance 'person))
如何获取对象本身或分配给它们的符号名称?
我希望能够说 (find-instances 'person)
并得到 (anna lisa)
或至少 (#<PERSON {100700E793}> #<PERSON {100700E793}>)
.
我要搜索的是ruby中的each_object。
我非常希望能够在没有外部库的情况下做到这一点。
据我所知,没有可移植的解决方案。如果你正在做CCL, then 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 指出的那样),回调函数应该避免 consing。为了实现这一点,此实现预先分配一个缓冲区,并最多收集那么多实例。
Common Lisp 中没有内置的东西。
录制实例
为了找到一个class的所有实例,通常会让class记录实例创建时的实例。人们可以想象各种机制。有时人们仍然希望实例被垃圾收集——然后需要某种非标准的 weak 数据结构来做到这一点。我希望有一些库可以为 CLOS 实例实现类似的东西。
迭代包的符号
如果您想知道某些或所有包的哪些符号具有 CLOS 实例作为值,您可以迭代它们(DO-SYMBOLS
、DO-ALL-SYMBOLS
、...)并检查是否它们有一个符号值,如果该符号值是某个 class.
的实例
假设我有一个 class:
(defclass person () ())
然后我举一些例子:
(setf anna (make-instance 'person))
(setf lisa (make-instance 'person))
如何获取对象本身或分配给它们的符号名称?
我希望能够说 (find-instances 'person)
并得到 (anna lisa)
或至少 (#<PERSON {100700E793}> #<PERSON {100700E793}>)
.
我要搜索的是ruby中的each_object。
我非常希望能够在没有外部库的情况下做到这一点。
据我所知,没有可移植的解决方案。如果你正在做CCL, then 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 指出的那样),回调函数应该避免 consing。为了实现这一点,此实现预先分配一个缓冲区,并最多收集那么多实例。
Common Lisp 中没有内置的东西。
录制实例
为了找到一个class的所有实例,通常会让class记录实例创建时的实例。人们可以想象各种机制。有时人们仍然希望实例被垃圾收集——然后需要某种非标准的 weak 数据结构来做到这一点。我希望有一些库可以为 CLOS 实例实现类似的东西。
迭代包的符号
如果您想知道某些或所有包的哪些符号具有 CLOS 实例作为值,您可以迭代它们(DO-SYMBOLS
、DO-ALL-SYMBOLS
、...)并检查是否它们有一个符号值,如果该符号值是某个 class.