是的,您需要为其定义打印方法的自定义实现:
(defmethod print-method Xyz [obj writer]
(.write writer (.getXyz obj)))
您应该用(.getXyz obj)
您想要打印的任何逻辑替换。
现在,最好提供一种逻辑用于以人类可读的方式进行打印,并提供一种用于以可以回读的方式进行打印的逻辑。因此,print
它将以人类可读pr
的方式打印,并且将以您可以使用自定义阅读器回读的方式打印。
(defmethod print-method Xyz [obj writer]
(if *print-readably*
(.write writer (str "#xyz/builder " "\"" (.getXyz obj) "\""))
(.write writer (.getXyz obj))))
当*print-readably*
为真时,您想以机器可读的方式打印,因此edn/read-string
可以再次读取它。
这是一个完整的示例,我使用 StringBuilder 而不是 Xyz,因为它很方便,并且默认情况下它打印为对象内存位置(您所说的看起来像哈希),就像您所要求的那样。
(defn getXyz [str]
(StringBuilder. str))
(defn custom-readers []
{'xyz/builder getXyz})
(defn getSomeObj
[]
(edn/read-string
{:readers (custom-readers)}
"{\"version\" \"1.0\"
\"xyz\" #xyz/builder \"testString\"}"))
(defmethod print-method StringBuilder [obj writer]
(if *print-readably*
(.write writer (str "#xyz/builder " "\"" (.toString obj) "\""))
(.write writer (str "The xyz is: " (.toString obj)))))
(getSomeObj)
;; => {"version" "1.0", "xyz" #xyz/builder "testString"}
(pr-str (getSomeObj))
;; => "{\"version\" \"1.0\", \"xyz\" #xyz/builder \"testString\"}"
(print-str (getSomeObj))
;; => "{version 1.0, xyz The xyz is: testString}"