2010-09-10 16 views
5
(deftype Bag [state] 
    Object 
    (toString [bag] 
     (str "Bag???" state))) 

我想了toString看起來像什麼是良好的toString方法在Clojure的一個deftype'd對象

clojure.core=> (def b (Bag. {:apples 1 :bannanas 4})) 
#'clojure.core/b 
clojure.core=> (str b) 
"BAG: {:apples 1 :bannanas 4}" 

什麼是表示該信息的一個很好的方式clojurey? 是

"Bag/{:k :v}" 

更好?你怎麼稱呼你的toStrings?

回答

5

以下是deftype

user=> (deftype Bag [state] 
     Object 
     (toString [_] 
      (str "BAG: " (pr-str state)))) 
user.Bag 
user=> (def b (Bag. {:apples 1 :bannanas 4})) 
#'user/b 
user=> (str b) 
"BAG: {:bannanas 4, :apples 1}" 
6

取決於你想要做什麼,最簡單的方法是使用defrecord

 
user=> (defrecord Bag [state]) 
user.Bag 
user=> (def b (Bag. :foo)) 
#'user/b 
user=> b 
#:user.Bag{:state :foo} 

雖然你在上面看到的應該是pr,不str

 
user=> (str b) 
"[email protected]" 
user=> (prn b) 
#:user.Bag{:state :foo} 
nil 

所以我們只是做出改變:

 
user=> (defrecord Bag [state] 
     Object 
     (toString [bag] (pr-str bag))) 
user.Bag 
user=> (def b (Bag. :foo)) 
#'user/b 
user=> (str b) 
"#:user.Bag{:state :foo}" 
user=> (.toString b) 
"#:user.Bag{:state :foo}" 

現在,如果以上不適合,那麼下一個選項是在print-method多方法中增加一個新方法。谷歌周圍的細節。

另外:使用defrecord通常應優先於deftype,除非您的操作非常低級。

+0

定義低級別。我正在嘗試創建新的集合類型(包和多圖)。你什麼時候使用defrecord或deftype,爲什麼? – 2010-09-11 11:26:00

+0

在deftype中使用此方法會產生一個java.lang.StackOverflowError – 2010-09-11 11:35:10

+0

是的,如果您要創建新的集合類型,deftype可能是正確的,而defrecord在需要類似於某些域數據的結構時更合適。 – 2010-09-11 19:38:12

相關問題