दिलचस्प पोस्ट
आर में एक मैट्रिक्स के पंक्तिवार विचरण Django- पंजीकरण, अद्वितीय ई-मेल को बल दें मैं निश्चित आदेश को हर डेढ़ घंटे चलाने के लिए क्रॉन कैसे सेट कर सकता हूं? स्पिनर में लटकती तीर कैसे सेट करें? केवल नवीनतम प्रतिबद्ध के लिए GitHub पर पुल अनुरोध भेजें सीएसएस के साथ दूसरे अंतिम तत्व का चयन करें क्यों करता है collections.shuffle () मेरी सरणी के लिए विफल? स्विफ्ट 3.0 में यूआईवीआईयूईई () कंस्ट्रक्टर का क्या हुआ? सर्वर से PHP / जावास्क्रिप्ट के साथ सूचनाएं पुश करें SQL में तालिका पंक्तियों के लिए सीमा निर्धारित करें JQuery के साथ टाइपराइटर प्रभाव स्वचालित HTTPS कनेक्शन / नोड.जेएस / एक्सप्रेस के साथ रीडायरेक्ट क्या हेक स्टडी :: डेक के स्मृति ओवरहेड के साथ चल रहा है? पायथन में स्पष्ट 'स्व' कैसे बचें? Image.FromStream () विधि अमान्य तर्क अपवाद देता है

क्लोज़र: स्ट्रिंग क्लास नाम से नया इंस्टेंस बना रहा है

क्लोज़र में, एक स्ट्रिंग के रूप में एक क्लास का नाम दिया गया, मुझे क्लास का एक नया इंस्टेंस बनाना होगा। दूसरे शब्दों में, मैं नए-उदाहरण-से-क्लास-नाम को कैसे कार्यान्वित करूंगा

(def my-class-name "org.myorg.pkg.Foo") ; calls constructor of org.myorg.pkg.Foo with arguments 1, 2 and 3 (new-instance-from-class-name my-class-name 1 2 3) 

मैं एक समाधान की तुलना में अधिक सुंदर दिख रहा हूं

  • क्लास से एक कन्स्ट्रक्टर पर जावा नई इंस्टासेंस विधि को बुला रहा है
  • eval, लोड-स्ट्रिंग, … का उपयोग कर

व्यवहार में, मैं इसे defrecord का उपयोग कर बनाया वर्गों पर प्रयोग करेंगे। इसलिए यदि उस परिदृश्य के लिए कोई विशेष सिंटैक्स है, तो मुझे काफी दिलचस्पी होगी।

Solutions Collecting From Web of "क्लोज़र: स्ट्रिंग क्लास नाम से नया इंस्टेंस बना रहा है"

ऐसा करने के दो अच्छे तरीके हैं कौन सा सबसे अच्छा विशिष्ट परिस्थितियों पर निर्भर करता है।

पहला प्रतिबिंब है:

 (Clojure.lang.Reflector / invokeConstructor
   (संकल्प (प्रतीक "पूर्णांक"))
   (टू-अरैम ["16"]))

यह बुला (new Integer "16") … इसमें किसी भी अन्य सीटीओआर तर्क को आप को सरणी वेक्टर में शामिल करना है। यह आसान है, लेकिन पर्याप्त प्रकार संकेतों के साथ new का उपयोग करने से रनटाइम पर धीमा है

दूसरा विकल्प जितना तेज़ हो सके, लेकिन थोड़ा और अधिक जटिल है, और eval का उपयोग करता है:

 (बनाओ कारखाने [वर्गनाम और प्रकार]
   (चलिए [आर्ग (मैप # (मेटा (प्रतीक (str "x"% 2)) {: tag% 1}) प्रकार (श्रेणी))]
     (eval `(fn [~ @ args] (नया ~ (प्रतीक वर्गनाम) ~ @ आर्ग्स)))))

 (def int- कारखाना (मेक-फैक्ट्री "पूर्णांक" 'स्ट्रिंग))

 (इंट फैक्ट्री "42")

कुंजी बिंदु eval कोड है जो एक अनाम फ़ंक्शन को परिभाषित करता है, क्योंकि make-factory करता है। यह धीमी गति से ऊपर प्रतिबिंब के उदाहरण की तुलना में धीमी है, इसलिए केवल इसे जितना संभव हो उतना संभव नहीं है जैसे प्रति वर्ग एक बार। लेकिन ऐसा करते हुए कि आपके पास एक नियमित क्लोज़र फ़ंक्शन होता है जो कि आप इस उदाहरण में int-factory जैसे किसी स्थान में, या किसी हैश-मैप या सदिश में कहीं भी स्टोर कर सकते हैं, इस पर निर्भर करते हुए कि आप इसका उपयोग कैसे करेंगे। भले ही, यह फैक्ट्री फ़ंक्शन पूरी संकलित गति से चलेगा, हॉटस्पॉट आदि द्वारा इनलाइन किया जा सकता है और प्रतिबिंब के उदाहरण से हमेशा बहुत तेज़ चलता रहेगा।

जब आप विशिष्ट रूप से deftype या defrecord द्वारा उत्पन्न वर्गों से व्यवहार करते हैं, तो आप प्रकार सूची को छोड़ सकते हैं क्योंकि उन कक्षाओं में हमेशा अलग-अलग विभिन्नताएं होती हैं। यह कुछ ऐसा अनुमति देता है:

 (रिकॉर्ड-फैक्टरी [रिकॉर्ड का नाम]
   (चलो [रिकॉर्ड वर्ग ^ वर्ग (हल (प्रतीक रिकॉर्ड नाम))
         अधिकतम- आर्ग-गणना (अधिकतम लागू करें (नक्शा # (गणना (.getParameterTypes%))
                                       (.getConstructors रिकॉर्ड वर्ग)))
         आर्ग (नक्शा # (प्रतीक (str "x"%)) (श्रेणी (- अधिकतम-आर्ग-गिनती 2)))]
     (eval `(fn [~ @ args] (नया ~ (प्रतीक रिकॉर्ड नाम) ~ @ आर्ग्स)))))


 (defrecord उदाहरणरेकॉर्ड [एबीसी])

 (डेफ उदाहरण-रिकार्ड-फैक्टरी (रिकार्ड-फैक्ट्री "उदाहरणरेकॉर्ड"))

 (उदाहरण-रिकार्ड-कारखाना "एफ" "स्कॉट" फिजराल्ड़)

चूंकि 'नया' एक विशेष रूप है, मुझे यकीन नहीं है कि आप मैक्रो के बिना ऐसा कर सकते हैं। मैक्रो का उपयोग करके इसे करने का एक तरीका है:

 user=> (defmacro str-new [s & args] `(new ~(symbol s) ~@args)) #'user/str-new user=> (str-new "String" "LOL") "LOL" 

इस मैक्रो की सीमाओं पर मीकल की टिप्पणी देखें

रिकॉर्ड संस्करणों (या तो नया या मौजूदा रिकॉर्ड पर आधारित) के निर्माण के लिए स्वचालित रूप से अच्छी तरह से नामित कन्स्ट्रक्टर फ़ंक्शंस बनाने के लिए defrecord का विस्तार करने के लिए यहां एक तकनीक है।

http://david-mcneil.com/post/765563763/enhanced-clojure-records

क्लोज़र 1.3 में, defrecord स्वचालित रूप से "->" तैयार नाम के साथ रिकॉर्ड नाम का उपयोग करके एक फ़ैक्टरी फ़ंक्शन को अवरुद्ध करेगा। इसी तरह, एक नक्शा लेते हुए एक संस्करण "मैप->" के साथ प्रीपेड रिकॉर्ड नाम होगा।

 user=> (defrecord MyRec [ab]) user.MyRec user=> (->MyRec 1 "one") #user.MyRec{:a 1, :b "one"} user=> (map->MyRec {:a 2}) #user.MyRec{:a 2, :b nil} 

इस प्रकार की मैक्रो रिकॉर्ड प्रकार के स्ट्रिंग नाम से एक उदाहरण बनाने के लिए काम करनी चाहिए:

 (defmacro newbie [recname & args] `(~(symbol (str "->" recname)) ~@args))