2010-09-14 15 views
17

के "प्रकार" समारोह के लिए कुछ कॉल की कोशिश करते हैं:फ़ंक्शन किस प्रकार का है?

user=> (type 10) 
java.lang.Integer 

user=> (type 10.0) 
java.lang.Double 

user=> (type :keyword?) 
clojure.lang.Keyword 

और अब एक गुमनाम समारोह के साथ:

user=> (type #(str "wonder" "what" "this" "is")) 
user$eval7$fn__8 

ए) इसका क्या मतलब "उपयोगकर्ता $ eval7 $ fn__8" करता है? बी) और किस प्रकार का फ़ंक्शन है?

"प्रकार" के लिए स्रोत है:

user=> (source type) 
(defn type 
    "Returns the :type metadata of x, or its Class if none" 
    {:added "1.0"} 
    [x] 
    (or (:type (meta x)) (class x))) 
nil 

तो एक समारोह मेटा डेटा के एक विशिष्ट भाग एक वर्ग

एक गुमनाम समारोह पैदावार नाडा के मेटा जाँच है या होने की जरूरत है:

user=> (defn woot [] (str "wonder" "what" "this" "is")) 
#'user/woot 
user=> (meta woot) 
{:ns #<Namespace user>, :name woot} 
:
user=> (meta #(str "wonder" "what" "this" "is")) 
nil 

एक अलग दृष्टिकोण की कोशिश कर रहा

सी) लगता है कि कुछ मेटा है लेकिन मुझे लगा कि यह "woot" प्रतीक का मेटा है, है ना?

के बारे में "या" दूसरी छमाही क्या:

user=> (class #(str "wonder" "what" "this" "is")) 
user$eval31$fn__32 

user=> (class woot) 
user$woot 

ये क्या हैं: "उपयोगकर्ता $ eval31 $ fn__32" और "उपयोगकर्ता $ woot" और वे कहाँ से आते हैं?

"वर्ग" समारोह पैदावार बाहर की जाँच:

user=> (source class) 
(defn ^Class class 
    "Returns the Class of x" 
    {:added "1.0"} 
    [^Object x] (if (nil? x) x (. x (getClass)))) 
nil 

और आगे की जांच की पैदावार:

user=> (.getClass #(str "wonder" "what" "this" "is")) 
user$eval38$fn__39 

user=> (.getClass woot) 
user$woot 

मैं इसे नहीं मिलता है। डी) क्या यह हैशकोड है: eval38 $ fn__39? ई) क्या यह एक प्रतीक है: woot?

एफ) फ़ंक्शन में कोई प्रकार क्यों नहीं है? क्या यह आईएफएन या कुछ नहीं होना चाहिए?

+3

स्पष्ट रूप से, प्रत्येक कार्य अपने स्वयं के प्रकार को परिभाषित करता है (यह कम से कम बंद होने के लिए कुछ हद तक व्यवहार्य है)। आप जो देख रहे हैं वह उस फ़ंक्शन के लिए स्वचालित रूप से परिभाषित प्रकार है। क्लोजर फू की कमी, मैं इसे एक टिप्पणी के रूप में छोड़ दूंगा। –

उत्तर

14

क्लोजर JVM पर बनाया गया है।

जेवीएम बॉक्स के बाहर प्रथम श्रेणी के कार्यों, या लैम्बडा का समर्थन नहीं करता है। प्रत्येक क्लोजर फ़ंक्शन, इसे संकलित करने के बाद, JVM के परिप्रेक्ष्य से अपनी अज्ञात कक्षा बन जाता है। प्रत्येक कार्य तकनीकी रूप से, यह स्वयं का प्रकार है।

यह वर्ग आईएफएन लागू करता है, लेकिन जब आप इसे टाइप करते हैं, तो यह आपको अज्ञात वर्ग का नाम देता है जो हर बार अलग होता है।

1

मैं एक क्लोजर नौसिखिया हूं लेकिन मैं बोल्ड होने जा रहा हूं। सबसे पहले हमारे पास एक समारोह के "प्रकार" के लिए दो अलग-अलग अर्थ हैं, एक, जावा इंटरफेस और क्लोजर इंटर्नल्स के वर्ग और प्रोग्रामिंग अवधारणा के रूप में फ़ंक्शन का प्रकार।दूसरा दृष्टिकोण एक समारोह के प्रकार उठाते हुए अपनी वापसी मूल्य (या इसके पैरामीटर प्रकार और वापसी मान प्रकार) के प्रकार होगा:

1) मैं सभी कार्यों लगता है कि लागू करता है IFn इंटरफेस, जो कुछ भी उनके मौजूदा वर्ग

2) फ़ंक्शन अज्ञात या नामित होने पर क्लोजर diffs द्वारा स्वचालित रूप से उत्पन्न क्लास नाम है, लेकिन ऐसा लगता है कि दोनों मामलों में आंतरिक कक्षाएं हैं (टिपली रूप से उनके नाम $ 500 से अलग होते हैं और बाहरी कक्षाओं से आंतरिक में जाते हैं)

3) लौटाए गए मान का प्रकार फ़ंक्शन मेटाडेटा की टैग कुंजी में हो सकता है यदि आप इसे फ़ंक्शन परिभाषा में एनोटेट करते हैं। उदा आपके द्वारा खुलासा किया गया फ़ंक्शन क्लास क्लास के रूप में इसके लौटा प्रकार के कारण के रूप में होता है, वहां नाम से पहले^वर्ग होता है।

मैं यह सोचते हैं रहा हूँ आप, जावा (या इसी तरह की OOP लैंग) से परिचित खेद है नहीं

+2

मैं जावा डेवलपर हूं, इसलिए हम ठीक हैं :) मेरा सवाल है: आप क्यों मानेंगे कि "फ़ंक्शन का प्रकार इसके वापसी मूल्य का प्रकार होगा"? (मेरा मतलब है क्लोजर में कार्य प्रथम श्रेणी की वस्तुएं हैं, इसलिए उनके पास अपनी आत्मा है: पी) – Belun

+0

जूम क्योंकि "फ़ंक्शन के प्रकार" की दो संभावित इंद्रियों के बीच अंतर। यह मेरे लिए स्पष्ट है अब आप फ़ंक्शन के प्रकार के बारे में बात करते हैं जैसे कि जावा ऑब्जेक्ट के प्रकार क्लोजर/जेवीएम इंटर्नल्स में और फ़ंक्शन के हस्ताक्षर के प्रकार के रूप में नहीं। भ्रम के लिए खेद है – jneira

18

एक समारोह प्रकार clojure.lang.IFn है, जो एक जावा इंटरफ़ेस है की है अगर।

प्रत्येक क्लोजर फ़ंक्शन जावा क्लास में संकलित किया गया है जो clojure.lang.IFn लागू करता है। नाम user$eval7$fn__8 उस वर्ग का "बाइनरी क्लास नाम" है, यानी, इसका आंतरिक नाम JVM में है।

+1

फ़ंक्शन का प्रकार क्यों नहीं है: clojure.lang.IFn? – Belun

+4

क्योंकि जब वर्ग कक्षा बी लागू करता है तो यह अभी भी बी नहीं है। –

3

यहाँ API docs

Returns the :type metadata of x, or its Class if none 

में विवरण दिया गया है आप क्या देख रहे हैं ("उपयोगकर्ता $ eval7 $ fn__8") अज्ञात फ़ंक्शन आपके द्वारा निर्धारित लागू करने के लिए Clojure द्वारा बनाई आंतरिक उत्पन्न आंतरिक क्लास का नाम है ।

आपने गौर किया हो सकता है, Clojure मानक जावा वर्ग नामकरण सम्मेलनों का पालन नहीं करता :-)

ध्यान दें कि वर्ग को लागू करता है इंटरफ़ेस clojure.lang.IFn - यह सब Clojure कार्यों के लिए लागू होता है।

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