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

时间:2013-02-13 13:27:50

标签: common-lisp identity clos

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

如果我只是尝试打印我的对象,我会得到一些差不多好的东西(因为我从不为我的班级覆盖PRINT-OBJECT):

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

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

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

1 个答案:

答案 0 :(得分:8)

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

您可能会考虑做的是在对象中添加name广告位并使用gensym自动初始化它们。

如果您想跟踪所有对象,甚至可能会intern特殊包中的名称并将symbol-value设置为对象(提防将使GC对象无法收集,直到您unintern他们的名字,或取消设置他们的symbol-valuedelete the aforementioned special package)。

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

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