2012-10-07 5 views
5

मैं कुछ Clojure कोड है कि (, java.nio.file.WatchEvent<?> के माध्यम से जावा कोड के एक जोड़े परतों के माध्यम से Interop के लिए इस मामले में java.nio.Path कोशिश कर रहा है है:आप थ्रेडिंग (->) मैक्रो के अंदर संकेत कैसे टाइप कर सकते हैं?

(defn unroll-event 
    [^WatchEvent event] 
    { :kind (.kind event) 
    :context (.context event) 
    :path (-> event .context .toAbsolutePath .toString)}) 

इस कोड में, मैं प्रकार का संकेत दिया event है, तो मैं करूंगा , लगता है कि यह यह पता लगाने की क्या .context वापस जाने के लिए माना जाता है, और इस तरह के रूप में, यह पता लगाने की क्या .toAbsolutePath और .toString करते हैं। मैं इस मामले में लगता है कि सक्षम हो सक्षम होना चाहिए, के बाद से .context परिभाषित किया गया है एक सामान्य प्रकार T लौट गया है मैं मैं सोच रहा हूं कि क्या मैं .context पर कॉल को संकेत दे सकता हूं। मैंने केवल प्रीपेन्डिन की कोशिश की है

Reflection warning, junkcode/core.clj:28 - reference to field toAbsolutePath can't be resolved. 
Reflection warning, junkcode/core.clj:28 - reference to field toString can't be resolved. 

वहाँ कुछ मैं इस मामले में कुछ कर सकते हैं: जी .context को ^java.nio.file.Path, और ^Path और ^String.toAbsolutePath और toString को क्रमश: लेकिन मैं अभी भी चेतावनी मिल सकता है? क्या ऐसा इसलिए है क्योंकि -> एक मैक्रो है और उसमें संकेत देने के लिए विशेष नियम हैं?

+0

इसका विस्तार क्या हो रहा है? 'Clojure.walk/macroexpand-all' का प्रयोग करें – noahlz

उत्तर

2

(-> x .blah ^String .bar) मूल रूप से (^String .bar (.blah x)) तक फैला हुआ है, जो स्पष्ट रूप से नहीं है कि आप संकेत कहाँ चाहते हैं। मुद्दा यह है कि टाइप-संकेत के किसी भी संदर्भ में विशेष व्यवहार नहीं है (उदाहरण के लिए, मैक्रोज़): यह सिर्फ मेटाडेटा स्रोत-कोड प्रतीकों पर लागू होता है। आपके उदाहरण में ->, ऐसा कोई स्थान नहीं है जहां आप इनपुट फॉर्म पर मेटाडेटा डाल सकें जिससे यह आउटपुट फॉर्म में आप कहां रहें। तो आपको उदाहरण के लिए (-> ^Path (.context event) .toAbsolutePath str) जैसे कुछ अन्य फॉर्म लिखने की आवश्यकता है।

इसके अलावा, क्लोजर के इंफ्रेंसर को सामान्य प्रकारों के बारे में कुछ भी पता नहीं है, इसलिए एक विधि-वापसी-टी को विधि-वापसी-ऑब्जेक्ट के रूप में माना जाता है, जो बताता है कि आपको यहां पर संकेत देने की आवश्यकता क्यों है।

0

मुझे नहीं पता कि यह हमेशा मामला रहा है, लेकिन क्लोजर 1.4.0, 1.5.1, और 1.6.0 में, आप -> में किसी भी बिंदु पर टाइप-इशारा कर सकते हैं जब तक आप ब्रांड्स का उपयोग करते हैं:

user=> (set! *warn-on-reflection* true) 
true 
user=> (fn [^java.nio.file.WatchEvent e] 
     (-> e ^java.nio.file.Path .context .toAbsolutePath)) 
Reflection warning, /private/var/folders/9_/wdph6m796zzc8trzcbtcmhrn5bjpt0/T/form-init8364673644863044068.clj:1:35 - reference to field toAbsolutePath on java.lang.Object can't be resolved. 
#<user$eval1995$fn__1996 [email protected]> 
user=> ; but no warning if we do 
user=> (fn [^java.nio.file.WatchEvent e] 
     (-> e ^java.nio.file.Path (.context) .toAbsolutePath)) 
#<user$eval1999$fn__2000 [email protected]> 

केवल अंतर .context के माता-पिता हैं।

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