【问题标题】:defmethod catch alldefmethod 包罗万象
【发布时间】:2012-02-25 01:20:41
【问题描述】:

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

(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,否则这是行不通的。

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

【问题讨论】:

    标签: clojure multimethod


    【解决方案1】:

    如果没有其他方法匹配,多方法支持使用(可配置)值 :default 标识的后备方法。

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

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

    鉴于您的示例,可能值得注意的是,您可以使用 Clojure 关键字建立层次结构,并且多方法调度可以理解这些层次结构:http://clojure.org/multimethods

    【讨论】:

    • 不幸的是,对于不同类型的值,我需要不同的默认行为,我相信每个多方法只能定义一个:default
    【解决方案2】:

    您的调度函数需要知道哪些映射已经定义,以便它可以决定何时使用默认值。 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]))))
    

    【讨论】:

      【解决方案3】:

      您可以将 defmulti 更改为:

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

      然后这样写你的方法:

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

      【讨论】:

      • 我不希望 defmulti 知道将使用它的 defmethods。
      猜你喜欢
      • 2018-10-01
      • 1970-01-01
      • 2011-07-23
      • 2011-02-12
      • 2011-09-09
      • 2014-04-27
      • 1970-01-01
      • 2016-08-20
      • 2011-04-15
      相关资源
      最近更新 更多