2012-02-25 6 views
8

मैं एक multimethod कि दो मापदंडों पर माहिर है:defmethod पकड़ सभी

(defmethod get-tag-type [::cat 0] [type tag] ::tiger) 
(defmethod get-tag-type [::cat 1] [type tag] ::lion) 
(defmethod get-tag-type [::cat 2] [type tag] ::jaguar) 

(defmethod get-tag-type [::dog 0] [type tag] ::poodle) 
(defmethod get-tag-type [::dog 1] [type tag] ::australian-shepherd) 
(defmethod get-tag-type [::dog 2] [type tag] ::labrador-retriever) 

लेकिन, कभी कभी, मैं चाहता हूँ: अलग defmethod सेट में कॉल

(defmulti get-tag-type (fn [type tag] [type tag])) 

प्रकार के बाद मुझे समूह के लिए अनुमति देता समूह में से किसी एक के लिए सभी या डिफ़ॉल्ट पकड़ें, जिसे किसी अन्य से मेल नहीं किया जाएगा:

(defmethod get-tag-type [::dog :default] ::mutt) 

हालांकि, यह तब तक काम नहीं करता जब तक tag वास्तव में :default है।

इसे पूरा करने का एक अच्छा तरीका क्या है?

उत्तर

7

आपका प्रेषण समारोह को पता है जो मैपिंग पहले ही निर्धारित कर इतना है कि यह तय कर सकते हैं जब की जरूरत है एक डिफ़ॉल्ट का सहारा लें। methods फ़ंक्शन उन मैपिंग को आपके पास वापस कर देगा।

(defmulti get-tag-type (fn [type tag] 
         (let [mlist (methods get-tag-type)] 
          (if-let [d (get mlist [type tag])] 
          [type tag] 
          [type :default])))) 
0

आप को defmulti बदल सकता है:

(defmulti get-tag-type (fn [type tag] 
         (if (= type ::dog) 
          ::dog 
          [type tag]))) 

तो इस तरह से अपनी विधि लिखें:

(defmethod get-tag-type ::dog ::mutt) 
+0

मैं नहीं चाहता कि defmulti defmethods के बारे में जानना चाहें जो इसका उपयोग करेंगे। – Brigham

7

मुल्टीमेथड्स फ़ॉलबैक विधि, (विन्यास) मूल्य :default का उपयोग करके पहचान का समर्थन है, यदि अन्य विधियों में से कोई भी मैच।

आपके मामले में, आप बस जोड़ेंगे:

(defmethod get-tag-type :default [type tag] 
    (do special behaviour here ...)) 

अपने उदाहरण को देखते हुए यह ध्यान देने योग्य है कि आप Clojure कीवर्ड का उपयोग कर पदानुक्रम स्थापित कर सकते हैं हो सकता है, और multimethod प्रेषण उन पदानुक्रम को समझता है: http://clojure.org/multimethods

+0

दुर्भाग्यवश, मुझे अलग-अलग मानों के प्रकार के लिए डिफ़ॉल्ट व्यवहार की आवश्यकता है, और मेरा मानना ​​है कि केवल एक 'डिफ़ॉल्ट' प्रति बहु विधि परिभाषित किया जा सकता है। – Brigham

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