当varargs参与时,defmethod派遣

时间:2016-04-01 20:04:55

标签: clojure

我试图找到一种方法来定义一个多方法,(a)调度多个args和(b)允许指定仅关注某些args的方法(编译器不喜欢_ in最后一种方法):

(defmulti whocares (fn [a1 a2] [(class a1)(class a2)]))

(defmethod whocares [String String] [s1 s2]
  (println :s2 s1 s2))

(defmethod whocares [_ String] [any1 s2]
  (println :_s any1 s2))

编译器绝对不喜欢_。

我知道:默认catch-all,但我需要更精细的东西(在单个args上)。

在CL中我们会使用t作为匹配所有内容的类型,但是我没有看到指示clojure对X有什么东西(isa?无论X)总是会返回true。

顺便说一下,我想Java类层次结构有一个顶层,但我试图远离我的库,只支持Java类。

1 个答案:

答案 0 :(得分:1)

最简单的方法是使用java.lang.Object作为你的所有类型:

(defmulti whocares (fn [a b] [(class a) (class b)]))

(defmethod whocares [String String] [a b] (println "Two strings" a b))

(defmethod whocares [Object String] [a b] (println "Anything and string" a b))

(whocares "a" "b")
;; => "Two strings a b"

(whocares 1 "c")
;; => "Anything and string 1 c"

(whocares :a "c")
;; => "Anything and string :a c"

我不确定您为什么不想使用顶级的Java层次结构。可以使用derive来定义捕获所有调度值,但是仍然需要使Java的Object类成为自定义捕获所有值的子项:

(derive Object :whocares/any)

(defmulti whocares2 (fn [a b] [(class a) (class b)]))

(defmethod whocares2 [String String] [a b] (println "Two strings" a b))

(defmethod whocares2 [:whocares/any String] [a b] (println "Anything and string" a b))

(whocares2 "a" "b")
;; => "Two strings a b"

(whocares2 1 "c")
;; => "Anything and string 1 c"

(whocares2 :a "c")
;; => "Anything and string :a c"