如何避免在使用 clojure 将 EDN 文件读取到 java 对象时打印对象哈希码



我已经为自定义标签定义了EDN读取器,该读取器会在出现自定义标签时创建新对象。 我正在使用 edn/read-string 来读取 EDN 数据。

(defn getXyz [str]
(.getXyz (XyzBuilder.) str)
)
(defn custom-readers []
{'xyz/builder getXyz}
)
(defn getSomeObj
[filename myEdnFile]
(edn/read-string
{:readers custom-readers}
(slurp myEdnFile))
)

我的 EDN 文件

{
"version" "1.0"
"xyz" #xyz/builder "testString"
}

当我从java打印getSomeObj的输出时,它会打印以下输出

{"version" "1.0", "Xyz" #object[com.java.sample.Xyz 0x6731787b "Xyz [type=type_1]"]}

我想避免在返回字符串中获取对象哈希码(即 #object[com.java.sample.Xyz 0x6731787b(。有没有办法实现它?

是的,您需要为其定义打印方法的自定义实现:

(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*为 true 时,您希望以机器可读的方式打印,以便edn/read-string可以再次读回它。

这是一个完整的示例,我使用了 StringBuilder 而不是 Xyz,sinc很方便,默认情况下它打印为对象内存位置(您所说的看起来像哈希(,就像您询问的那样。

(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}"

最新更新