2012-02-25 94 views
8

我有專門的兩個參數的多重方法:defmethod捕獲所有

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

具有類型允許我組不同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 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 2012-02-25 01:51:06

7

多方法支持的回退的方法,通過使用(可配置)值:default標識,如果沒有其他的方法匹配。

在你的情況,你只需添加:

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

鑑於您的例子,它可能是值得注意的是,你可以建立使用Clojure的關鍵字層次和多方法分派理解這些層次:http://clojure.org/multimethods

+0

不幸的是,我需要默認行爲對不同類型的值有所不同,我相信只有一個':default'可以按照多種方法定義。 – Brigham 2012-02-25 15:00:20