2012-01-11 11 views
12

क्लोजर का उपयोग करके, मैं निम्न ऑब्जेक्ट कैसे बना सकता हूं? वस्तु जावा कोड से लिया जाता है (प्रभावी जावा से):मैं क्लोजर में जावा-जैसी ऑब्जेक्ट कैसे बना सकता हूं जो बिल्डर पैटर्न का उपयोग करता है?

NutritionFacts cocaCola = new NutritionFacts.Builder(240,8).calories(100).sodium(35).carbohydrate(27).build();

उत्तर

21

हालांकि यह अन्य उत्तर में कटाई से बहस करना मुश्किल है , .. कुछ हद तक बाहर हो गया है पक्ष के, अधिक बहुमुखी -> द्वारा प्रतिस्थापित किया गया। व्यक्तिगत तौर पर मैं पसंद करते हैं:

(-> (NutritionFacts$Builder. 240 8) 
    (.calories 100) 
    (.sodium 350) 
    (.carbohydrates 27) 
    (.build)) 

यह कुछ और वर्ण है, लेकिन आप दो बातें हासिल:

  • मुखरता। मैं सोडियम लाइन (उदाहरण के लिए) देख सकता हूं और बता सकता हूं कि यह जावा विधि कॉल है, क्योंकि . ठीक है।
  • लचीलापन। अगर मुझे इसकी ज़रूरत है, तो मैं बीच में कुछ गैर-विधि कॉल (इसे stdout, कहने के लिए प्रिंट कर सकता हूं), या इस सब के अंत में इसे किसी अन्य फ़ंक्शन कॉल में फ़ीड कर सकता हूं।

सबसे महत्वपूर्ण बात, इस सवाल का जवाब हर दूसरे classname गलत हो गया है: जावा के NutritionFacts.Builder असली JVM NutritionFacts $ बिल्डर नामित वर्ग से अधिक भाषा चीनी है, और उस वर्ग एक Clojure का उल्लेख करना चाहिए (क्योंकि है हम अपने कोड को संकलित करने के लिए जावैक का उपयोग नहीं कर रहे हैं)।

मैं doto सुझाव से सहमत है: यह काम करता है सिर्फ इसलिए कि इस बिल्डर वर्ग एक उदाहरण परिवर्तनशील है और फिर इसे वापस लौट कर अपने विधि चेन लागू करने के लिए होता है। doto जावा ऑब्जेक्ट्स के लिए बहुत बढ़िया है, जिसमें जगह-जगह उत्परिवर्तन की आवश्यकता होती है, लेकिन जब एक वर्ग अपने अपरिवर्तनीय नाटक करने के लिए पर्याप्त दयालु है तो आपको वास्तव में विधि-चेनिंग संस्करण (यानी ->) का उपयोग करना चाहिए।

3

मैं केवल Clojure के साथ शुरू कर रहा हूँ, लेकिन यह मेरे लिए मानक विधि मंगलाचरण की तरह दिखता है:

(doto 
    (NutritionFacts.Builder. 240 8) 
    (.carbohydrates 27) 
    (.sodium 35) 
    (.calories 100) 
    (.build) 
) 

संपादित करें :
@ गोरान जोविच बताते हैं, यह पहले फॉर्म में बनाए गए ऑब्जेक्ट पर सभी विधियों को कॉल करता है।
तो यह इस मामले में काम करता है क्योंकि जावा कोड विधि श्रृंखला का उपयोग करता है, लेकिन आमतौर पर लागू नहीं होता है।

+0

एकमात्र कारण यह मुहावरेदार नहीं है क्योंकि आप कई अलग रूपों में एक वर उत्परिवर्तित। बस इसे एक [डोटो] में लपेटें (https://github.com/clojure/clojure/blob/f5f827ac9fbb87e770d25007472504403ed3d7a6/src/clj/clojure/core।क्लोज # एल 33 9 5) और यह ठीक है! –

+0

@ गोरान जोविच मैंने आपके द्वारा सुझाए गए कोड को बदल दिया है। धन्यवाद! –

+0

हाँ, यह है। ध्यान दें कि 'doto' और' ..' के बीच मुख्य अंतर यह है कि पहले प्रारूप द्वारा परिभाषित एक ऑब्जेक्ट पर 'doto' कॉल विधियां, और '..' पिछले एक के परिणाम पर प्रत्येक आमंत्रण करता है। इस मामले में यह वही है क्योंकि जावा विधियां ऑब्जेक्ट बनने पर वापस आती रहती हैं। –

2

(.. (NutrionalFacts.Builder. 240 8) (calories 100) (sodium 35) (carbohydrates 27) (build))

8

उपयोग .. मैक्रो। यह लगातार दो बिंदु है। यह आपको केवल वही करने की इजाजत देता है - पिछली बार के परिणाम पर अगली जावा विधि को लगातार कॉल करने के लिए।

मैं चारों ओर एक आरईपीएल की जरूरत नहीं है, लेकिन अपने लाइन की तरह कुछ करने के लिए अनुवाद करते हैं चाहिए:

(.. (NutritionFacts.Builder. 240 8) 
    (calories 100) 
    (sodium 350) 
    (carbohydrates 27) 
    (build)) 
0

यह धागा कुछ साल पुराना है, और थ्रेड-प्रथम मैक्रो अभी भी वैसे ही पसंदीदा तरीका है जहां तक ​​मैं कह सकता हूं, लेकिन $ वाक्यविन्यास की आवश्यकता नहीं है। स्लैश (/) के रूप में अच्छी तरह से काम करता है:

(-> (Caffeine/newBuilder) 
     (.maximumSize 10000) 
     (.build)) 
+0

'(कैफीन/न्यूबिल्डर)' एक स्थिर विधि (जावा 'कैफीन.न्यूबिल्डर() ') के लिए एक कॉल है, जबकि' (पोषण संबंधी तथ्य $ बिल्डर।)' एक स्थिर वर्ग (जावा 'न्यू न्यूट्रिशनफैक्ट्स के निर्माता के लिए एक कॉल है। बिल्डर() '), इसलिए यह वास्तव में स्वीकार किए गए उत्तर से अलग नहीं है। – glts

+0

आह, ठीक है। मैंने सोचा कि वाक्यविन्यास के लिए कुछ अद्यतन था। धन्यवाद – Alex

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

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