Clojure/ClojureScript:如何为EDN标签字面量配置自定义打印实现?
自定义Clojure Record的pr-str输出格式
你需要为Ref record实现自定义的打印逻辑,Clojure中可以通过扩展打印相关多方法或实现特定接口来达成需求,以下是两种可行方案:
方案一:扩展print-method和print-dup多方法
通过扩展clojure.core/print-method(控制pr/pr-str的输出)和clojure.core/print-dup(适配序列化场景),自定义输出格式:
(ns my) (defrecord Ref [type id]) ;; 自定义pr-str的输出格式 (defmethod clojure.core/print-method Ref [ref ^java.io.Writer w] (.write w (str "#my.Ref [" (:type ref) " " (:id ref) "]"))) ;; 适配序列化场景的打印逻辑 (defmethod clojure.core/print-dup Ref [ref ^java.io.Writer w] (.write w (str "#my.Ref [" (:type ref) " " (:id ref) "]"))) (def rich (->Ref :Person 42)) (pr-str rich) ; 输出 "#my.Ref [:Person 42]"
方案二:实现IPrintWithWriter接口
在定义record时直接实现clojure.lang.IPrintWithWriter接口,将打印逻辑内聚到record定义中:
(ns my) (defrecord Ref [type id] clojure.lang.IPrintWithWriter (pr-writer [this writer opts] (.write writer (str "#my.Ref [" (:type this) " " (:id this) "]")))) (def rich (->Ref :Person 42)) (pr-str rich) ; 输出 "#my.Ref [:Person 42]"
可选:支持EDN反序列化
如果需要自定义格式能被clojure.edn/read-string正确解析,需要注册对应的读取器:
(clojure.edn/read-string {:readers {'my.Ref (fn [[type id]] (->Ref type id))}} "#my.Ref [:Person 42]") ;; 返回结果:#my.Ref{:type :Person, :id 42}
内容的提问来源于stack exchange,提问作者Witek
相关产品推荐
相关产品推荐

