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

मैं toStringक्या clojure में एक deftype'd वस्तु के लिए एक अच्छा toString विधि है

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

बेहतर? समुदाय आप अपने टूस्ट्रिंग को कैसे कॉल करते हैं?

उत्तर

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 बहु-विधि में एक नई विधि जोड़ना होगा। उस पर ब्योरे के लिए Google चारों ओर।

इसके अलावा: defrecord का उपयोग आमतौर पर deftype से अधिक होना चाहिए जबतक कि आप बहुत कम स्तर पर कुछ नहीं कर रहे हैं।

+0

निम्न स्तर को परिभाषित करें। मैं नए संग्रह प्रकार (बैग और मल्टीमैप्स) बनाने की कोशिश कर रहा हूं। आप defrecord या deftype का उपयोग कब करते हैं और क्यों? –

+0

डेफटाइप के साथ इस विधि का उपयोग एक java.lang.StackOverflowError –

+0

हां, यदि आप नया संग्रह प्रकार बना रहे हैं, तो डेफटाइप शायद सही है, जबकि कुछ डोमेन डेटा की संरचना की तरह कुछ की आवश्यकता होने पर defrecord अधिक उपयुक्त है। –

संबंधित मुद्दे