common-lisp - 将对象打印为唯一字符串,可能使用其地址

标签 common-lisp identity clos

我需要一种从 CLOS 对象创建 GraphViz 节点名称的方法,这样每个对象都有自己的节点,如果我改变我的对象并重新创建 GraphViz 可视化,我会得到相同的对象节点名称保持(引用)相同。

如果我只是尝试打印我的对象,我会得到几乎不错的东西(因为我从不为我的类(class)覆盖 PRINT-OBJECT):

CL-USER> (format nil "~A" *g*)
"#<GREF {1002D22C81}>"

有没有办法将 1002D22C81 部分作为字符串?然后我可以从中创建像 N1002D22C81 这样的 GraphViz 节点名称。

或者我应该通过抓取 {} 之间的部分将 (format nil "~A"obj) 的结果作为字符串处理?

最佳答案

十六进制数是对象地址。它可以在垃圾回收后更改。您的实现可能会提供一个函数来直接获取它,但我认为您不应该使用它。

您可能会考虑为您的对象添加一个 name 槽,并使用 gensym 等自动初始化它们。 .

如果您想跟踪所有对象,您甚至可以 intern特殊包中的名称并设置它们的symbol-value到对象(注意,这将使对象 无法被 GC 收集,直到您 unintern 他们的名字,或取消设置他们的 symbol-value , 或 delete the aforementioned special package )。

PS。即使覆盖 print-object 也可以获得对象地址 - 只需将 :identity t 传递给 print-unreadable-object .

PPS。我相信您知道 (format nil "~A"x)(princ-to-string x) 相同。

关于common-lisp - 将对象打印为唯一字符串,可能使用其地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14854661/

相关文章:

common-lisp - 常见的 lisp : Can I define a function with arbitrary number of args and optional keyword args?

sql-server - SQL Server 查询查找聚集索引

lisp - CLOS 插槽访问器 : read but not write

lisp - CLOS 中的构造函数等价于什么?

common-lisp - 在Common Lisp中定义setf-expanders

character-encoding - 如何处理 Common Lisp (SBCL) 中的重音符号?

linux - Windows Server 2012 R2 NFS 身份映射 linux 客户端

c# - 通过外部(自定义)服务的 ASP 核心登录

Lisp:如何在 initialize-instance :around 方法中获取创建的实例

recursion - Scheme 中的 Mandelbrot 集实现非常慢