krz*_*z00 11 lisp serialization common-lisp clos
如果你想使CLOS对象成为常见的lisp可打印(可读打印),那么如何在不使用打印和读取的情况下进行此操作.
这有两个部分,至少在我的解决方案中,但是你将需要这个功能(感谢cl-prevalence的人(警告LLGPL)
(defun get-slots (object)
;; thanks to cl-prevalence
#+openmcl
(mapcar #'ccl:slot-definition-name
(#-openmcl-native-threads ccl:class-instance-slots
#+openmcl-native-threads ccl:class-slots
(class-of object)))
#+cmu
(mapcar #'pcl:slot-definition-name (pcl:class-slots (class-of object)))
#+sbcl
(mapcar #'sb-pcl:slot-definition-name (sb-pcl:class-slots (class-of object)))
#+lispworks
(mapcar #'hcl:slot-definition-name (hcl:class-slots (class-of object)))
#+allegro
(mapcar #'mop:slot-definition-name (mop:class-slots (class-of object)))
#+sbcl
(mapcar #'sb-mop:slot-definition-name (sb-mop:class-slots (class-of object)))
#+clisp
(mapcar #'clos:slot-definition-name (clos:class-slots (class-of object)))
#-(or openmcl cmu lispworks allegro sbcl clisp)
(error "not yet implemented"))
Run Code Online (Sandbox Code Playgroud)
然后,为了阅读,你需要运行这段代码,它设置了1/2的语法 { type-of-object ((slot-name . slot-value) (slot-name . slot-value) ...)
(set-macro-character
#\{
#'(lambda (str char)
(declare (ignore char))
(let ((list (read-delimited-list #\} str t)))
(let ((type (first list))
(list (second list)))
(let ((class (allocate-instance (find-class type))))
(loop for i in list do
(setf (slot-value class (car i)) (cdr i)))
class)))))
Run Code Online (Sandbox Code Playgroud)
用于打印,使用
(defmethod print-object ((object standard-object) stream)
(format stream "{ ~s ~s}" (type-of object)
(loop for i in (get-slots object)
collect (cons i (slot-value object i)))))
Run Code Online (Sandbox Code Playgroud)
*print-readably*
使用所有这些方法时,强烈建议使用A. 另请注意,循环关系未经测试