2012-02-25 68 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