8

我有一个专门处理两个参数的多方法:

(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但是,除非is 实际上,否则这是行不通的:default

有什么好方法可以做到这一点?

4

3 回答 3

8

:default如果没有其他方法匹配,多方法支持使用 (configurable) value 标识的回退方法。

在您的情况下,您只需添加:

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

Given your example, it might be worth noting that you can establish hierarchies using Clojure keywords, and multimethod dispatch understands those hierarchies: http://clojure.org/multimethods

于 2012-02-25T08:17:59.040 回答
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]))))
于 2012-02-25T06:00:00.977 回答
0

您可以将 defmulti 更改为:

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

然后像这样编写你的方法:

(defmethod get-tag-type ::dog ::mutt)
于 2012-02-25T01:36:29.130 回答