Common Lisp遍历符号列表调用print-object实现自定义输出问题
问题根因
你定义的*master-list*中存储的不是CLOS对象实例本身,而是绑定了CLOS实例的符号。你硬编码调用(print-object foo::my-object *)时,foo::my-object会先求值得到绑定的实例,所以能匹配你自定义的print-object方法输出预期格式;而遍历列表时你直接把符号传给print-object,泛型函数会匹配系统默认的符号类型打印方法,自然只会输出符号名。
解决方案
方案1:保留现有符号列表结构,遍历取值
如果确实需要全局列表存储符号,遍历的时候先取符号的绑定值再调用打印:
(defun show-all (&optional (stream *standard-output*)) "Print summaries for all objects in the current environment" (dolist (sym *master-list*) ;; 先取符号绑定的实例,可增加类型校验避免异常 (let ((instance (symbol-value sym))) (print-object instance stream) (terpri stream))))
方案2:优化全局列表存储逻辑(更推荐)
修改*master-list*的填充逻辑,直接存储CLOS实例而非符号,原有打印逻辑无需调整即可生效:
;; 填充列表时直接存入实例,不要加引号转成符号 (push foo::my-object *master-list*) ;; 错误写法示例:(push 'foo::my-object *master-list*) 该写法会存入符号而非实例
补充说明
print-object是标准泛型函数,依赖第一个参数的类型做方法分发,只有传入你定义的CLOS类的实例时,才会匹配你自定义的打印方法,传入其他类型对象会走对应的默认打印逻辑。
内容的提问来源于stack exchange,提问作者CL-USER
相关产品推荐
相关产品推荐

