我需要一种从 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/