我有一個Java類Vector2
,我想說服Clojure閱讀器「很好地玩」。通過Clojure打印機和閱讀器往返Java類
(def a (vec2 1 2))
(print-str a)
=> "#<Vector2 [1 2]>"
理想我想這個類中,可以通過Clojure的閱讀器讀取的形式打印出來。即我想以下返回true:
(= a (read-string (print-str a)))
什麼是實現這種往返能力的最佳方式?
我有一個Java類Vector2
,我想說服Clojure閱讀器「很好地玩」。通過Clojure打印機和閱讀器往返Java類
(def a (vec2 1 2))
(print-str a)
=> "#<Vector2 [1 2]>"
理想我想這個類中,可以通過Clojure的閱讀器讀取的形式打印出來。即我想以下返回true:
(= a (read-string (print-str a)))
什麼是實現這種往返能力的最佳方式?
您需要爲您的班級/類型提供print-dup
和print-method
multimethods。
退房core.clj
例:
(import 'java.util.Hashtable)
(defmethod print-method Hashtable [x writer]
(binding [*out* writer]
(print (let [h (gensym)]
`(let [~h (Hashtable.)]
[email protected](map (fn [i]
`(.put ~h ~(str "\"" (.getKey i) "\"") ~(.getValue i) )) x) ~h))) ))
(def a (Hashtable.))
(.put a "a" 1)
(.put a "b" 2)
(= a (eval (read-string (print-str a))))
這似乎只包括寫作結束。它如何閱讀? – 2013-02-22 11:47:09
'read-string'用於閱讀。基本上這種multimethod會返回一個像'(vec2 1 2)'這樣的字符串格式的s表達式,當執行時會導致創建所需的對象 – Ankur 2013-02-22 11:54:02
這不是Mikera想要的:他不想將代碼「他的對象;他想**閱讀**,就像一個本地的Clojure矢量。 – 2013-02-22 12:30:02
你不想涉及'EvalReader',我想? – 2013-02-22 10:56:50
@Marko:對建議持開放態度。它並不專門用於外部API--更多的是爲了方便REPL和輕鬆的序列化/反序列化。 – mikera 2013-02-22 11:01:32
我認爲'read-eval'左爲真,讀者將知道如何處理'#=(Vector2.1 2)'。 – 2013-02-22 11:48:09