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

Common lisp 将对象打印为唯一字符串,可能使用其地址,common-lisp,identity,clos,Common Lisp,Identity,Clos,我需要一种从CLOS对象创建GraphViz节点名称的方法,以使每个对象都有自己的节点,如果我更改对象并重新创建GraphViz可视化,我会为保持(参照)相同的对象获得相同的节点名称 如果我只是尝试打印我的对象,我会得到一些几乎不错的东西(因为我从不为我的类重写PRINT-object): CL-USER>(格式为nil“~A”*g*) "#" 是否有办法将1002D22C81部分作为字符串获取?然后,我可以从中创建GraphViz节点名称,如N1002D22C81 或者我应该通过抓取{}?之

我需要一种从CLOS对象创建GraphViz节点名称的方法,以使每个对象都有自己的节点,如果我更改对象并重新创建GraphViz可视化,我会为保持(参照)相同的对象获得相同的节点名称

如果我只是尝试打印我的对象,我会得到一些几乎不错的东西(因为我从不为我的类重写
PRINT-object
):

CL-USER>(格式为nil“~A”*g*)
"#"
是否有办法将
1002D22C81
部分作为字符串获取?然后,我可以从中创建GraphViz节点名称,如
N1002D22C81


或者我应该通过抓取
{}

之间的部分,将
(格式nil”~A“obj)
的结果作为字符串处理。它可以在垃圾收集后更改。您的实现可能提供了一个直接获取它的函数,但我认为您不应该使用它

你可以考虑的是在你的对象中添加一个<代码>名称< /Cord>时隙,并自动使用,例如,./P>初始化它们。 如果您想跟踪所有对象,您甚至可以将名称放在一个特殊的包中,并将其设置为对象(注意,这将使GC无法收集对象,直到您找到它们的名称,或取消设置它们的

符号值
,或)

注:即使覆盖了打印对象,也可以获取对象地址-只需将身份t传递给


PPS。我确信您知道
(格式为nil”~A“x)
(princ to string x)
相同,创建一个哈希表(可能)更便宜,然后使用
(setf(gethash(name node)*node table*)node)
(或者调用访问器和表的任何名称)。@Vatine:
符号值
只是一个插槽访问;它肯定比哈希表搜索便宜。不过,符号实习并不便宜。按名称查找符号(la
find symbol
)并不比哈希表搜索便宜。@Vatine:这两方面你都是对的。然而,我在这里的假设是,
intern
find symbol
在这种设置中都是罕见的,因为首先,创建比访问更为罕见,其次,用户将名称保留为符号,而不是字符串。此外,包操作可能比一般的哈希表更优化。是的,需要进行一些基准测试,以确定两种选择的确切性能成本。基于问题中提到的“alter”,我怀疑对象创建并不罕见。
CL-USER> (format nil "~A" *g*)
"#<GREF {1002D22C81}>"