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

在使用clojure将EDN文件读入java对象时,如何避免打印对象哈希代码,clojure,clojure-java-interop,edn,Clojure,Clojure Java Interop,Edn,我已经为自定义标记定义了EDN阅读器,它在出现自定义标记时创建新对象。 我正在使用edn/读取字符串来读取edn数据 (defn getXyz [str] (.getXyz (XyzBuilder.) str) ) (defn custom-readers [] {'xyz/builder getXyz} ) (defn getSomeObj [filename myEdnFile] (edn/read-string {:readers cus

我已经为自定义标记定义了EDN阅读器,它在出现自定义标记时创建新对象。 我正在使用edn/读取字符串来读取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]"]}

我希望避免在返回字符串中获取对象hashcode(即#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 readable*
为真时,您希望以机器可读的方式打印,以便
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}"